SON261 - Withdrawal transfer ( PW -> user address ), addition of bitcoin public private key to config.ini for multiple sons mode
This commit is contained in:
parent
1d304993e9
commit
9e30f8866a
3 changed files with 107 additions and 12 deletions
|
|
@ -29,11 +29,12 @@ public:
|
|||
void send_btc_tx( const std::string& tx_hex );
|
||||
std::string add_multisig_address( const std::vector<std::string> public_keys );
|
||||
bool connection_is_not_defined() const;
|
||||
std::string create_raw_transaction(const sidechain_event_data& sed, const std::string& pw_address);
|
||||
std::string create_raw_transaction(const std::string& txid, const std::string& vout, const std::string& out_address, double transfer_amount);
|
||||
std::string sign_raw_transaction_with_wallet(const std::string& tx_hash);
|
||||
std::string sign_raw_transaction_with_privkey(const std::string& tx_hash, const std::string& private_key);
|
||||
void import_address( const std::string& address_or_script);
|
||||
std::vector<btc_txout> list_unspent();
|
||||
std::vector<btc_txout> list_unspent_by_address_and_amount(const std::string& address, double transfer_amount);
|
||||
std::string prepare_tx(const std::vector<btc_txout>& ins, const fc::flat_map<std::string, double> outs);
|
||||
|
||||
private:
|
||||
|
|
@ -83,6 +84,7 @@ public:
|
|||
std::string sign_transaction( const std::string& transaction );
|
||||
std::string send_transaction( const std::string& transaction );
|
||||
std::string transfer_deposit_to_primary_wallet (const sidechain_event_data& sed);
|
||||
std::string transfer_withdrawal_from_primary_wallet(const std::string& user_address, int64_t sidechain_amount);
|
||||
|
||||
private:
|
||||
std::string ip;
|
||||
|
|
|
|||
|
|
@ -106,6 +106,9 @@ void peerplays_sidechain_plugin_impl::plugin_set_program_options(
|
|||
("bitcoin-address", bpo::value<string>()->default_value("2N911a7smwDzUGARg8s7Q1ViizFCw6gWcbR"), "Bitcoin address")
|
||||
("bitcoin-public-key", bpo::value<string>()->default_value("02d0f137e717fb3aab7aff99904001d49a0a636c5e1342f8927a4ba2eaee8e9772"), "Bitcoin public key")
|
||||
("bitcoin-private-key", bpo::value<string>()->default_value("cVN31uC9sTEr392DLVUEjrtMgLA8Yb3fpYmTRj7bomTm6nn2ANPr"), "Bitcoin private key")
|
||||
("bitcoin-private-keys", bpo::value<vector<string>>()->composing()->multitoken()->
|
||||
DEFAULT_VALUE_VECTOR(std::make_pair("02d0f137e717fb3aab7aff99904001d49a0a636c5e1342f8927a4ba2eaee8e9772", "cVN31uC9sTEr392DLVUEjrtMgLA8Yb3fpYmTRj7bomTm6nn2ANPr")),
|
||||
"Tuple of [Bitcoin PublicKey, Bitcoin Private key] (may specify multiple times)")
|
||||
;
|
||||
cfg.add(cli);
|
||||
}
|
||||
|
|
@ -120,7 +123,7 @@ void peerplays_sidechain_plugin_impl::plugin_initialize(const boost::program_opt
|
|||
config_ready_son = config_ready_son && !_sons.empty();
|
||||
|
||||
#ifndef SUPPORT_MULTIPLE_SONS
|
||||
FC_ASSERT( _sons.size() == 1, "Multiple SONs not supported" );
|
||||
//FC_ASSERT( _sons.size() == 1, "Multiple SONs not supported" );
|
||||
#endif
|
||||
|
||||
if( options.count("peerplays-private-key") )
|
||||
|
|
|
|||
|
|
@ -170,19 +170,12 @@ std::string bitcoin_rpc_client::add_multisig_address( const std::vector<std::str
|
|||
return "";
|
||||
}
|
||||
|
||||
std::string bitcoin_rpc_client::create_raw_transaction(const sidechain_event_data& sed, const std::string& pw_address)
|
||||
std::string bitcoin_rpc_client::create_raw_transaction(const std::string& txid, const std::string& nvout, const std::string& out_address, double transfer_amount)
|
||||
{
|
||||
std::string txid = sed.sidechain_transaction_id;
|
||||
std::string suid = sed.sidechain_uid;
|
||||
std::string nvout = suid.substr(suid.find_last_of("-")+1);
|
||||
int64_t deposit_amount = sed.sidechain_amount;
|
||||
deposit_amount -= 1000; // Deduct minimum relay fee
|
||||
double transfer_amount = (double)deposit_amount/100000000.0;
|
||||
|
||||
std::string body = std::string("{\"jsonrpc\": \"1.0\", \"id\":\"createrawtransaction\", \"method\": \"createrawtransaction\", \"params\": [");
|
||||
std::string params = "";
|
||||
std::string input = std::string("[{\"txid\":\"") + txid + std::string("\",\"vout\":")+ nvout +std::string("}]");
|
||||
std::string output = std::string("[{\"") + pw_address + std::string("\":") + std::to_string(transfer_amount) + std::string("}]");
|
||||
std::string output = std::string("[{\"") + out_address + std::string("\":") + std::to_string(transfer_amount) + std::string("}]");
|
||||
params = params + input + std::string(",") + output;
|
||||
body = body + params + std::string("]}");
|
||||
|
||||
|
|
@ -313,6 +306,51 @@ std::vector<btc_txout> bitcoin_rpc_client::list_unspent()
|
|||
return result;
|
||||
}
|
||||
|
||||
std::vector<btc_txout> bitcoin_rpc_client::list_unspent_by_address_and_amount(const std::string& address, double minimum_amount)
|
||||
{
|
||||
std::string body = std::string("{\"jsonrpc\": \"1.0\", \"id\":\"pp_plugin\", \"method\": \"listunspent\", \"params\": [");
|
||||
body += std::string("1,999999,[\"");
|
||||
body += address;
|
||||
body += std::string("\"],true,{\"minimumAmount\":");
|
||||
body += std::to_string(minimum_amount);
|
||||
body += std::string("}] }");
|
||||
|
||||
ilog(body);
|
||||
|
||||
const auto reply = send_post_request( body );
|
||||
|
||||
std::vector<btc_txout> result;
|
||||
if( reply.body.empty() )
|
||||
{
|
||||
wlog("Failed to list unspent txo");
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string reply_str( reply.body.begin(), reply.body.end() );
|
||||
|
||||
std::stringstream ss(reply_str);
|
||||
boost::property_tree::ptree json;
|
||||
boost::property_tree::read_json( ss, json );
|
||||
|
||||
if( reply.status == 200 ) {
|
||||
idump((reply_str));
|
||||
if( json.count( "result" ) )
|
||||
{
|
||||
for(auto& entry: json.get_child("result"))
|
||||
{
|
||||
btc_txout txo;
|
||||
txo.txid_ = entry.second.get_child("txid").get_value<std::string>();
|
||||
txo.out_num_ = entry.second.get_child("vout").get_value<unsigned int>();
|
||||
txo.amount_ = entry.second.get_child("amount").get_value<double>();
|
||||
result.push_back(txo);
|
||||
}
|
||||
}
|
||||
} else if( json.count( "error" ) && !json.get_child( "error" ).empty() ) {
|
||||
wlog( "Failed to list unspent txo! Reply: ${msg}", ("msg", reply_str) );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string bitcoin_rpc_client::prepare_tx(const std::vector<btc_txout> &ins, const fc::flat_map<std::string, double> outs)
|
||||
{
|
||||
std::string body("{\"jsonrpc\": \"1.0\", \"id\":\"pp_plugin\", \"method\": \"createrawtransaction\", \"params\": [");
|
||||
|
|
@ -553,7 +591,15 @@ std::string sidechain_net_handler_bitcoin::transfer_deposit_to_primary_wallet (
|
|||
|
||||
std::string pw_address = json.get<std::string>("address");
|
||||
|
||||
std::string reply_str = bitcoin_client->create_raw_transaction(sed, pw_address);
|
||||
std::string txid = sed.sidechain_transaction_id;
|
||||
std::string suid = sed.sidechain_uid;
|
||||
std::string nvout = suid.substr(suid.find_last_of("-")+1);
|
||||
int64_t deposit_amount = sed.sidechain_amount;
|
||||
deposit_amount -= 1000; // Deduct minimum relay fee
|
||||
double transfer_amount = (double)deposit_amount/100000000.0;
|
||||
|
||||
std::string reply_str = bitcoin_client->create_raw_transaction(txid, nvout, pw_address, transfer_amount);
|
||||
|
||||
ilog(reply_str);
|
||||
|
||||
std::stringstream ss_utx(reply_str);
|
||||
|
|
@ -583,6 +629,50 @@ std::string sidechain_net_handler_bitcoin::transfer_deposit_to_primary_wallet (
|
|||
return reply_str;
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_bitcoin::transfer_withdrawal_from_primary_wallet(const std::string& user_address, int64_t sidechain_amount) {
|
||||
const auto& idx = database.get_index_type<son_wallet_index>().indices().get<by_id>();
|
||||
auto obj = idx.rbegin();
|
||||
if (obj == idx.rend() || obj->addresses.find(sidechain_type::bitcoin) == obj->addresses.end())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string pw_address_json = obj->addresses.find(sidechain_type::bitcoin)->second;
|
||||
|
||||
std::stringstream ss(pw_address_json);
|
||||
boost::property_tree::ptree json;
|
||||
boost::property_tree::read_json( ss, json );
|
||||
|
||||
std::string pw_address = json.get<std::string>("address");
|
||||
|
||||
double total_amount = (((double)sidechain_amount*1000.0)+1000.0)/100000000.0; // Account only for relay fee for now
|
||||
double transfer_amount = ((double)sidechain_amount*1000.0)/100000000.0;
|
||||
std::vector<btc_txout> unspent_utxo= bitcoin_client->list_unspent_by_address_and_amount(pw_address, total_amount);
|
||||
|
||||
if(unspent_utxo.size() == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
btc_txout utxo = unspent_utxo[0];
|
||||
std::string reply_str = bitcoin_client->create_raw_transaction(utxo.txid_, std::to_string(utxo.out_num_), user_address, transfer_amount);
|
||||
ilog(reply_str);
|
||||
|
||||
std::stringstream ss_utx(reply_str);
|
||||
boost::property_tree::ptree pt;
|
||||
boost::property_tree::read_json( ss_utx, pt );
|
||||
|
||||
if( !(pt.count( "error" ) && pt.get_child( "error" ).empty()) || !pt.count("result") ) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string unsigned_tx_hex = pt.get<std::string>("result");
|
||||
|
||||
std::cout << unsigned_tx_hex << std::endl;
|
||||
|
||||
return unsigned_tx_hex;
|
||||
}
|
||||
|
||||
void sidechain_net_handler_bitcoin::handle_event( const std::string& event_data ) {
|
||||
ilog("peerplays sidechain plugin: sidechain_net_handler_bitcoin::handle_event");
|
||||
ilog(" event_data: ${event_data}", ("event_data", event_data));
|
||||
|
|
|
|||
Loading…
Reference in a new issue