From db244887c27c3324ee591f4cfadd8867724ed7aa Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Tue, 30 Aug 2022 08:19:43 +0300 Subject: [PATCH] #420 - recover function for sign transaction --- .../ethereum/transaction.cpp | 34 +++++++++++++++++++ .../ethereum/transaction.hpp | 2 ++ 2 files changed, 36 insertions(+) diff --git a/libraries/plugins/peerplays_sidechain/ethereum/transaction.cpp b/libraries/plugins/peerplays_sidechain/ethereum/transaction.cpp index 9f160445..82a81ac1 100644 --- a/libraries/plugins/peerplays_sidechain/ethereum/transaction.cpp +++ b/libraries/plugins/peerplays_sidechain/ethereum/transaction.cpp @@ -129,6 +129,40 @@ void raw_transaction::deserialize(const std::string &raw_tx) { //! signed_transaction +std::string signed_transaction::recover(const std::string &chain_id) const { + fc::ecc::compact_signature input64; + fc::from_hex(r, (char *)&input64.at(1), 32); + fc::from_hex(v, (char *)&input64.at(0), 1); + int recid = input64.at(0) - from_hex(chain_id) * 2 - 35; + fc::from_hex(s, (char *)&input64.at(33), 32); + + secp256k1_ecdsa_recoverable_signature sig; + FC_ASSERT(secp256k1_ecdsa_recoverable_signature_parse_compact(eth_context(), &sig, (const unsigned char *)&input64.data[1], recid)); + + raw_transaction tr; + tr.nonce = nonce; + tr.gas_price = gas_price; + tr.gas_limit = gas_limit; + tr.to = to; + tr.value = value; + tr.data = data; + tr.chain_id = chain_id; + + secp256k1_pubkey rawPubkey; + FC_ASSERT(secp256k1_ecdsa_recover(eth_context(), &rawPubkey, &sig, (const unsigned char *)tr.hash().data())); + + std::array pubkey; + size_t biglen = 65; + FC_ASSERT(secp256k1_ec_pubkey_serialize(eth_context(), pubkey.data(), &biglen, &rawPubkey, SECP256K1_EC_UNCOMPRESSED)); + + const std::string out = std::string(pubkey.begin(), pubkey.end()).substr(1); + bytes hash; + hash.resize(32); + keccak_256((const unsigned char *)out.data(), out.size(), (unsigned char *)hash.data()); + + return add_0x(fc::to_hex((char *)&hash[0], hash.size()).substr(24)); +} + std::string signed_transaction::serialize() const { rlp_encoder encoder; const std::string serialized = encoder.encode(remove_0x(nonce)) + diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/ethereum/transaction.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/ethereum/transaction.hpp index b8b1aa13..f4edf015 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/ethereum/transaction.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/ethereum/transaction.hpp @@ -55,6 +55,8 @@ public: std::string r; std::string s; + std::string recover(const std::string &chain_id) const; + virtual std::string serialize() const override; virtual void deserialize(const std::string &raw_tx) override; };