From 4c3da2015a44041a08149a9893587724b2bf145b Mon Sep 17 00:00:00 2001 From: satyakoneru <15652887+satyakoneru@users.noreply.github.com> Date: Tue, 14 Apr 2020 17:49:56 +0000 Subject: [PATCH] Add send_transaction_standalone function --- .../bitcoin/sign_bitcoin_transaction.cpp | 10 +++++ .../bitcoin/sign_bitcoin_transaction.hpp | 2 + .../sidechain_net_handler_bitcoin.cpp | 45 +++++++++++++++++-- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/libraries/plugins/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.cpp b/libraries/plugins/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.cpp index cc1948cb..eaf33d0b 100644 --- a/libraries/plugins/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.cpp +++ b/libraries/plugins/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.cpp @@ -128,4 +128,14 @@ std::vector> sort_sigs( const bitcoin_transaction& tx, const return new_stacks; } +void add_signatures_to_transaction( bitcoin_transaction &tx, std::vector> &signature_set ) +{ + for (unsigned int i = 0; i < signature_set.size(); i++) { + std::vector signatures = signature_set[i]; + FC_ASSERT(signatures.size() == tx.vin.size(), "Invalid signatures number"); + for (unsigned int i = 0; i < tx.vin.size(); i++) + tx.vin[i].scriptWitness.push_back(signatures[i]); + } +} + } } } diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.hpp index 72617360..30e11a93 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.hpp @@ -26,4 +26,6 @@ bool verify_sig( const bytes& sig, const bytes& pubkey, const bytes& msg, const std::vector> sort_sigs( const bitcoin_transaction& tx, const std::vector& redeem_scripts, const std::vector& amounts, const secp256k1_context_t* context ); +void add_signatures_to_transaction( bitcoin_transaction &tx, std::vector> &signature_set ); + } } } diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp index 22376d3e..4957d08e 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -1418,17 +1418,17 @@ std::string sidechain_net_handler_bitcoin::send_transaction(const sidechain_tran } } -std::vector> read_byte_arrays_from_string(const std::string &string_buf) +std::vector read_byte_arrays_from_string(const std::string &string_buf) { std::stringstream ss(string_buf); boost::property_tree::ptree json; boost::property_tree::read_json(ss, json); - std::vector data; + std::vector data; for(auto &v: json) { std::string hex = v.second.data(); - bytes item; + bitcoin::bytes item; item.resize(hex.size() / 2); fc::from_hex(hex, (char*)&item[0], item.size()); data.push_back(item); @@ -1760,7 +1760,44 @@ std::string sidechain_net_handler_bitcoin::send_transaction_psbt(const sidechain } std::string sidechain_net_handler_bitcoin::send_transaction_standalone(const sidechain_transaction_object &sto) { - return bitcoin_client->sendrawtransaction(sto.transaction); + using namespace bitcoin; + std::vector in_amounts; + std::string tx_hex; + + read_tx_data_from_string(sto.transaction, tx_hex, in_amounts); + + accounts_keys son_pubkeys; + for (auto& son: sto.signers) { + std::string pub_key = son.sidechain_public_keys.at(sidechain_type::bitcoin); + son_pubkeys[son.son_id] = create_public_key_data( parse_hex(pub_key) ); + } + + uint32_t nrequired = sto.signers.size() * 2 / 3 + 1; + btc_multisig_segwit_address pw_address(nrequired, son_pubkeys); + + bitcoin_transaction tx = unpack(parse_hex(tx_hex)); + + bitcoin::bytes rscript = pw_address.get_redeem_script(); + + std::vector redeem_scripts(tx.vin.size(), rscript); + + vector> signatures; + for (unsigned idx = 0; idx < sto.signatures.size(); ++idx) { + if(!sto.signatures[idx].second.empty()) + signatures.push_back(read_byte_arrays_from_string(sto.signatures[idx].second)); + } + + add_signatures_to_transaction(tx, signatures); + + sign_witness_transaction_finalize(tx, redeem_scripts); + + std::string final_tx_hex = fc::to_hex( pack( tx ) ); + + std::string res = bitcoin_client->sendrawtransaction(final_tx_hex); + + wlog("skoneru: send_transaction_standalone: ${tx}, [${res}]", ("tx", final_tx_hex)("res", res)); + + return res; } void sidechain_net_handler_bitcoin::handle_event(const std::string &event_data) {