WIP, Moving Bitcoin listener to plugin
- Fix include paths - Add missing files
This commit is contained in:
parent
bfa6babfd2
commit
942e571949
8 changed files with 887 additions and 643 deletions
|
|
@ -1,8 +1,8 @@
|
||||||
#include <sidechain/bitcoin_address.hpp>
|
#include <graphene/peerplays_sidechain/bitcoin_address.hpp>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fc/crypto/base58.hpp>
|
#include <fc/crypto/base58.hpp>
|
||||||
#include <sidechain/segwit_addr.hpp>
|
#include <graphene/peerplays_sidechain/segwit_addr.hpp>
|
||||||
#include <sidechain/bitcoin_script.hpp>
|
#include <graphene/peerplays_sidechain/bitcoin_script.hpp>
|
||||||
|
|
||||||
namespace sidechain {
|
namespace sidechain {
|
||||||
|
|
||||||
|
|
|
||||||
60
libraries/plugins/peerplays_sidechain/bitcoin_script.cpp
Normal file
60
libraries/plugins/peerplays_sidechain/bitcoin_script.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
#include <graphene/peerplays_sidechain/bitcoin_script.hpp>
|
||||||
|
#include <graphene/peerplays_sidechain/serialize.hpp>
|
||||||
|
|
||||||
|
namespace sidechain {
|
||||||
|
|
||||||
|
script_builder& script_builder::operator<<( op opcode )
|
||||||
|
{
|
||||||
|
const auto op_byte = static_cast<uint8_t>( opcode );
|
||||||
|
if ( op_byte < 0 || op_byte > 0xff )
|
||||||
|
throw std::runtime_error( "script_builder::operator<<(OP): invalid opcode" );
|
||||||
|
script.push_back( op_byte );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
script_builder& script_builder::operator<<( uint8_t number )
|
||||||
|
{
|
||||||
|
FC_ASSERT( 0 <= number && number <= 16 );
|
||||||
|
|
||||||
|
if ( number == 0 )
|
||||||
|
script.push_back( static_cast<uint8_t>( op::_0 ) );
|
||||||
|
else
|
||||||
|
script.push_back( static_cast<uint8_t>( op::_1 ) + number - 1 );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
script_builder& script_builder::operator<<( size_t size )
|
||||||
|
{
|
||||||
|
sidechain::write_compact_size( script, size );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
script_builder& script_builder::operator<<( const bytes& sc ) {
|
||||||
|
sidechain::write_compact_size( script, sc.size() );
|
||||||
|
script.insert( script.end(), sc.begin(), sc.end() );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
script_builder& script_builder::operator<<( const fc::sha256& hash )
|
||||||
|
{
|
||||||
|
sidechain::write_compact_size( script, hash.data_size() );
|
||||||
|
script.insert( script.end(), hash.data(), hash.data() + hash.data_size() );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
script_builder& script_builder::operator<<( const fc::ripemd160& hash )
|
||||||
|
{
|
||||||
|
sidechain::write_compact_size( script, hash.data_size() );
|
||||||
|
script.insert( script.end(), hash.data(), hash.data() + hash.data_size() );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
script_builder& script_builder::operator<<( const fc::ecc::public_key_data& pubkey_data )
|
||||||
|
{
|
||||||
|
sidechain::write_compact_size( script, pubkey_data.size() );
|
||||||
|
script.insert( script.end(), pubkey_data.begin(), pubkey_data.begin() + pubkey_data.size() );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,279 +1,279 @@
|
||||||
//#include <sidechain/bitcoin_transaction.hpp>
|
#include <graphene/peerplays_sidechain/bitcoin_transaction.hpp>
|
||||||
//#include <fc/crypto/base58.hpp>
|
#include <fc/crypto/base58.hpp>
|
||||||
//#include <sidechain/bitcoin_script.hpp>
|
#include <graphene/peerplays_sidechain/bitcoin_script.hpp>
|
||||||
//#include <sidechain/serialize.hpp>
|
#include <graphene/peerplays_sidechain/serialize.hpp>
|
||||||
//
|
|
||||||
//namespace sidechain {
|
namespace sidechain {
|
||||||
//
|
|
||||||
//bool out_point::operator==( const out_point& op ) const
|
bool out_point::operator==( const out_point& op ) const
|
||||||
//{
|
{
|
||||||
// if( this->hash == op.hash &&
|
if( this->hash == op.hash &&
|
||||||
// this->n == op.n )
|
this->n == op.n )
|
||||||
// {
|
{
|
||||||
// return true;
|
return true;
|
||||||
// }
|
}
|
||||||
// return false;
|
return false;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//bool tx_in::operator==( const tx_in& ti ) const
|
bool tx_in::operator==( const tx_in& ti ) const
|
||||||
//{
|
{
|
||||||
// if( this->prevout == ti.prevout &&
|
if( this->prevout == ti.prevout &&
|
||||||
// this->scriptSig == ti.scriptSig &&
|
this->scriptSig == ti.scriptSig &&
|
||||||
// this->nSequence == ti.nSequence )
|
this->nSequence == ti.nSequence )
|
||||||
// {
|
{
|
||||||
// return true;
|
return true;
|
||||||
// }
|
}
|
||||||
// return false;
|
return false;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//bool tx_out::operator==( const tx_out& to ) const
|
bool tx_out::operator==( const tx_out& to ) const
|
||||||
//{
|
{
|
||||||
// if( this->value == to.value &&
|
if( this->value == to.value &&
|
||||||
// this->scriptPubKey == to.scriptPubKey )
|
this->scriptPubKey == to.scriptPubKey )
|
||||||
// {
|
{
|
||||||
// return true;
|
return true;
|
||||||
// }
|
}
|
||||||
// return false;
|
return false;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//bool tx_out::is_p2wsh() const
|
bool tx_out::is_p2wsh() const
|
||||||
//{
|
{
|
||||||
// if( scriptPubKey.size() == 34 && scriptPubKey[0] == static_cast<char>(0x00) && scriptPubKey[1] == static_cast<char>(0x20) ) {
|
if( scriptPubKey.size() == 34 && scriptPubKey[0] == static_cast<char>(0x00) && scriptPubKey[1] == static_cast<char>(0x20) ) {
|
||||||
// return true;
|
return true;
|
||||||
// }
|
}
|
||||||
// return false;
|
return false;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//bool tx_out::is_p2wpkh() const
|
bool tx_out::is_p2wpkh() const
|
||||||
//{
|
{
|
||||||
// if( scriptPubKey.size() == 22 && scriptPubKey[0] == static_cast<char>(0x00) && scriptPubKey[1] == static_cast<char>(0x14) ) {
|
if( scriptPubKey.size() == 22 && scriptPubKey[0] == static_cast<char>(0x00) && scriptPubKey[1] == static_cast<char>(0x14) ) {
|
||||||
// return true;
|
return true;
|
||||||
// }
|
}
|
||||||
// return false;
|
return false;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//bool tx_out::is_p2pkh() const
|
bool tx_out::is_p2pkh() const
|
||||||
//{
|
{
|
||||||
// if( scriptPubKey.size() == 25 && scriptPubKey[0] == static_cast<char>(0x76) && scriptPubKey[1] == static_cast<char>(0xa9) &&
|
if( scriptPubKey.size() == 25 && scriptPubKey[0] == static_cast<char>(0x76) && scriptPubKey[1] == static_cast<char>(0xa9) &&
|
||||||
// scriptPubKey[2] == static_cast<char>(0x14) && scriptPubKey[23] == static_cast<char>(0x88) && scriptPubKey[24] == static_cast<char>(0xac) ) {
|
scriptPubKey[2] == static_cast<char>(0x14) && scriptPubKey[23] == static_cast<char>(0x88) && scriptPubKey[24] == static_cast<char>(0xac) ) {
|
||||||
// return true;
|
return true;
|
||||||
// }
|
}
|
||||||
// return false;
|
return false;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//bool tx_out::is_p2sh() const
|
bool tx_out::is_p2sh() const
|
||||||
//{
|
{
|
||||||
// if( scriptPubKey.size() == 23 && scriptPubKey[0] == static_cast<char>(0xa9) &&
|
if( scriptPubKey.size() == 23 && scriptPubKey[0] == static_cast<char>(0xa9) &&
|
||||||
// scriptPubKey[1] == static_cast<char>(0x14) && scriptPubKey[22] == static_cast<char>(0x87) ) {
|
scriptPubKey[1] == static_cast<char>(0x14) && scriptPubKey[22] == static_cast<char>(0x87) ) {
|
||||||
// return true;
|
return true;
|
||||||
// }
|
}
|
||||||
// return false;
|
return false;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//bool tx_out::is_p2pk() const
|
bool tx_out::is_p2pk() const
|
||||||
//{
|
{
|
||||||
// if( scriptPubKey.size() == 35 && scriptPubKey[0] == static_cast<char>(0x21) && scriptPubKey[34] == static_cast<char>(0xac) ) {
|
if( scriptPubKey.size() == 35 && scriptPubKey[0] == static_cast<char>(0x21) && scriptPubKey[34] == static_cast<char>(0xac) ) {
|
||||||
// return true;
|
return true;
|
||||||
// }
|
}
|
||||||
// return false;
|
return false;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//bytes tx_out::get_data_or_script() const
|
bytes tx_out::get_data_or_script() const
|
||||||
//{
|
{
|
||||||
// if( is_p2pkh() ) {
|
if( is_p2pkh() ) {
|
||||||
// return bytes( scriptPubKey.begin() + 3, scriptPubKey.begin() + 23 );
|
return bytes( scriptPubKey.begin() + 3, scriptPubKey.begin() + 23 );
|
||||||
// } else if( is_p2sh() || is_p2wpkh() ) {
|
} else if( is_p2sh() || is_p2wpkh() ) {
|
||||||
// return bytes( scriptPubKey.begin() + 2, scriptPubKey.begin() + 22 );
|
return bytes( scriptPubKey.begin() + 2, scriptPubKey.begin() + 22 );
|
||||||
// } else if( is_p2wsh() ) {
|
} else if( is_p2wsh() ) {
|
||||||
// return bytes( scriptPubKey.begin() + 2, scriptPubKey.begin() + 34 );
|
return bytes( scriptPubKey.begin() + 2, scriptPubKey.begin() + 34 );
|
||||||
// } else if( is_p2pk() ) {
|
} else if( is_p2pk() ) {
|
||||||
// return bytes( scriptPubKey.begin() + 1, scriptPubKey.begin() + 34 );
|
return bytes( scriptPubKey.begin() + 1, scriptPubKey.begin() + 34 );
|
||||||
// }
|
}
|
||||||
// return scriptPubKey;
|
return scriptPubKey;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//bool bitcoin_transaction::operator!=( const bitcoin_transaction& bt ) const
|
bool bitcoin_transaction::operator!=( const bitcoin_transaction& bt ) const
|
||||||
//{
|
{
|
||||||
// if( this->nVersion != bt.nVersion ||
|
if( this->nVersion != bt.nVersion ||
|
||||||
// this->vin != bt.vin ||
|
this->vin != bt.vin ||
|
||||||
// this->vout != bt.vout ||
|
this->vout != bt.vout ||
|
||||||
// this->nLockTime != bt.nLockTime )
|
this->nLockTime != bt.nLockTime )
|
||||||
// {
|
{
|
||||||
// return true;
|
return true;
|
||||||
// }
|
}
|
||||||
// return false;
|
return false;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//fc::sha256 bitcoin_transaction::get_hash() const
|
fc::sha256 bitcoin_transaction::get_hash() const
|
||||||
//{
|
{
|
||||||
// const auto bytes = pack( *this, true) ;
|
const auto bytes = pack( *this, true) ;
|
||||||
// const auto hash = fc::sha256::hash( fc::sha256::hash(bytes.data(), bytes.size()) );
|
const auto hash = fc::sha256::hash( fc::sha256::hash(bytes.data(), bytes.size()) );
|
||||||
// std::reverse( hash.data(), hash.data() + hash.data_size() );
|
std::reverse( hash.data(), hash.data() + hash.data_size() );
|
||||||
// return hash;
|
return hash;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//fc::sha256 bitcoin_transaction::get_txid() const
|
fc::sha256 bitcoin_transaction::get_txid() const
|
||||||
//{
|
{
|
||||||
// const auto bytes = pack( *this, false );
|
const auto bytes = pack( *this, false );
|
||||||
// const auto hash = fc::sha256::hash( fc::sha256::hash(bytes.data(), bytes.size()) );
|
const auto hash = fc::sha256::hash( fc::sha256::hash(bytes.data(), bytes.size()) );
|
||||||
// std::reverse( hash.data(), hash.data() + hash.data_size() );
|
std::reverse( hash.data(), hash.data() + hash.data_size() );
|
||||||
// return hash;
|
return hash;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//size_t bitcoin_transaction::get_vsize() const
|
size_t bitcoin_transaction::get_vsize() const
|
||||||
//{
|
{
|
||||||
// static const auto witness_scale_factor = 4;
|
static const auto witness_scale_factor = 4;
|
||||||
//
|
|
||||||
// fc::datastream<size_t> no_wit_ds;
|
fc::datastream<size_t> no_wit_ds;
|
||||||
// pack( no_wit_ds, *this, false );
|
pack( no_wit_ds, *this, false );
|
||||||
//
|
|
||||||
// fc::datastream<size_t> wit_ds;
|
fc::datastream<size_t> wit_ds;
|
||||||
// pack( wit_ds, *this, true );
|
pack( wit_ds, *this, true );
|
||||||
//
|
|
||||||
// const size_t weight = no_wit_ds.tellp() * ( witness_scale_factor - 1 ) + wit_ds.tellp();
|
const size_t weight = no_wit_ds.tellp() * ( witness_scale_factor - 1 ) + wit_ds.tellp();
|
||||||
// const size_t vsize = ( weight + witness_scale_factor - 1 ) / witness_scale_factor;
|
const size_t vsize = ( weight + witness_scale_factor - 1 ) / witness_scale_factor;
|
||||||
//
|
|
||||||
// return vsize;
|
return vsize;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//void bitcoin_transaction_builder::set_version( int32_t version )
|
void bitcoin_transaction_builder::set_version( int32_t version )
|
||||||
//{
|
{
|
||||||
// tx.nVersion = version;
|
tx.nVersion = version;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//void bitcoin_transaction_builder::set_locktime(uint32_t lock_time)
|
void bitcoin_transaction_builder::set_locktime(uint32_t lock_time)
|
||||||
//{
|
{
|
||||||
// tx.nLockTime = lock_time;
|
tx.nLockTime = lock_time;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//void bitcoin_transaction_builder::add_in( payment_type type, const fc::sha256& txid, uint32_t n_out, const bytes& script_code, bool front, uint32_t sequence )
|
void bitcoin_transaction_builder::add_in( payment_type type, const fc::sha256& txid, uint32_t n_out, const bytes& script_code, bool front, uint32_t sequence )
|
||||||
//{
|
{
|
||||||
// out_point prevout;
|
out_point prevout;
|
||||||
// prevout.hash = txid;
|
prevout.hash = txid;
|
||||||
// prevout.n = n_out;
|
prevout.n = n_out;
|
||||||
//
|
|
||||||
// tx_in txin;
|
tx_in txin;
|
||||||
// txin.prevout = prevout;
|
txin.prevout = prevout;
|
||||||
// txin.nSequence = sequence;
|
txin.nSequence = sequence;
|
||||||
//
|
|
||||||
// add_in( type, txin, script_code, front );
|
add_in( type, txin, script_code, front );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//void bitcoin_transaction_builder::add_in( payment_type type, tx_in txin, const bytes& script_code, bool front )
|
void bitcoin_transaction_builder::add_in( payment_type type, tx_in txin, const bytes& script_code, bool front )
|
||||||
//{
|
{
|
||||||
// switch ( type ) {
|
switch ( type ) {
|
||||||
// case payment_type::P2SH_WPKH:
|
case payment_type::P2SH_WPKH:
|
||||||
// case payment_type::P2SH_WSH:
|
case payment_type::P2SH_WSH:
|
||||||
// FC_ASSERT( script_code != bytes() );
|
FC_ASSERT( script_code != bytes() );
|
||||||
// txin.scriptSig = script_code;
|
txin.scriptSig = script_code;
|
||||||
// break;
|
break;
|
||||||
// default:{
|
default:{
|
||||||
// if( txin.prevout.hash == fc::sha256("0000000000000000000000000000000000000000000000000000000000000000") ) { //coinbase
|
if( txin.prevout.hash == fc::sha256("0000000000000000000000000000000000000000000000000000000000000000") ) { //coinbase
|
||||||
// FC_ASSERT( script_code != bytes() );
|
FC_ASSERT( script_code != bytes() );
|
||||||
// txin.scriptSig = script_code;
|
txin.scriptSig = script_code;
|
||||||
// }
|
}
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// if( front ) {
|
if( front ) {
|
||||||
// tx.vin.insert( tx.vin.begin(), txin );
|
tx.vin.insert( tx.vin.begin(), txin );
|
||||||
// } else {
|
} else {
|
||||||
// tx.vin.push_back( txin );
|
tx.vin.push_back( txin );
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//void bitcoin_transaction_builder::add_out( payment_type type, int64_t amount, const std::string& base58_address, bool front )
|
void bitcoin_transaction_builder::add_out( payment_type type, int64_t amount, const std::string& base58_address, bool front )
|
||||||
//{
|
{
|
||||||
// // TODO: add checks
|
// TODO: add checks
|
||||||
// const auto address_bytes = fc::from_base58(base58_address);
|
const auto address_bytes = fc::from_base58(base58_address);
|
||||||
// add_out( type, amount, bytes( address_bytes.begin() + 1, address_bytes.begin() + 1 + 20 ), front );
|
add_out( type, amount, bytes( address_bytes.begin() + 1, address_bytes.begin() + 1 + 20 ), front );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//void bitcoin_transaction_builder::add_out( payment_type type, int64_t amount, const fc::ecc::public_key_data& pubkey, bool front )
|
void bitcoin_transaction_builder::add_out( payment_type type, int64_t amount, const fc::ecc::public_key_data& pubkey, bool front )
|
||||||
//{
|
{
|
||||||
// FC_ASSERT( is_payment_to_pubkey( type ) );
|
FC_ASSERT( is_payment_to_pubkey( type ) );
|
||||||
//
|
|
||||||
// if ( type == payment_type::P2PK ) {
|
if ( type == payment_type::P2PK ) {
|
||||||
// const auto pubkey_bytes = bytes( pubkey.begin(), pubkey.begin() + pubkey.size() );
|
const auto pubkey_bytes = bytes( pubkey.begin(), pubkey.begin() + pubkey.size() );
|
||||||
// add_out( type, amount, pubkey_bytes, front );
|
add_out( type, amount, pubkey_bytes, front );
|
||||||
// } else {
|
} else {
|
||||||
// const auto hash256 = fc::sha256::hash( pubkey.begin(), pubkey.size() );
|
const auto hash256 = fc::sha256::hash( pubkey.begin(), pubkey.size() );
|
||||||
// const auto hash160 = fc::ripemd160::hash( hash256.data(), hash256.data_size() );
|
const auto hash160 = fc::ripemd160::hash( hash256.data(), hash256.data_size() );
|
||||||
// add_out( type, amount, bytes( hash160.data(), hash160.data() + hash160.data_size() ), front );
|
add_out( type, amount, bytes( hash160.data(), hash160.data() + hash160.data_size() ), front );
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//void bitcoin_transaction_builder::add_out( payment_type type, int64_t amount, const bytes& script_code, bool front )
|
void bitcoin_transaction_builder::add_out( payment_type type, int64_t amount, const bytes& script_code, bool front )
|
||||||
//{
|
{
|
||||||
// tx_out out;
|
tx_out out;
|
||||||
// out.value = amount;
|
out.value = amount;
|
||||||
// out.scriptPubKey = get_script_pubkey( type, script_code );
|
out.scriptPubKey = get_script_pubkey( type, script_code );
|
||||||
//
|
|
||||||
// if( front ) {
|
if( front ) {
|
||||||
// tx.vout.insert( tx.vout.begin(), out );
|
tx.vout.insert( tx.vout.begin(), out );
|
||||||
// } else {
|
} else {
|
||||||
// tx.vout.push_back( out );
|
tx.vout.push_back( out );
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//void bitcoin_transaction_builder::add_out_all_type( const uint64_t& amount, const bitcoin_address& address, bool front )
|
void bitcoin_transaction_builder::add_out_all_type( const uint64_t& amount, const bitcoin_address& address, bool front )
|
||||||
//{
|
{
|
||||||
// switch( address.get_type() ) {
|
switch( address.get_type() ) {
|
||||||
// case payment_type::P2PK: {
|
case payment_type::P2PK: {
|
||||||
// bytes raw_address( address.get_raw_address() );
|
bytes raw_address( address.get_raw_address() );
|
||||||
// fc::ecc::public_key_data public_key;
|
fc::ecc::public_key_data public_key;
|
||||||
// std::copy( raw_address.begin(), raw_address.end(), public_key.begin() );
|
std::copy( raw_address.begin(), raw_address.end(), public_key.begin() );
|
||||||
// add_out( address.get_type(), amount, public_key, front );
|
add_out( address.get_type(), amount, public_key, front );
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// case payment_type::P2PKH:
|
case payment_type::P2PKH:
|
||||||
// case payment_type::P2SH:
|
case payment_type::P2SH:
|
||||||
// case payment_type::P2SH_WPKH:
|
case payment_type::P2SH_WPKH:
|
||||||
// case payment_type::P2SH_WSH: {
|
case payment_type::P2SH_WSH: {
|
||||||
// add_out( address.get_type(), amount, address.get_address(), front );
|
add_out( address.get_type(), amount, address.get_address(), front );
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// case payment_type::P2WPKH:
|
case payment_type::P2WPKH:
|
||||||
// case payment_type::P2WSH: {
|
case payment_type::P2WSH: {
|
||||||
// add_out( address.get_type(), amount, address.get_raw_address(), front );
|
add_out( address.get_type(), amount, address.get_raw_address(), front );
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//inline bool bitcoin_transaction_builder::is_payment_to_pubkey( payment_type type )
|
inline bool bitcoin_transaction_builder::is_payment_to_pubkey( payment_type type )
|
||||||
//{
|
{
|
||||||
// switch ( type ) {
|
switch ( type ) {
|
||||||
// case payment_type::P2PK:
|
case payment_type::P2PK:
|
||||||
// case payment_type::P2PKH:
|
case payment_type::P2PKH:
|
||||||
// case payment_type::P2WPKH:
|
case payment_type::P2WPKH:
|
||||||
// case payment_type::P2SH_WPKH:
|
case payment_type::P2SH_WPKH:
|
||||||
// return true;
|
return true;
|
||||||
// default:
|
default:
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//bytes bitcoin_transaction_builder::get_script_pubkey( payment_type type, const bytes& script_code )
|
bytes bitcoin_transaction_builder::get_script_pubkey( payment_type type, const bytes& script_code )
|
||||||
//{
|
{
|
||||||
// switch ( type ) {
|
switch ( type ) {
|
||||||
// case payment_type::NULLDATA:
|
case payment_type::NULLDATA:
|
||||||
// return script_builder() << op::RETURN << script_code;
|
return script_builder() << op::RETURN << script_code;
|
||||||
// case payment_type::P2PK:
|
case payment_type::P2PK:
|
||||||
// return script_builder() << script_code << op::CHECKSIG;
|
return script_builder() << script_code << op::CHECKSIG;
|
||||||
// case payment_type::P2PKH:
|
case payment_type::P2PKH:
|
||||||
// return script_builder() << op::DUP << op::HASH160 << script_code << op::EQUALVERIFY << op::CHECKSIG;
|
return script_builder() << op::DUP << op::HASH160 << script_code << op::EQUALVERIFY << op::CHECKSIG;
|
||||||
// case payment_type::P2SH:
|
case payment_type::P2SH:
|
||||||
// case payment_type::P2SH_WPKH:
|
case payment_type::P2SH_WPKH:
|
||||||
// case payment_type::P2SH_WSH:
|
case payment_type::P2SH_WSH:
|
||||||
// return script_builder() << op::HASH160 << script_code << op::EQUAL;
|
return script_builder() << op::HASH160 << script_code << op::EQUAL;
|
||||||
// case payment_type::P2WPKH:
|
case payment_type::P2WPKH:
|
||||||
// case payment_type::P2WSH:
|
case payment_type::P2WSH:
|
||||||
// return script_builder() << op::_0 << script_code;
|
return script_builder() << op::_0 << script_code;
|
||||||
// default:
|
default:
|
||||||
// return script_code;
|
return script_code;
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <graphene/peerplays_sidechain/types.hpp>
|
||||||
|
|
||||||
|
namespace sidechain {
|
||||||
|
|
||||||
|
enum class op {
|
||||||
|
// push value
|
||||||
|
_0 = 0x00,
|
||||||
|
_1 = 0x51,
|
||||||
|
_2 = 0x52,
|
||||||
|
_3 = 0x53,
|
||||||
|
_4 = 0x54,
|
||||||
|
_5 = 0x55,
|
||||||
|
_6 = 0x56,
|
||||||
|
_7 = 0x57,
|
||||||
|
_8 = 0x58,
|
||||||
|
_9 = 0x59,
|
||||||
|
_10 = 0x5a,
|
||||||
|
_11 = 0x5b,
|
||||||
|
_12 = 0x5c,
|
||||||
|
_13 = 0x5d,
|
||||||
|
_14 = 0x5e,
|
||||||
|
_15 = 0x5f,
|
||||||
|
_16 = 0x60,
|
||||||
|
|
||||||
|
// control
|
||||||
|
RETURN = 0x6a,
|
||||||
|
|
||||||
|
// stack ops
|
||||||
|
DUP = 0x76,
|
||||||
|
|
||||||
|
// bit logic
|
||||||
|
EQUAL = 0x87,
|
||||||
|
EQUALVERIFY = 0x88,
|
||||||
|
|
||||||
|
// crypto
|
||||||
|
HASH160 = 0xa9,
|
||||||
|
CHECKSIG = 0xac,
|
||||||
|
CHECKMULTISIG = 0xae,
|
||||||
|
};
|
||||||
|
|
||||||
|
class script_builder {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
script_builder& operator<<( op opcode );
|
||||||
|
|
||||||
|
script_builder& operator<<( uint8_t number );
|
||||||
|
|
||||||
|
script_builder& operator<<( size_t size );
|
||||||
|
|
||||||
|
script_builder& operator<<( const bytes& sc );
|
||||||
|
|
||||||
|
script_builder& operator<<( const fc::sha256& hash );
|
||||||
|
|
||||||
|
script_builder& operator<<( const fc::ripemd160& hash );
|
||||||
|
|
||||||
|
script_builder& operator<<( const fc::ecc::public_key_data& pubkey_data );
|
||||||
|
|
||||||
|
operator bytes() const { return std::move( script ); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bytes script;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
/* Copyright (c) 2017 Pieter Wuille
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace sidechain { namespace segwit_addr {
|
||||||
|
|
||||||
|
/** Decode a SegWit address. Returns (witver, witprog). witver = -1 means failure. */
|
||||||
|
std::pair<int, std::vector<uint8_t> > decode(const std::string& hrp, const std::string& addr);
|
||||||
|
|
||||||
|
/** Encode a SegWit address. Empty string means failure. */
|
||||||
|
std::string encode(const std::string& hrp, int witver, const std::vector<uint8_t>& witprog);
|
||||||
|
|
||||||
|
} }
|
||||||
|
|
@ -1,360 +1,360 @@
|
||||||
//#pragma once
|
#pragma once
|
||||||
//
|
|
||||||
//#include <sidechain/types.hpp>
|
#include <graphene/peerplays_sidechain/types.hpp>
|
||||||
//#include <sidechain/bitcoin_transaction.hpp>
|
#include <graphene/peerplays_sidechain/bitcoin_transaction.hpp>
|
||||||
//
|
|
||||||
//namespace sidechain {
|
namespace sidechain {
|
||||||
//
|
|
||||||
//inline void write_compact_size( bytes& vec, size_t size )
|
inline void write_compact_size( bytes& vec, size_t size )
|
||||||
//{
|
{
|
||||||
// bytes sb;
|
bytes sb;
|
||||||
// sb.reserve( 2 );
|
sb.reserve( 2 );
|
||||||
// if ( size < 253 ) {
|
if ( size < 253 ) {
|
||||||
// sb.insert( sb.end(), static_cast<uint8_t>( size ) );
|
sb.insert( sb.end(), static_cast<uint8_t>( size ) );
|
||||||
// } else if ( size <= std::numeric_limits<unsigned short>::max() ) {
|
} else if ( size <= std::numeric_limits<unsigned short>::max() ) {
|
||||||
// uint16_t tmp = htole16( static_cast<uint16_t>( size ) );
|
uint16_t tmp = htole16( static_cast<uint16_t>( size ) );
|
||||||
// sb.insert( sb.end(), static_cast<uint8_t>( 253 ) );
|
sb.insert( sb.end(), static_cast<uint8_t>( 253 ) );
|
||||||
// sb.insert( sb.end(), reinterpret_cast<const char*>( tmp ), reinterpret_cast<const char*>( tmp ) + sizeof( tmp ) );
|
sb.insert( sb.end(), reinterpret_cast<const char*>( tmp ), reinterpret_cast<const char*>( tmp ) + sizeof( tmp ) );
|
||||||
// } else if ( size <= std::numeric_limits<unsigned int>::max() ) {
|
} else if ( size <= std::numeric_limits<unsigned int>::max() ) {
|
||||||
// uint32_t tmp = htole32( static_cast<uint32_t>( size ) );
|
uint32_t tmp = htole32( static_cast<uint32_t>( size ) );
|
||||||
// sb.insert( sb.end(), static_cast<uint8_t>( 254 ) );
|
sb.insert( sb.end(), static_cast<uint8_t>( 254 ) );
|
||||||
// sb.insert( sb.end(), reinterpret_cast<const char*>( tmp ), reinterpret_cast<const char*>( tmp ) + sizeof( tmp ) );
|
sb.insert( sb.end(), reinterpret_cast<const char*>( tmp ), reinterpret_cast<const char*>( tmp ) + sizeof( tmp ) );
|
||||||
// } else {
|
} else {
|
||||||
// uint64_t tmp = htole64( static_cast<uint64_t>( size ) );
|
uint64_t tmp = htole64( static_cast<uint64_t>( size ) );
|
||||||
// sb.insert( sb.end(), static_cast<uint8_t>( 255 ) );
|
sb.insert( sb.end(), static_cast<uint8_t>( 255 ) );
|
||||||
// sb.insert( sb.end(), reinterpret_cast<const char*>( tmp ), reinterpret_cast<const char*>( tmp ) + sizeof( tmp ) );
|
sb.insert( sb.end(), reinterpret_cast<const char*>( tmp ), reinterpret_cast<const char*>( tmp ) + sizeof( tmp ) );
|
||||||
// }
|
}
|
||||||
// vec.insert( vec.end(), sb.begin(), sb.end() );
|
vec.insert( vec.end(), sb.begin(), sb.end() );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream>
|
template<typename Stream>
|
||||||
//inline void pack_compact_size(Stream& s, size_t size)
|
inline void pack_compact_size(Stream& s, size_t size)
|
||||||
//{
|
{
|
||||||
// if ( size < 253 ) {
|
if ( size < 253 ) {
|
||||||
// fc::raw::pack( s, static_cast<uint8_t>( size ) );
|
fc::raw::pack( s, static_cast<uint8_t>( size ) );
|
||||||
// } else if ( size <= std::numeric_limits<unsigned short>::max() ) {
|
} else if ( size <= std::numeric_limits<unsigned short>::max() ) {
|
||||||
// fc::raw::pack( s, static_cast<uint8_t>( 253 ) );
|
fc::raw::pack( s, static_cast<uint8_t>( 253 ) );
|
||||||
// fc::raw::pack( s, htole16( static_cast<uint16_t>( size ) ) );
|
fc::raw::pack( s, htole16( static_cast<uint16_t>( size ) ) );
|
||||||
// } else if ( size <= std::numeric_limits<unsigned int>::max() ) {
|
} else if ( size <= std::numeric_limits<unsigned int>::max() ) {
|
||||||
// fc::raw::pack( s, static_cast<uint8_t>( 254 ) );
|
fc::raw::pack( s, static_cast<uint8_t>( 254 ) );
|
||||||
// fc::raw::pack( s, htole32(static_cast<uint32_t>( size ) ) );
|
fc::raw::pack( s, htole32(static_cast<uint32_t>( size ) ) );
|
||||||
// } else {
|
} else {
|
||||||
// fc::raw::pack( s, static_cast<uint8_t>( 255 ) );
|
fc::raw::pack( s, static_cast<uint8_t>( 255 ) );
|
||||||
// fc::raw::pack( s, htole64( static_cast<uint64_t>( size ) ) );
|
fc::raw::pack( s, htole64( static_cast<uint64_t>( size ) ) );
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream>
|
template<typename Stream>
|
||||||
//inline uint64_t unpack_compact_size( Stream& s )
|
inline uint64_t unpack_compact_size( Stream& s )
|
||||||
//{
|
{
|
||||||
// uint8_t size;
|
uint8_t size;
|
||||||
// uint64_t size_ret;
|
uint64_t size_ret;
|
||||||
//
|
|
||||||
// fc::raw::unpack( s, size );
|
fc::raw::unpack( s, size );
|
||||||
//
|
|
||||||
// if (size < 253) {
|
if (size < 253) {
|
||||||
// size_ret = size;
|
size_ret = size;
|
||||||
// } else if ( size == 253 ) {
|
} else if ( size == 253 ) {
|
||||||
// uint16_t tmp;
|
uint16_t tmp;
|
||||||
// fc::raw::unpack( s, tmp );
|
fc::raw::unpack( s, tmp );
|
||||||
// size_ret = le16toh( tmp );
|
size_ret = le16toh( tmp );
|
||||||
// if ( size_ret < 253 )
|
if ( size_ret < 253 )
|
||||||
// FC_THROW_EXCEPTION( fc::parse_error_exception, "non-canonical unpack_compact_size()" );
|
FC_THROW_EXCEPTION( fc::parse_error_exception, "non-canonical unpack_compact_size()" );
|
||||||
// } else if ( size == 254 ) {
|
} else if ( size == 254 ) {
|
||||||
// uint32_t tmp;
|
uint32_t tmp;
|
||||||
// fc::raw::unpack( s, tmp );
|
fc::raw::unpack( s, tmp );
|
||||||
// size_ret = le32toh( tmp );
|
size_ret = le32toh( tmp );
|
||||||
// if ( size_ret < 0x10000u )
|
if ( size_ret < 0x10000u )
|
||||||
// FC_THROW_EXCEPTION( fc::parse_error_exception, "non-canonical unpack_compact_size()" );
|
FC_THROW_EXCEPTION( fc::parse_error_exception, "non-canonical unpack_compact_size()" );
|
||||||
// } else {
|
} else {
|
||||||
// uint32_t tmp;
|
uint32_t tmp;
|
||||||
// fc::raw::unpack( s, tmp );
|
fc::raw::unpack( s, tmp );
|
||||||
// size_ret = le64toh( tmp );
|
size_ret = le64toh( tmp );
|
||||||
// if ( size_ret < 0x100000000ULL )
|
if ( size_ret < 0x100000000ULL )
|
||||||
// FC_THROW_EXCEPTION( fc::parse_error_exception, "non-canonical unpack_compact_size()" );
|
FC_THROW_EXCEPTION( fc::parse_error_exception, "non-canonical unpack_compact_size()" );
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// if ( size_ret > 0x08000000 )
|
if ( size_ret > 0x08000000 )
|
||||||
// FC_THROW_EXCEPTION( fc::parse_error_exception, "unpack_compact_size(): size too large" );
|
FC_THROW_EXCEPTION( fc::parse_error_exception, "unpack_compact_size(): size too large" );
|
||||||
//
|
|
||||||
// return size_ret;
|
return size_ret;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream>
|
template<typename Stream>
|
||||||
//inline void pack( Stream& s, const std::vector<char>& v )
|
inline void pack( Stream& s, const std::vector<char>& v )
|
||||||
//{
|
{
|
||||||
// pack_compact_size( s, v.size() );
|
pack_compact_size( s, v.size() );
|
||||||
// if ( !v.empty() )
|
if ( !v.empty() )
|
||||||
// s.write( v.data(), v.size() );
|
s.write( v.data(), v.size() );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream>
|
template<typename Stream>
|
||||||
//inline void unpack( Stream& s, std::vector<char>& v )
|
inline void unpack( Stream& s, std::vector<char>& v )
|
||||||
//{
|
{
|
||||||
// const auto size = unpack_compact_size( s );
|
const auto size = unpack_compact_size( s );
|
||||||
// v.resize( size );
|
v.resize( size );
|
||||||
// if ( size )
|
if ( size )
|
||||||
// s.read( v.data(), size );
|
s.read( v.data(), size );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
//inline void pack( Stream& s, const T& val )
|
inline void pack( Stream& s, const T& val )
|
||||||
//{
|
{
|
||||||
// fc::raw::pack( s, val );
|
fc::raw::pack( s, val );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
//inline void unpack( Stream& s, T& val )
|
inline void unpack( Stream& s, T& val )
|
||||||
//{
|
{
|
||||||
// fc::raw::unpack( s, val );
|
fc::raw::unpack( s, val );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream>
|
template<typename Stream>
|
||||||
//inline void pack( Stream& s, const out_point& op )
|
inline void pack( Stream& s, const out_point& op )
|
||||||
//{
|
{
|
||||||
// fc::sha256 reversed( op.hash );
|
fc::sha256 reversed( op.hash );
|
||||||
// std::reverse( reversed.data(), reversed.data() + reversed.data_size() );
|
std::reverse( reversed.data(), reversed.data() + reversed.data_size() );
|
||||||
// s.write( reversed.data(), reversed.data_size() );
|
s.write( reversed.data(), reversed.data_size() );
|
||||||
// pack( s, op.n );
|
pack( s, op.n );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream>
|
template<typename Stream>
|
||||||
//inline void unpack( Stream& s, out_point& op )
|
inline void unpack( Stream& s, out_point& op )
|
||||||
//{
|
{
|
||||||
// uint64_t hash_size = op.hash.data_size();
|
uint64_t hash_size = op.hash.data_size();
|
||||||
// std::unique_ptr<char[]> hash_data( new char[hash_size] );
|
std::unique_ptr<char[]> hash_data( new char[hash_size] );
|
||||||
// s.read( hash_data.get(), hash_size );
|
s.read( hash_data.get(), hash_size );
|
||||||
// std::reverse( hash_data.get(), hash_data.get() + hash_size );
|
std::reverse( hash_data.get(), hash_data.get() + hash_size );
|
||||||
//
|
|
||||||
// op.hash = fc::sha256( hash_data.get(), hash_size );
|
op.hash = fc::sha256( hash_data.get(), hash_size );
|
||||||
// unpack( s, op.n );
|
unpack( s, op.n );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream>
|
template<typename Stream>
|
||||||
//inline void pack( Stream& s, const tx_in& in )
|
inline void pack( Stream& s, const tx_in& in )
|
||||||
//{
|
{
|
||||||
// pack( s, in.prevout );
|
pack( s, in.prevout );
|
||||||
// pack( s, in.scriptSig );
|
pack( s, in.scriptSig );
|
||||||
// pack( s, in.nSequence );
|
pack( s, in.nSequence );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream>
|
template<typename Stream>
|
||||||
//inline void unpack( Stream& s, tx_in& in )
|
inline void unpack( Stream& s, tx_in& in )
|
||||||
//{
|
{
|
||||||
// unpack( s, in.prevout );
|
unpack( s, in.prevout );
|
||||||
// unpack( s, in.scriptSig );
|
unpack( s, in.scriptSig );
|
||||||
// unpack( s, in.nSequence );
|
unpack( s, in.nSequence );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream>
|
template<typename Stream>
|
||||||
//inline void pack( Stream& s, const tx_out& out )
|
inline void pack( Stream& s, const tx_out& out )
|
||||||
//{
|
{
|
||||||
// pack( s, out.value );
|
pack( s, out.value );
|
||||||
// pack( s, out.scriptPubKey );
|
pack( s, out.scriptPubKey );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream>
|
template<typename Stream>
|
||||||
//inline void unpack( Stream& s, tx_out& out )
|
inline void unpack( Stream& s, tx_out& out )
|
||||||
//{
|
{
|
||||||
// unpack( s, out.value );
|
unpack( s, out.value );
|
||||||
// unpack( s, out.scriptPubKey );
|
unpack( s, out.scriptPubKey );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream>
|
template<typename Stream>
|
||||||
//inline void pack( Stream& s, const bitcoin_transaction& tx, bool with_witness = true )
|
inline void pack( Stream& s, const bitcoin_transaction& tx, bool with_witness = true )
|
||||||
//{
|
{
|
||||||
// uint8_t flags = 0;
|
uint8_t flags = 0;
|
||||||
//
|
|
||||||
// if ( with_witness ) {
|
if ( with_witness ) {
|
||||||
// for ( const auto& in : tx.vin ) {
|
for ( const auto& in : tx.vin ) {
|
||||||
// if ( !in.scriptWitness.empty() ) {
|
if ( !in.scriptWitness.empty() ) {
|
||||||
// flags |= 1;
|
flags |= 1;
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// pack( s, tx.nVersion );
|
pack( s, tx.nVersion );
|
||||||
//
|
|
||||||
// if ( flags ) {
|
if ( flags ) {
|
||||||
// pack_compact_size( s, 0 );
|
pack_compact_size( s, 0 );
|
||||||
// pack( s, flags );
|
pack( s, flags );
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// pack_compact_size( s, tx.vin.size() );
|
pack_compact_size( s, tx.vin.size() );
|
||||||
// for ( const auto& in : tx.vin )
|
for ( const auto& in : tx.vin )
|
||||||
// pack( s, in );
|
pack( s, in );
|
||||||
//
|
|
||||||
// pack_compact_size( s, tx.vout.size() );
|
pack_compact_size( s, tx.vout.size() );
|
||||||
// for ( const auto& out : tx.vout )
|
for ( const auto& out : tx.vout )
|
||||||
// pack( s, out );
|
pack( s, out );
|
||||||
//
|
|
||||||
// if ( flags & 1 ) {
|
if ( flags & 1 ) {
|
||||||
// for ( const auto in : tx.vin ) {
|
for ( const auto in : tx.vin ) {
|
||||||
// pack_compact_size( s, in.scriptWitness.size() );
|
pack_compact_size( s, in.scriptWitness.size() );
|
||||||
// for ( const auto& sc : in.scriptWitness )
|
for ( const auto& sc : in.scriptWitness )
|
||||||
// pack( s, sc );
|
pack( s, sc );
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// pack( s, tx.nLockTime );
|
pack( s, tx.nLockTime );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream>
|
template<typename Stream>
|
||||||
//inline void unpack( Stream& s, bitcoin_transaction& tx )
|
inline void unpack( Stream& s, bitcoin_transaction& tx )
|
||||||
//{
|
{
|
||||||
// uint8_t flags = 0;
|
uint8_t flags = 0;
|
||||||
//
|
|
||||||
// unpack( s, tx.nVersion );
|
unpack( s, tx.nVersion );
|
||||||
//
|
|
||||||
// auto vin_size = unpack_compact_size( s );
|
auto vin_size = unpack_compact_size( s );
|
||||||
// if ( vin_size == 0 ) {
|
if ( vin_size == 0 ) {
|
||||||
// unpack( s, flags );
|
unpack( s, flags );
|
||||||
// vin_size = unpack_compact_size( s );
|
vin_size = unpack_compact_size( s );
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// tx.vin.reserve( vin_size );
|
tx.vin.reserve( vin_size );
|
||||||
// for ( size_t i = 0; i < vin_size; i++ ) {
|
for ( size_t i = 0; i < vin_size; i++ ) {
|
||||||
// tx_in in;
|
tx_in in;
|
||||||
// unpack( s, in );
|
unpack( s, in );
|
||||||
// tx.vin.push_back( in );
|
tx.vin.push_back( in );
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// const auto vout_size = unpack_compact_size( s );
|
const auto vout_size = unpack_compact_size( s );
|
||||||
// tx.vout.reserve( vout_size );
|
tx.vout.reserve( vout_size );
|
||||||
// for ( size_t i = 0; i < vout_size; i++ ) {
|
for ( size_t i = 0; i < vout_size; i++ ) {
|
||||||
// tx_out out;
|
tx_out out;
|
||||||
// unpack( s, out );
|
unpack( s, out );
|
||||||
// tx.vout.push_back( out );
|
tx.vout.push_back( out );
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// if ( flags & 1 ) {
|
if ( flags & 1 ) {
|
||||||
// for ( auto& in : tx.vin ) {
|
for ( auto& in : tx.vin ) {
|
||||||
// uint64_t stack_size = unpack_compact_size( s );
|
uint64_t stack_size = unpack_compact_size( s );
|
||||||
// in.scriptWitness.reserve( stack_size );
|
in.scriptWitness.reserve( stack_size );
|
||||||
// for ( uint64_t i = 0; i < stack_size; i++ ) {
|
for ( uint64_t i = 0; i < stack_size; i++ ) {
|
||||||
// std::vector<char> script;
|
std::vector<char> script;
|
||||||
// unpack( s, script );
|
unpack( s, script );
|
||||||
// in.scriptWitness.push_back( script );
|
in.scriptWitness.push_back( script );
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// unpack( s, tx.nLockTime );
|
unpack( s, tx.nLockTime );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//inline std::vector<char> pack( const bitcoin_transaction& v, bool with_witness = true )
|
inline std::vector<char> pack( const bitcoin_transaction& v, bool with_witness = true )
|
||||||
//{
|
{
|
||||||
// fc::datastream<size_t> ps;
|
fc::datastream<size_t> ps;
|
||||||
// pack( ps, v, with_witness );
|
pack( ps, v, with_witness );
|
||||||
// std::vector<char> vec( ps.tellp() );
|
std::vector<char> vec( ps.tellp() );
|
||||||
//
|
|
||||||
// if( !vec.empty() ) {
|
if( !vec.empty() ) {
|
||||||
// fc::datastream<char*> ds( vec.data(), size_t( vec.size() ) );
|
fc::datastream<char*> ds( vec.data(), size_t( vec.size() ) );
|
||||||
// pack( ds, v, with_witness );
|
pack( ds, v, with_witness );
|
||||||
// }
|
}
|
||||||
// return vec;
|
return vec;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//inline bitcoin_transaction unpack( const std::vector<char>& s )
|
inline bitcoin_transaction unpack( const std::vector<char>& s )
|
||||||
//{ try {
|
{ try {
|
||||||
// bitcoin_transaction tmp;
|
bitcoin_transaction tmp;
|
||||||
// if( !s.empty() ) {
|
if( !s.empty() ) {
|
||||||
// fc::datastream<const char*> ds( s.data(), size_t( s.size() ) );
|
fc::datastream<const char*> ds( s.data(), size_t( s.size() ) );
|
||||||
// unpack(ds, tmp);
|
unpack(ds, tmp);
|
||||||
// }
|
}
|
||||||
// return tmp;
|
return tmp;
|
||||||
//} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type","transaction" ) ) }
|
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type","transaction" ) ) }
|
||||||
//
|
|
||||||
//template<typename Stream>
|
template<typename Stream>
|
||||||
//inline void pack_tx_signature( Stream& s, const std::vector<char>& scriptPubKey, const bitcoin_transaction& tx, unsigned int in_index, int hash_type )
|
inline void pack_tx_signature( Stream& s, const std::vector<char>& scriptPubKey, const bitcoin_transaction& tx, unsigned int in_index, int hash_type )
|
||||||
//{
|
{
|
||||||
// pack( s, tx.nVersion );
|
pack( s, tx.nVersion );
|
||||||
//
|
|
||||||
// pack_compact_size( s, tx.vin.size() );
|
pack_compact_size( s, tx.vin.size() );
|
||||||
// for ( size_t i = 0; i < tx.vin.size(); i++ ) {
|
for ( size_t i = 0; i < tx.vin.size(); i++ ) {
|
||||||
// const auto& in = tx.vin[i];
|
const auto& in = tx.vin[i];
|
||||||
// pack( s, in.prevout );
|
pack( s, in.prevout );
|
||||||
// if ( i == in_index )
|
if ( i == in_index )
|
||||||
// pack( s, scriptPubKey );
|
pack( s, scriptPubKey );
|
||||||
// else
|
else
|
||||||
// pack_compact_size( s, 0 ); // Blank signature
|
pack_compact_size( s, 0 ); // Blank signature
|
||||||
// pack( s, in.nSequence );
|
pack( s, in.nSequence );
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// pack_compact_size( s, tx.vout.size() );
|
pack_compact_size( s, tx.vout.size() );
|
||||||
// for ( const auto& out : tx.vout )
|
for ( const auto& out : tx.vout )
|
||||||
// pack( s, out );
|
pack( s, out );
|
||||||
//
|
|
||||||
// pack( s, tx.nLockTime );
|
pack( s, tx.nLockTime );
|
||||||
// pack( s, hash_type );
|
pack( s, hash_type );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//template<typename Stream>
|
template<typename Stream>
|
||||||
//inline void pack_tx_witness_signature( Stream& s, const std::vector<char>& scriptCode, const bitcoin_transaction& tx, unsigned int in_index, int64_t amount, int hash_type )
|
inline void pack_tx_witness_signature( Stream& s, const std::vector<char>& scriptCode, const bitcoin_transaction& tx, unsigned int in_index, int64_t amount, int hash_type )
|
||||||
//{
|
{
|
||||||
//
|
|
||||||
// fc::sha256 hash_prevouts;
|
fc::sha256 hash_prevouts;
|
||||||
// fc::sha256 hash_sequence;
|
fc::sha256 hash_sequence;
|
||||||
// fc::sha256 hash_output;
|
fc::sha256 hash_output;
|
||||||
//
|
|
||||||
// {
|
{
|
||||||
// fc::datastream<size_t> ps;
|
fc::datastream<size_t> ps;
|
||||||
// for ( const auto in : tx.vin )
|
for ( const auto in : tx.vin )
|
||||||
// pack( ps, in.prevout );
|
pack( ps, in.prevout );
|
||||||
//
|
|
||||||
// std::vector<char> vec( ps.tellp() );
|
std::vector<char> vec( ps.tellp() );
|
||||||
// if ( vec.size() ) {
|
if ( vec.size() ) {
|
||||||
// fc::datastream<char*> ds( vec.data(), size_t( vec.size() ) );
|
fc::datastream<char*> ds( vec.data(), size_t( vec.size() ) );
|
||||||
// for ( const auto in : tx.vin )
|
for ( const auto in : tx.vin )
|
||||||
// pack( ds, in.prevout );
|
pack( ds, in.prevout );
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// hash_prevouts = fc::sha256::hash( fc::sha256::hash( vec.data(), vec.size() ) );
|
hash_prevouts = fc::sha256::hash( fc::sha256::hash( vec.data(), vec.size() ) );
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// {
|
{
|
||||||
// fc::datastream<size_t> ps;
|
fc::datastream<size_t> ps;
|
||||||
// for ( const auto in : tx.vin )
|
for ( const auto in : tx.vin )
|
||||||
// pack( ps, in.nSequence );
|
pack( ps, in.nSequence );
|
||||||
//
|
|
||||||
// std::vector<char> vec( ps.tellp() );
|
std::vector<char> vec( ps.tellp() );
|
||||||
// if ( vec.size() ) {
|
if ( vec.size() ) {
|
||||||
// fc::datastream<char*> ds( vec.data(), size_t( vec.size() ) );
|
fc::datastream<char*> ds( vec.data(), size_t( vec.size() ) );
|
||||||
// for ( const auto in : tx.vin )
|
for ( const auto in : tx.vin )
|
||||||
// pack( ds, in.nSequence );
|
pack( ds, in.nSequence );
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// hash_sequence = fc::sha256::hash( fc::sha256::hash( vec.data(), vec.size() ) );
|
hash_sequence = fc::sha256::hash( fc::sha256::hash( vec.data(), vec.size() ) );
|
||||||
// };
|
};
|
||||||
//
|
|
||||||
// {
|
{
|
||||||
// fc::datastream<size_t> ps;
|
fc::datastream<size_t> ps;
|
||||||
// for ( const auto out : tx.vout )
|
for ( const auto out : tx.vout )
|
||||||
// pack( ps, out );
|
pack( ps, out );
|
||||||
//
|
|
||||||
// std::vector<char> vec( ps.tellp() );
|
std::vector<char> vec( ps.tellp() );
|
||||||
// if ( vec.size() ) {
|
if ( vec.size() ) {
|
||||||
// fc::datastream<char*> ds( vec.data(), size_t( vec.size() ) );
|
fc::datastream<char*> ds( vec.data(), size_t( vec.size() ) );
|
||||||
// for ( const auto out : tx.vout )
|
for ( const auto out : tx.vout )
|
||||||
// pack( ds, out );
|
pack( ds, out );
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// hash_output = fc::sha256::hash( fc::sha256::hash( vec.data(), vec.size() ) );
|
hash_output = fc::sha256::hash( fc::sha256::hash( vec.data(), vec.size() ) );
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// pack( s, tx.nVersion );
|
pack( s, tx.nVersion );
|
||||||
// pack( s, hash_prevouts );
|
pack( s, hash_prevouts );
|
||||||
// pack( s, hash_sequence );
|
pack( s, hash_sequence );
|
||||||
//
|
|
||||||
// pack( s, tx.vin[in_index].prevout );
|
pack( s, tx.vin[in_index].prevout );
|
||||||
// pack( s, scriptCode );
|
pack( s, scriptCode );
|
||||||
// pack( s, amount );
|
pack( s, amount );
|
||||||
// pack( s, tx.vin[in_index].nSequence );
|
pack( s, tx.vin[in_index].nSequence );
|
||||||
//
|
|
||||||
// pack( s, hash_output );
|
pack( s, hash_output );
|
||||||
// pack( s, tx.nLockTime );
|
pack( s, tx.nLockTime );
|
||||||
// pack( s, hash_type );
|
pack( s, hash_type );
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//}
|
}
|
||||||
|
|
|
||||||
81
libraries/plugins/peerplays_sidechain/segwit_addr.cpp
Normal file
81
libraries/plugins/peerplays_sidechain/segwit_addr.cpp
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
/* Copyright (c) 2017 Pieter Wuille
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <graphene/peerplays_sidechain/segwit_addr.hpp>
|
||||||
|
#include <graphene/peerplays_sidechain/bech32.hpp>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef std::vector<uint8_t> data;
|
||||||
|
|
||||||
|
/** Convert from one power-of-2 number base to another. */
|
||||||
|
template<int frombits, int tobits, bool pad>
|
||||||
|
bool convertbits(data& out, const data& in) {
|
||||||
|
int acc = 0;
|
||||||
|
int bits = 0;
|
||||||
|
const int maxv = (1 << tobits) - 1;
|
||||||
|
const int max_acc = (1 << (frombits + tobits - 1)) - 1;
|
||||||
|
for (size_t i = 0; i < in.size(); ++i) {
|
||||||
|
int value = in[i];
|
||||||
|
acc = ((acc << frombits) | value) & max_acc;
|
||||||
|
bits += frombits;
|
||||||
|
while (bits >= tobits) {
|
||||||
|
bits -= tobits;
|
||||||
|
out.push_back((acc >> bits) & maxv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pad) {
|
||||||
|
if (bits) out.push_back((acc << (tobits - bits)) & maxv);
|
||||||
|
} else if (bits >= frombits || ((acc << (tobits - bits)) & maxv)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace sidechain { namespace segwit_addr {
|
||||||
|
|
||||||
|
/** Decode a SegWit address. */
|
||||||
|
std::pair<int, data> decode(const std::string& hrp, const std::string& addr) {
|
||||||
|
std::pair<std::string, data> dec = sidechain::bech32::Decode(addr);
|
||||||
|
if (dec.first != hrp || dec.second.size() < 1) return std::make_pair(-1, data());
|
||||||
|
data conv;
|
||||||
|
if (!convertbits<5, 8, false>(conv, data(dec.second.begin() + 1, dec.second.end())) ||
|
||||||
|
conv.size() < 2 || conv.size() > 40 || dec.second[0] > 16 || (dec.second[0] == 0 &&
|
||||||
|
conv.size() != 20 && conv.size() != 32)) {
|
||||||
|
return std::make_pair(-1, data());
|
||||||
|
}
|
||||||
|
return std::make_pair(dec.second[0], conv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Encode a SegWit address. */
|
||||||
|
std::string encode(const std::string& hrp, int witver, const data& witprog) {
|
||||||
|
data enc;
|
||||||
|
enc.push_back(witver);
|
||||||
|
convertbits<8, 5, true>(enc, witprog);
|
||||||
|
std::string ret = sidechain::bech32::Encode(hrp, enc);
|
||||||
|
if (decode(hrp, ret).first == -1) return "";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
} }
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#include <sidechain/network/zmq_listener.hpp>
|
#include <graphene/peerplays_sidechain/zmq_listener.hpp>
|
||||||
#include <boost/algorithm/hex.hpp>
|
#include <boost/algorithm/hex.hpp>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue