Add signing and verification tests and sign_transaction_standalone
This commit is contained in:
parent
b08d34d62f
commit
73e0673199
7 changed files with 233 additions and 4 deletions
|
|
@ -3,6 +3,12 @@
|
|||
|
||||
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
||||
|
||||
const secp256k1_context_t *btc_context()
|
||||
{
|
||||
static secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
fc::sha256 get_signature_hash( const bitcoin_transaction& tx, const bytes& scriptCode, int64_t amount,
|
||||
size_t in_index, int hash_type, bool is_witness )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,25 @@
|
|||
#include <graphene/peerplays_sidechain/bitcoin/utils.hpp>
|
||||
#include <fc/crypto/base58.hpp>
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
||||
|
||||
fc::ecc::public_key_data create_public_key_data( const std::vector<char>& public_key )
|
||||
{
|
||||
FC_ASSERT( public_key.size() == 33 );
|
||||
fc::ecc::public_key_data key;
|
||||
for(size_t i = 0; i < 33; i++) {
|
||||
key.at(i) = public_key[i];
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
bytes get_privkey_bytes( const std::string& privkey_base58 )
|
||||
{
|
||||
const auto privkey = fc::from_base58( privkey_base58 );
|
||||
// Remove version and hash
|
||||
return bytes( privkey.cbegin() + 1, privkey.cbegin() + 1 + 32 );
|
||||
}
|
||||
|
||||
bytes parse_hex( const std::string& str )
|
||||
{
|
||||
bytes vec( str.size() / 2 );
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
|||
|
||||
class bitcoin_transaction;
|
||||
|
||||
const secp256k1_context_t *btc_context();
|
||||
|
||||
fc::sha256 get_signature_hash( const bitcoin_transaction& tx, const bytes& scriptPubKey, int64_t amount,
|
||||
size_t in_index, int hash_type, bool is_witness );
|
||||
|
||||
|
|
@ -24,4 +26,4 @@ bool verify_sig( const bytes& sig, const bytes& pubkey, const bytes& msg, const
|
|||
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 );
|
||||
|
||||
} } }
|
||||
} } }
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
|
||||
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
||||
|
||||
fc::ecc::public_key_data create_public_key_data( const std::vector<char>& public_key );
|
||||
|
||||
bytes get_privkey_bytes( const std::string& privkey_base58 );
|
||||
|
||||
bytes parse_hex( const std::string& str );
|
||||
|
||||
std::vector<bytes> get_pubkey_from_redeemScript( bytes script );
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <graphene/chain/son_wallet_object.hpp>
|
||||
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_transaction.hpp>
|
||||
#include <graphene/peerplays_sidechain/bitcoin/serialize.hpp>
|
||||
#include <graphene/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.hpp>
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain {
|
||||
|
||||
|
|
@ -1435,7 +1436,7 @@ std::vector<std::vector<unsigned char>> read_byte_arrays_from_string(const std::
|
|||
return data;
|
||||
}
|
||||
|
||||
std::string write_byte_arrays_to_string(const std::vector<std::vector<unsigned char>>& data)
|
||||
std::string write_byte_arrays_to_string(const std::vector<bitcoin::bytes>& data)
|
||||
{
|
||||
std::string res = "[";
|
||||
for (unsigned int idx = 0; idx < data.size(); ++idx) {
|
||||
|
|
@ -1461,6 +1462,17 @@ void read_tx_data_from_string(const std::string &string_buf, std::vector<unsigne
|
|||
in_amounts.push_back(fc::to_uint64(v.second.data()));
|
||||
}
|
||||
|
||||
void read_tx_data_from_string(const std::string &string_buf, std::string &tx_hex, std::vector<uint64_t> &in_amounts)
|
||||
{
|
||||
std::stringstream ss(string_buf);
|
||||
boost::property_tree::ptree json;
|
||||
boost::property_tree::read_json(ss, json);
|
||||
tx_hex = json.get<std::string>("tx_hex");
|
||||
in_amounts.clear();
|
||||
for(auto &v: json.get_child("in_amounts"))
|
||||
in_amounts.push_back(fc::to_uint64(v.second.data()));
|
||||
}
|
||||
|
||||
std::string save_tx_data_to_string(const std::vector<unsigned char> &tx, const std::vector<uint64_t> &in_amounts)
|
||||
{
|
||||
std::string res = "{\"tx_hex\":\"" + fc::to_hex((const char*)&tx[0], tx.size()) + "\",\"in_amounts\":[";
|
||||
|
|
@ -1669,9 +1681,36 @@ std::string sidechain_net_handler_bitcoin::sign_transaction_psbt(const sidechain
|
|||
std::string sidechain_net_handler_bitcoin::sign_transaction_standalone(const sidechain_transaction_object &sto) {
|
||||
std::string pubkey = plugin.get_current_son_object().sidechain_public_keys.at(sidechain);
|
||||
std::string prvkey = get_private_key(pubkey);
|
||||
using namespace bitcoin;
|
||||
std::vector<uint64_t> in_amounts;
|
||||
std::string tx_hex;
|
||||
|
||||
|
||||
return "";
|
||||
const auto privkey_signing = get_privkey_bytes( prvkey );
|
||||
|
||||
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<bitcoin::bytes> redeem_scripts(tx.vin.size(), rscript);
|
||||
|
||||
auto sigs = sign_witness_transaction_part( tx, redeem_scripts, in_amounts, privkey_signing, btc_context(), 1 );
|
||||
|
||||
std::string tx_signature = write_byte_arrays_to_string(sigs);
|
||||
|
||||
wlog("skoneru: signatures: ${s}", ("s", tx_signature));
|
||||
|
||||
return tx_signature;
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_bitcoin::send_transaction_raw(const sidechain_transaction_object &sto) {
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ BOOST_AUTO_TEST_CASE( create_segwit_address_10_of_14_test )
|
|||
std::vector<char> public_key14 = parse_hex( "0287bcbd4f5d357f89a86979b386402445d7e9a5dccfd16146d1d2ab0dc2c32ae8" );
|
||||
|
||||
std::vector<char> witness_script = parse_hex("0020b70a52b55974d3c8c1a2055bf23e2d6421942135c7be1f786ad8cbce2f532cef");
|
||||
std::vector<char> redeem_script = parse_hex("5a2103456772301e221026269d3095ab5cb623fc239835b583ae4632f99a15107ef2752102d67c26cf20153fe7625ca1454222d3b3aeb53b122d8a0f7d32a3dd4b2c2016f421025f7cfda933516fd590c5a34ad4a68e3143b6f4155a64b3aab2c55fb851150f61210228155bb1ddcd11c7f14a2752565178023aa963f84ea6b6a052bddebad6fe986621037500441cfb4484da377073459511823b344f1ef0d46bac1efd4c7c466746f6662102ef0d79bfdb99ab0be674b1d5d06c24debd74bffdc28d466633d6668cc281cccf210317941e4219548682fb8d8e172f0a8ce4d83ce21272435c85d598558c8e060b7f210266065b27f7e3d3ad45b471b1cd4e02de73fc4737dc2679915a45e293c5adcf8421023821cc3da7be9e8cdceb8f146e9ddd78a9519875ecc5b42fe645af690544bccf210229ff2b2106b76c27c393e82d71c20eec32bcf1f0cf1a9aca8a237269a67ff3e521024d113381cc09deb8a6da62e0470644d1a06de82be2725b5052668c8845a4a8da2103df2462a5a2f681a3896f61964a65566ff77448be9a55a6da18506fd9c6c051c12102bafba3096f546cc5831ce1e49ba7142478a659f2d689bbc70ed37235255172a8210287bcbd4f5d357f89a86979b386402445d7e9a5dccfd16146d1d2ab0dc2c32ae85eae");
|
||||
|
||||
fc::ecc::public_key_data key1 = create_public_key_data( public_key1 );
|
||||
fc::ecc::public_key_data key2 = create_public_key_data( public_key2 );
|
||||
|
|
@ -170,6 +171,7 @@ BOOST_AUTO_TEST_CASE( create_segwit_address_10_of_14_test )
|
|||
{ son_id_type(8), public_key_type(key8) }, { son_id_type(9), public_key_type(key9) }, { son_id_type(10), public_key_type(key10) }, { son_id_type(11), public_key_type(key11) },
|
||||
{ son_id_type(12), public_key_type(key12) }, { son_id_type(13), public_key_type(key13) }, { son_id_type(14), public_key_type(key14) },});
|
||||
BOOST_CHECK( address.get_witness_script() == witness_script );
|
||||
BOOST_CHECK( address.get_redeem_script() == redeem_script );
|
||||
BOOST_CHECK( address.get_address() == "2MwhYhBrZeb6mTf1kaWcYfLBCCQoMqQybFZ" );
|
||||
}
|
||||
|
||||
|
|
|
|||
158
tests/peerplays_sidechain/bitcoin_sign_tests.cpp
Normal file
158
tests/peerplays_sidechain/bitcoin_sign_tests.cpp
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue