From 4e425790862574fe91d80bd980ebb70b19454c2d Mon Sep 17 00:00:00 2001 From: gladcow Date: Fri, 20 Mar 2020 18:20:38 +0300 Subject: [PATCH] create_multisig_address_standalone implementation --- .../sidechain_net_handler_bitcoin.hpp | 6 +- .../sidechain_net_handler_bitcoin.cpp | 94 +++++++++++++++---- 2 files changed, 79 insertions(+), 21 deletions(-) diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp index 697ac32f..3f75ca0d 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp @@ -103,11 +103,15 @@ private: fc::future on_changed_objects_task; - std::string create_multisig_address(const std::vector &son_pubkeys_bitcoin); + std::string create_multisig_address(const std::vector &son_pubkeys_bitcoin, const std::vector& son_votes); std::string create_transaction(const std::vector &inputs, const fc::flat_map outputs, const std::string& extra_data); std::string sign_transaction(const sidechain_transaction_object &sto, bool &complete); bool send_transaction(const sidechain_transaction_object &sto, std::string &sidechain_transaction); + std::string create_multisig_address_raw(const std::vector &son_pubkeys); + std::string create_multisig_address_psbt(const std::vector &son_pubkeys); + std::string create_multisig_address_standalone(const std::vector &son_pubkeys, const std::vector& son_votes); + std::string create_transaction_raw(const std::vector &inputs, const fc::flat_map outputs); std::string create_transaction_psbt(const std::vector &inputs, const fc::flat_map outputs); std::string create_transaction_standalone(const std::vector &inputs, const fc::flat_map outputs, const std::string& redeem_script); diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp index 1b04ee8d..1e3ad369 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -854,10 +854,13 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() { auto active_sons = gpo.active_sons; vector son_pubkeys_bitcoin; + vector son_votes; for (const son_info &si : active_sons) { son_pubkeys_bitcoin.push_back(si.sidechain_public_keys.at(sidechain_type::bitcoin)); + son_votes.push_back(si.total_votes); } - std::string full_address_info = create_multisig_address(son_pubkeys_bitcoin); + + std::string full_address_info = create_multisig_address(son_pubkeys_bitcoin, son_votes); if(!full_address_info.size()) { elog("Failed to create multisig address"); @@ -1147,26 +1150,13 @@ bool sidechain_net_handler_bitcoin::send_sidechain_transaction(const sidechain_t return send_transaction(sto, sidechain_transaction); } -std::string sidechain_net_handler_bitcoin::create_multisig_address(const std::vector &son_pubkeys_bitcoin) +std::string sidechain_net_handler_bitcoin::create_multisig_address(const std::vector &son_pubkeys_bitcoin, const std::vector& son_votes) { - if (!wallet_password.empty()) { - bitcoin_client->walletpassphrase(wallet_password, 5); - } - - uint32_t nrequired = son_pubkeys_bitcoin.size() * 2 / 3 + 1; - string reply_str = bitcoin_client->addmultisigaddress(nrequired, son_pubkeys_bitcoin); - - std::stringstream active_pw_ss(reply_str); - boost::property_tree::ptree active_pw_pt; - boost::property_tree::read_json(active_pw_ss, active_pw_pt); - if (!active_pw_pt.count("error") || !active_pw_pt.get_child("error").empty()) { - elog("Failed to recreate primary wallet"); - return ""; - } - - std::stringstream res; - boost::property_tree::json_parser::write_json(res, active_pw_pt.get_child("result")); - return res.str(); + std::string new_address = ""; + //new_tx = create_multisig_address_raw(son_pubkeys); + new_address = create_multisig_address_psbt(son_pubkeys_bitcoin); + //new_tx = create_multisig_address_standalone(son_pubkeys_bitcoin, son_votes); + return new_address; } // Creates transaction in any format @@ -1196,6 +1186,70 @@ bool sidechain_net_handler_bitcoin::send_transaction(const sidechain_transaction return send_transaction_psbt(sto, sidechain_transaction); } +std::string sidechain_net_handler_bitcoin::create_multisig_address_raw(const std::vector &son_pubkeys) +{ + if (!wallet_password.empty()) { + bitcoin_client->walletpassphrase(wallet_password, 5); + } + + uint32_t nrequired = son_pubkeys.size() * 2 / 3 + 1; + string reply_str = bitcoin_client->addmultisigaddress(nrequired, son_pubkeys); + + std::stringstream active_pw_ss(reply_str); + boost::property_tree::ptree active_pw_pt; + boost::property_tree::read_json(active_pw_ss, active_pw_pt); + if (!active_pw_pt.count("error") || !active_pw_pt.get_child("error").empty()) { + elog("Failed to recreate primary wallet"); + return ""; + } + + std::stringstream res; + boost::property_tree::json_parser::write_json(res, active_pw_pt.get_child("result")); + return res.str(); +} + +std::string sidechain_net_handler_bitcoin::create_multisig_address_psbt(const std::vector &son_pubkeys) +{ + if (!wallet_password.empty()) { + bitcoin_client->walletpassphrase(wallet_password, 5); + } + + uint32_t nrequired = son_pubkeys.size() * 2 / 3 + 1; + string reply_str = bitcoin_client->addmultisigaddress(nrequired, son_pubkeys); + + std::stringstream active_pw_ss(reply_str); + boost::property_tree::ptree active_pw_pt; + boost::property_tree::read_json(active_pw_ss, active_pw_pt); + if (!active_pw_pt.count("error") || !active_pw_pt.get_child("error").empty()) { + elog("Failed to recreate primary wallet"); + return ""; + } + + std::stringstream res; + boost::property_tree::json_parser::write_json(res, active_pw_pt.get_child("result")); + return res.str(); +} + +std::string sidechain_net_handler_bitcoin::create_multisig_address_standalone(const std::vector &son_pubkeys, const std::vector &son_votes) +{ + FC_ASSERT(son_pubkeys.size() == son_votes.size()); + + vector> son_data; + for(unsigned idx = 0; idx < son_pubkeys.size(); ++idx) + son_data.push_back(make_pair(son_pubkeys[idx], son_votes[idx])); + sort(son_data.begin(), son_data.end(), + [](const pair& p1, const pair& p2) -> bool + { return p1.second > p2.second; } + ); + + std::string address = get_weighted_multisig_address(son_data); + bytes redeem_script = get_weighted_multisig_redeem_script(son_data); + + return "{\"address\":\"" + address + "\",\"redeemScript\":\"" + + fc::to_hex((char*)&redeem_script[0], redeem_script.size()) + + "\"}"; +} + std::string sidechain_net_handler_bitcoin::create_transaction_raw(const std::vector &inputs, const fc::flat_map outputs) { return bitcoin_client->createrawtransaction(inputs, outputs); }