Signature bitcoin transaction and confirmation proposal
This commit is contained in:
parent
38ba47bdd5
commit
810051e7c9
12 changed files with 217 additions and 101 deletions
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
#include <sidechain/sign_bitcoin_transaction.hpp>
|
||||
#include <sidechain/input_withdrawal_info.hpp>
|
||||
|
||||
#include <graphene/chain/bitcoin_address_object.hpp>
|
||||
#include <graphene/chain/primary_wallet_vout_object.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
|
|
@ -25,7 +26,6 @@ object_id_type bitcoin_transaction_send_evaluator::do_apply( const bitcoin_trans
|
|||
{
|
||||
bitcoin_transaction_send_operation& mutable_op = const_cast<bitcoin_transaction_send_operation&>( op );
|
||||
database& d = db();
|
||||
sidechain::bytes wit_script;
|
||||
|
||||
finalize_bitcoin_transaction( mutable_op );
|
||||
|
||||
|
|
@ -43,6 +43,7 @@ object_id_type bitcoin_transaction_send_evaluator::do_apply( const bitcoin_trans
|
|||
});
|
||||
|
||||
sidechain::prev_out new_pw_vout = { "", 0, 0 };
|
||||
sidechain::bytes wit_script = d.get_latest_PW().address.get_witness_script();
|
||||
if( btc_tx.transaction.vout[0].is_p2wsh() && btc_tx.transaction.vout[0].scriptPubKey == wit_script )
|
||||
new_pw_vout = { btc_tx.transaction.get_txid(), 0, btc_tx.transaction.vout[0].value };
|
||||
|
||||
|
|
@ -71,19 +72,34 @@ std::vector< info_for_used_vin_id_type > bitcoin_transaction_send_evaluator::cre
|
|||
if( obj_itr.valid() )
|
||||
d.i_w_info.remove_info_for_vin( *obj_itr );
|
||||
}
|
||||
|
||||
return new_vins;
|
||||
}
|
||||
|
||||
void bitcoin_transaction_send_evaluator::finalize_bitcoin_transaction( bitcoin_transaction_send_operation& op )
|
||||
{
|
||||
database& d = db();
|
||||
|
||||
std::vector<std::vector<sidechain::bytes>> new_stacks( sidechain::sort_sigs( op.transaction, op.vins, d.context_verify ) );
|
||||
auto vins = op.vins;
|
||||
if( op.pw_vin.str().compare( 0, 24, SIDECHAIN_NULL_VIN_IDENTIFIER ) != 0 ) {
|
||||
const auto& pw_vout = d.pw_vout_manager.get_vout( op.pw_vin );
|
||||
info_for_vin vin;
|
||||
vin.out = pw_vout->vout;
|
||||
vin.address = d.get_latest_PW().address.get_address();
|
||||
vin.identifier = pw_vout->hash_id;
|
||||
vins.insert( vins.begin(), vin );
|
||||
}
|
||||
|
||||
std::vector<bytes> redeem_scripts( d.i_w_info.get_redeem_scripts( vins ) );
|
||||
std::vector<uint64_t> amounts( d.i_w_info.get_amounts( vins ) );
|
||||
|
||||
std::vector<std::vector<sidechain::bytes>> new_stacks( sidechain::sort_sigs( op.transaction, redeem_scripts, amounts, d.context_verify ) );
|
||||
|
||||
for( size_t i = 0; i < new_stacks.size(); i++ ) {
|
||||
op.transaction.vin[i].scriptWitness = new_stacks[i];
|
||||
}
|
||||
|
||||
sidechain::sign_witness_transaction_finalize( op.transaction, op.vins );
|
||||
sidechain::sign_witness_transaction_finalize( op.transaction, redeem_scripts );
|
||||
}
|
||||
|
||||
void bitcoin_transaction_send_evaluator::send_bitcoin_transaction( const bitcoin_transaction_object& btc_tx )
|
||||
|
|
@ -99,18 +115,16 @@ void_result bitcoin_transaction_sign_evaluator::do_evaluate( const bitcoin_trans
|
|||
{
|
||||
database& d = db();
|
||||
|
||||
const auto& sidechain_proposal_idx = d.get_index_type<sidechain_proposal_index>().indices().get<by_id>();
|
||||
const auto& sidechain_proposal_itr = sidechain_proposal_idx.find( op.sidechain_proposal_id );
|
||||
FC_ASSERT( sidechain_proposal_idx.end() != sidechain_proposal_itr,
|
||||
"sidechain_proposal not found");
|
||||
const auto& proposal_idx = d.get_index_type<proposal_index>().indices().get<by_id>();
|
||||
const auto& proposal_itr = proposal_idx.find( op.proposal_id );
|
||||
FC_ASSERT( proposal_idx.end() != proposal_itr, "proposal not found");
|
||||
|
||||
witness_id_type scheduled_witness = d.get_scheduled_witness( 1 );
|
||||
const auto& witness_obj = d.get< witness_object >( scheduled_witness );
|
||||
FC_ASSERT( witness_obj.witness_account == op.payer, "Incorrect witness." );
|
||||
|
||||
sidechain::bytes public_key( public_key_data_to_bytes( witness_obj.signing_key.key_data ) );
|
||||
const auto& proposal = sidechain_proposal_itr->proposal_id( d );
|
||||
auto btc_send_op = proposal.proposed_transaction.operations[0].get<bitcoin_transaction_send_operation>();
|
||||
auto btc_send_op = proposal_itr->proposed_transaction.operations[0].get<bitcoin_transaction_send_operation>();
|
||||
FC_ASSERT( check_sigs( public_key, op.signatures, btc_send_op.vins, btc_send_op.transaction ) ); // Add pw_vin
|
||||
|
||||
// const auto& proposal = sidechain_proposal_itr->proposal_id( d );
|
||||
|
|
@ -122,9 +136,7 @@ void_result bitcoin_transaction_sign_evaluator::do_evaluate( const bitcoin_trans
|
|||
void_result bitcoin_transaction_sign_evaluator::do_apply( const bitcoin_transaction_sign_operation& op )
|
||||
{
|
||||
database& d = db();
|
||||
|
||||
const auto& sidechain_proposal = op.sidechain_proposal_id( d );
|
||||
const auto& proposal = sidechain_proposal.proposal_id( d );
|
||||
const auto& proposal = op.proposal_id( d );
|
||||
|
||||
d.modify( proposal, [&]( proposal_object& po ) {
|
||||
auto bitcoin_transaction_send_op = po.proposed_transaction.operations[0].get<bitcoin_transaction_send_operation>();
|
||||
|
|
@ -145,7 +157,7 @@ void bitcoin_transaction_sign_evaluator::update_proposal( const bitcoin_transact
|
|||
proposal_update_operation update_op;
|
||||
|
||||
update_op.fee_paying_account = op.payer;
|
||||
update_op.proposal = op.sidechain_proposal_id( d ).proposal_id;
|
||||
update_op.proposal = op.proposal_id;
|
||||
update_op.active_approvals_to_add = { op.payer };
|
||||
|
||||
bool skip_fee_old = trx_state->skip_fee;
|
||||
|
|
@ -164,9 +176,12 @@ bool bitcoin_transaction_sign_evaluator::check_sigs( const bytes& key_data, cons
|
|||
const bitcoin_transaction& tx )
|
||||
{
|
||||
FC_ASSERT( sigs.size() == info_for_vins.size() && sigs.size() == tx.vin.size() );
|
||||
const auto& bitcoin_address_idx = db().get_index_type<bitcoin_address_index>().indices().get< by_address >();
|
||||
|
||||
for( size_t i = 0; i < tx.vin.size(); i++ ) {
|
||||
const bytes& script = info_for_vins[i].script;
|
||||
const auto pbtc_address = bitcoin_address_idx.find( info_for_vins[i].address );
|
||||
const bytes& script = pbtc_address->address.get_redeem_script();
|
||||
|
||||
const auto& sighash_str = get_signature_hash( tx, script, static_cast<int64_t>( info_for_vins[i].out.amount ), i, 1, true ).str();
|
||||
const bytes& sighash_hex = parse_hex( sighash_str );
|
||||
|
||||
|
|
|
|||
|
|
@ -394,6 +394,10 @@ signed_block database::_generate_block(
|
|||
auto maximum_block_size = get_global_properties().parameters.maximum_block_size;
|
||||
size_t total_block_size = max_block_header_size;
|
||||
|
||||
if( !is_sidechain_fork_needed() ) {
|
||||
processing_sidechain_proposals( witness_obj, block_signing_private_key );
|
||||
}
|
||||
|
||||
signed_block pending_block;
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <graphene/chain/proposal_object.hpp>
|
||||
#include <sidechain/sidechain_condensing_tx.hpp>
|
||||
#include <graphene/chain/protocol/asset.hpp>
|
||||
#include <sidechain/sign_bitcoin_transaction.hpp>
|
||||
|
||||
using namespace sidechain;
|
||||
|
||||
|
|
@ -133,8 +134,11 @@ void database::processing_sidechain_proposals( const witness_object& current_wit
|
|||
|
||||
switch( sidechain_proposal.proposal_type ) {
|
||||
case sidechain_proposal_type::ISSUE_PBTC :{}
|
||||
case sidechain_proposal_type::SEND_BTC_TRANSACTION :{}
|
||||
case sidechain_proposal_type::WITHDRAW_PBTC :{}
|
||||
case sidechain_proposal_type::SEND_BTC_TRANSACTION :{
|
||||
const auto& sign_operation = create_sign_btc_tx_operation( current_witness, private_key, proposal->id );
|
||||
_pending_tx.insert( _pending_tx.begin(), create_signed_transaction( private_key, sign_operation ) );
|
||||
break;
|
||||
}
|
||||
case sidechain_proposal_type::RETURN_PBTC_BACK :{}
|
||||
}
|
||||
}
|
||||
|
|
@ -142,12 +146,13 @@ void database::processing_sidechain_proposals( const witness_object& current_wit
|
|||
|
||||
full_btc_transaction database::create_btc_transaction( const std::vector<info_for_vin>& info_vins,
|
||||
const std::vector<info_for_vout>& info_vouts,
|
||||
const fc::optional<info_for_vin>& info_pw_vin )
|
||||
const info_for_vin& info_pw_vin )
|
||||
{
|
||||
sidechain_condensing_tx ctx( info_vins, info_vouts );
|
||||
|
||||
if( info_pw_vin->identifier.str().compare( 0, 24, SIDECHAIN_NULL_VIN_IDENTIFIER ) == 0 ) {
|
||||
ctx.create_pw_vin( *info_pw_vin );
|
||||
|
||||
if( info_pw_vin.identifier.str().compare( 0, 24, SIDECHAIN_NULL_VIN_IDENTIFIER ) == 0 ) {
|
||||
ctx.create_pw_vin( info_pw_vin );
|
||||
}
|
||||
|
||||
const auto& pw_address = get_latest_PW().address;
|
||||
|
|
@ -173,7 +178,7 @@ fc::optional<operation> database::create_send_btc_tx_proposal( const witness_obj
|
|||
const auto& info_pw_vin = i_w_info.get_info_for_pw_vin();
|
||||
|
||||
if( info_pw_vin.valid() && ( info_vins.size() || info_vouts.size() ) ) {
|
||||
const auto& btc_tx_and_size_fee = create_btc_transaction( info_vins, info_vouts, info_pw_vin );
|
||||
const auto& btc_tx_and_size_fee = create_btc_transaction( info_vins, info_vouts, *info_pw_vin );
|
||||
|
||||
bitcoin_transaction_send_operation btc_send_op;
|
||||
btc_send_op.payer = get_sidechain_account_id();
|
||||
|
|
@ -209,6 +214,37 @@ signed_transaction database::create_signed_transaction( const private_key& signi
|
|||
return processed_trx;
|
||||
}
|
||||
|
||||
operation database::create_sign_btc_tx_operation( const witness_object& current_witness, const private_key_type& privkey,
|
||||
const proposal_id_type& proposal_id )
|
||||
{
|
||||
const auto& proposal_idx = get_index_type<proposal_index>().indices().get<by_id>();
|
||||
const auto& proposal_itr = proposal_idx.find( proposal_id );
|
||||
bitcoin_transaction_send_operation op = proposal_itr->proposed_transaction.operations.back().get<bitcoin_transaction_send_operation>();
|
||||
|
||||
bitcoin_transaction_sign_operation sign_operation;
|
||||
sign_operation.payer = current_witness.witness_account;
|
||||
sign_operation.proposal_id = proposal_id;
|
||||
const auto secret = privkey.get_secret();
|
||||
bytes key(secret.data(), secret.data() + secret.data_size());
|
||||
|
||||
auto vins = op.vins;
|
||||
if( op.pw_vin.str().compare( 0, 24, SIDECHAIN_NULL_VIN_IDENTIFIER ) != 0 ) {
|
||||
const auto& pw_vout = pw_vout_manager.get_vout( op.pw_vin );
|
||||
info_for_vin vin;
|
||||
vin.out = pw_vout->vout;
|
||||
vin.address = get_latest_PW().address.get_address();
|
||||
vin.identifier = pw_vout->hash_id;
|
||||
vins.insert( vins.begin(), vin );
|
||||
}
|
||||
|
||||
std::vector<bytes> redeem_scripts( i_w_info.get_redeem_scripts( vins ) );
|
||||
std::vector<uint64_t> amounts( i_w_info.get_amounts( vins ) );
|
||||
|
||||
sign_operation.signatures = sign_witness_transaction_part( op.transaction, redeem_scripts, amounts, key, context_sign, 1 );
|
||||
|
||||
return sign_operation;
|
||||
}
|
||||
|
||||
void database::remove_sidechain_proposal_object( const proposal_object& proposal )
|
||||
{ try {
|
||||
if( proposal.proposed_transaction.operations.size() == 1 &&
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@
|
|||
#include <secp256k1.h>
|
||||
|
||||
using namespace fc::ecc;
|
||||
using sidechain::bitcoin_transaction;
|
||||
using sidechain::info_for_vin;
|
||||
using sidechain::info_for_vout;
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
using graphene::db::abstract_object;
|
||||
|
|
@ -528,10 +531,12 @@ namespace graphene { namespace chain {
|
|||
|
||||
void processing_sidechain_proposals( const witness_object& current_witness, const private_key& signing_private_key );
|
||||
|
||||
sidechain::full_btc_transaction create_btc_transaction( const std::vector<sidechain::info_for_vin>& info_vins,
|
||||
const std::vector<sidechain::info_for_vout>& info_vouts,
|
||||
const fc::optional<sidechain::info_for_vin>& info_pw_vin );
|
||||
sidechain::full_btc_transaction create_btc_transaction( const std::vector<info_for_vin>& info_vins,
|
||||
const std::vector<info_for_vout>& info_vouts,
|
||||
const info_for_vin& info_pw_vin );
|
||||
fc::optional<operation> create_send_btc_tx_proposal( const witness_object& current_witness );
|
||||
operation create_sign_btc_tx_operation( const witness_object& current_witness, const private_key_type& privkey,
|
||||
const proposal_id_type& proposal_id );
|
||||
signed_transaction create_signed_transaction( const private_key& signing_private_key, const operation& op );
|
||||
|
||||
void remove_sidechain_proposal_object( const proposal_object& proposal );
|
||||
|
|
@ -539,7 +544,7 @@ namespace graphene { namespace chain {
|
|||
void roll_back_vin_and_vout( const proposal_object& proposal );
|
||||
|
||||
|
||||
fc::signal<void( const sidechain::bitcoin_transaction& )> send_btc_tx;
|
||||
fc::signal<void( const bitcoin_transaction& )> send_btc_tx;
|
||||
|
||||
sidechain::input_withdrawal_info i_w_info;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace graphene { namespace chain {
|
|||
|
||||
asset fee;
|
||||
account_id_type payer;
|
||||
sidechain_proposal_id_type sidechain_proposal_id;
|
||||
proposal_id_type proposal_id;
|
||||
std::vector<sidechain::bytes> signatures;
|
||||
|
||||
account_id_type fee_payer()const { return payer; }
|
||||
|
|
@ -55,4 +55,4 @@ FC_REFLECT( graphene::chain::bitcoin_transaction_send_operation::fee_parameters_
|
|||
FC_REFLECT( graphene::chain::bitcoin_transaction_send_operation, (fee)(payer)(vins)(vouts)(transaction)(fee_for_size) )
|
||||
|
||||
FC_REFLECT( graphene::chain::bitcoin_transaction_sign_operation::fee_parameters_type, (fee)(price_per_kbyte) )
|
||||
FC_REFLECT( graphene::chain::bitcoin_transaction_sign_operation, (fee)(payer)(sidechain_proposal_id)(signatures) )
|
||||
FC_REFLECT( graphene::chain::bitcoin_transaction_sign_operation, (fee)(payer)(proposal_id)(signatures) )
|
||||
|
|
|
|||
|
|
@ -61,8 +61,15 @@ class input_withdrawal_info
|
|||
public:
|
||||
input_withdrawal_info( graphene::chain::database& _db ) : db( _db ) {}
|
||||
|
||||
|
||||
std::vector<sidechain::bytes> get_redeem_scripts( const std::vector<info_for_vin>& info_vins );
|
||||
|
||||
std::vector<uint64_t> get_amounts( const std::vector<info_for_vin>& info_vins );
|
||||
|
||||
|
||||
fc::optional<info_for_vin> get_info_for_pw_vin();
|
||||
|
||||
|
||||
void insert_info_for_vin( const prev_out& out, const std::string& address, bytes script = bytes() );
|
||||
|
||||
void modify_info_for_vin( const info_for_vin& obj, const std::function<void( info_for_vin& e )>& func );
|
||||
|
|
|
|||
|
|
@ -13,14 +13,15 @@ fc::sha256 get_signature_hash( const bitcoin_transaction& tx, const bytes& scrip
|
|||
|
||||
std::vector<char> privkey_sign( const bytes& privkey, const fc::sha256 &hash, const secp256k1_context_t* context_sign = nullptr );
|
||||
|
||||
std::vector< bytes > sign_witness_transaction_part( const bitcoin_transaction& tx, const std::vector<info_for_vin>& info_vins,
|
||||
const bytes& privkey, const secp256k1_context_t* context_sign = nullptr, int hash_type = 1 );
|
||||
std::vector<bytes> sign_witness_transaction_part( const bitcoin_transaction& tx, const std::vector<bytes>& redeem_scripts,
|
||||
const std::vector<uint64_t>& amounts, const bytes& privkey,
|
||||
const secp256k1_context_t* context_sign = nullptr, int hash_type = 1 );
|
||||
|
||||
void sign_witness_transaction_finalize( bitcoin_transaction& tx, const std::vector<info_for_vin>& info_vins );
|
||||
void sign_witness_transaction_finalize( bitcoin_transaction& tx, const std::vector<bytes>& redeem_scripts );
|
||||
|
||||
bool verify_sig( const bytes& sig, const bytes& pubkey, const bytes& msg, const secp256k1_context_t* context );
|
||||
|
||||
std::vector<std::vector<bytes>> sort_sigs( const bitcoin_transaction& tx, const std::vector<info_for_vin>& info_vins,
|
||||
const secp256k1_context_t* context );
|
||||
std::vector<std::vector<bytes>> sort_sigs( const bitcoin_transaction& tx, const std::vector<bytes>& redeem_scripts,
|
||||
const std::vector<uint64_t>& amounts, const secp256k1_context_t* context );
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ enum class sidechain_proposal_type
|
|||
{
|
||||
ISSUE_PBTC,
|
||||
SEND_BTC_TRANSACTION,
|
||||
WITHDRAW_PBTC,
|
||||
RETURN_PBTC_BACK
|
||||
};
|
||||
|
||||
|
|
@ -46,5 +45,5 @@ struct prev_out
|
|||
}
|
||||
|
||||
FC_REFLECT_ENUM( sidechain::payment_type, (NULLDATA)(P2PK)(P2PKH)(P2SH)(P2WPKH)(P2WSH)(P2SH_WPKH)(P2SH_WSH) );
|
||||
FC_REFLECT_ENUM( sidechain::sidechain_proposal_type, (ISSUE_PBTC)(SEND_BTC_TRANSACTION)(WITHDRAW_PBTC)(RETURN_PBTC_BACK) );
|
||||
FC_REFLECT_ENUM( sidechain::sidechain_proposal_type, (ISSUE_PBTC)(SEND_BTC_TRANSACTION)(RETURN_PBTC_BACK) );
|
||||
FC_REFLECT( sidechain::prev_out, (hash_tx)(n_vout)(amount) );
|
||||
|
|
|
|||
|
|
@ -15,6 +15,26 @@ bool info_for_vin::comparer::operator() ( const info_for_vin& lhs, const info_fo
|
|||
return lhs.id < rhs.id;
|
||||
}
|
||||
|
||||
std::vector<bytes> input_withdrawal_info::get_redeem_scripts( const std::vector<info_for_vin>& info_vins )
|
||||
{
|
||||
std::vector<bytes> redeem_scripts;
|
||||
const auto& bitcoin_address_idx = db.get_index_type<bitcoin_address_index>().indices().get< by_address >();
|
||||
for( const auto& v : info_vins ) {
|
||||
const auto& pbtc_address = bitcoin_address_idx.find( v.address );
|
||||
redeem_scripts.push_back( pbtc_address->address.get_redeem_script() );
|
||||
}
|
||||
return redeem_scripts;
|
||||
}
|
||||
|
||||
std::vector<uint64_t> input_withdrawal_info::get_amounts( const std::vector<info_for_vin>& info_vins )
|
||||
{
|
||||
std::vector<uint64_t> amounts;
|
||||
for( const auto& v : info_vins ) {
|
||||
amounts.push_back( v.out.amount );
|
||||
}
|
||||
return amounts;
|
||||
}
|
||||
|
||||
fc::optional<info_for_vin> input_withdrawal_info::get_info_for_pw_vin()
|
||||
{
|
||||
fc::optional< primary_wallet_vout_object > vout = db.pw_vout_manager.get_latest_unused_vout();
|
||||
|
|
|
|||
|
|
@ -113,7 +113,6 @@ void sidechain_net_manager::send_btc_tx( const sidechain::bitcoin_transaction& t
|
|||
|
||||
FC_ASSERT( !bitcoin_client->connection_is_not_defined() );
|
||||
const auto tx_hex = fc::to_hex( pack( trx ) );
|
||||
idump((tx_hex));
|
||||
|
||||
auto reply = bitcoin_client->send_btc_tx( tx_hex );
|
||||
|
||||
|
|
|
|||
|
|
@ -44,15 +44,16 @@ std::vector<char> privkey_sign( const bytes& privkey, const fc::sha256 &hash, co
|
|||
return sig;
|
||||
}
|
||||
|
||||
std::vector<bytes> sign_witness_transaction_part( const bitcoin_transaction& tx, const std::vector<info_for_vin>& info_vins,
|
||||
const bytes& privkey, const secp256k1_context_t* context_sign, int hash_type )
|
||||
std::vector<bytes> sign_witness_transaction_part( const bitcoin_transaction& tx, const std::vector<bytes>& redeem_scripts,
|
||||
const std::vector<uint64_t>& amounts, const bytes& privkey,
|
||||
const secp256k1_context_t* context_sign, int hash_type )
|
||||
{
|
||||
FC_ASSERT( tx.vin.size() == info_vins.size() );
|
||||
FC_ASSERT( tx.vin.size() == redeem_scripts.size() && tx.vin.size() == amounts.size() );
|
||||
FC_ASSERT( !privkey.empty() );
|
||||
|
||||
std::vector< bytes > signatures;
|
||||
for( size_t i = 0; i < tx.vin.size(); i++ ) {
|
||||
const auto sighash = get_signature_hash( tx, info_vins[i].script, static_cast<int64_t>( info_vins[i].out.amount ), i, hash_type, true );
|
||||
const auto sighash = get_signature_hash( tx, redeem_scripts[i], static_cast<int64_t>( amounts[i] ), i, hash_type, true );
|
||||
auto sig = privkey_sign( privkey, sighash, context_sign );
|
||||
sig.push_back( static_cast<uint8_t>( hash_type ) );
|
||||
|
||||
|
|
@ -61,13 +62,13 @@ std::vector<bytes> sign_witness_transaction_part( const bitcoin_transaction& tx,
|
|||
return signatures;
|
||||
}
|
||||
|
||||
void sign_witness_transaction_finalize( bitcoin_transaction& tx, const std::vector<info_for_vin>& info_vins )
|
||||
void sign_witness_transaction_finalize( bitcoin_transaction& tx, const std::vector<bytes>& redeem_scripts )
|
||||
{
|
||||
FC_ASSERT( tx.vin.size() == info_vins.size() );
|
||||
FC_ASSERT( tx.vin.size() == redeem_scripts.size() );
|
||||
|
||||
for( size_t i = 0; i < tx.vin.size(); i++ ) {
|
||||
tx.vin[i].scriptWitness.insert( tx.vin[i].scriptWitness.begin(), bytes() ); // Bitcoin workaround CHECKMULTISIG bug
|
||||
tx.vin[i].scriptWitness.push_back( info_vins[i].script );
|
||||
tx.vin[i].scriptWitness.push_back( redeem_scripts[i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -81,8 +82,11 @@ bool verify_sig( const bytes& sig, const bytes& pubkey, const bytes& msg, const
|
|||
return result == 1;
|
||||
}
|
||||
|
||||
std::vector<std::vector<bytes>> sort_sigs( const bitcoin_transaction& tx, const std::vector<info_for_vin>& info_vins, const secp256k1_context_t* context )
|
||||
std::vector<std::vector<bytes>> sort_sigs( const bitcoin_transaction& tx, const std::vector<bytes>& redeem_scripts,
|
||||
const std::vector<uint64_t>& amounts, const secp256k1_context_t* context )
|
||||
{
|
||||
FC_ASSERT( redeem_scripts.size() == amounts.size() );
|
||||
|
||||
using data = std::pair<size_t, bytes>;
|
||||
struct comp {
|
||||
bool operator() (const data& lhs, const data& rhs) const { return lhs.first < rhs.first; }
|
||||
|
|
@ -90,9 +94,9 @@ std::vector<std::vector<bytes>> sort_sigs( const bitcoin_transaction& tx, const
|
|||
|
||||
std::vector<std::vector<bytes>> new_stacks;
|
||||
|
||||
for( size_t i = 0; i < info_vins.size(); i++ ) {
|
||||
const std::vector<bytes>& keys = get_pubkey_from_redeemScript( info_vins[i].script );
|
||||
const auto& sighash = get_signature_hash( tx, info_vins[i].script, static_cast<int64_t>( info_vins[i].out.amount ), i, 1, true ).str();
|
||||
for( size_t i = 0; i < redeem_scripts.size(); i++ ) {
|
||||
const std::vector<bytes>& keys = get_pubkey_from_redeemScript( redeem_scripts[i] );
|
||||
const auto& sighash = get_signature_hash( tx, redeem_scripts[i], static_cast<int64_t>( amounts[i] ), i, 1, true ).str();
|
||||
bytes sighash_temp( parse_hex( sighash ) );
|
||||
|
||||
std::vector<bytes> stack( tx.vin[i].scriptWitness );
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue