CLANG code format
This commit is contained in:
parent
2739b56b94
commit
b5a3ca8040
19 changed files with 1015 additions and 1098 deletions
53
libraries/plugins/peerplays_sidechain/bitcoin/bech32.cpp
Executable file → Normal file
53
libraries/plugins/peerplays_sidechain/bitcoin/bech32.cpp
Executable file → Normal file
|
|
@ -6,8 +6,7 @@
|
||||||
|
|
||||||
// #include <bech32.h>
|
// #include <bech32.h>
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
{
|
|
||||||
|
|
||||||
typedef std::vector<uint8_t> data;
|
typedef std::vector<uint8_t> data;
|
||||||
|
|
||||||
|
|
@ -23,12 +22,10 @@ const int8_t CHARSET_REV[128] = {
|
||||||
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
|
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
|
||||||
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
|
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
|
||||||
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
|
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
|
||||||
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
|
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1};
|
||||||
};
|
|
||||||
|
|
||||||
/** Concatenate two byte arrays. */
|
/** Concatenate two byte arrays. */
|
||||||
data Cat(data x, const data& y)
|
data Cat(data x, const data &y) {
|
||||||
{
|
|
||||||
x.insert(x.end(), y.begin(), y.end());
|
x.insert(x.end(), y.begin(), y.end());
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
@ -36,8 +33,7 @@ data Cat(data x, const data& y)
|
||||||
/** This function will compute what 6 5-bit values to XOR into the last 6 input values, in order to
|
/** This function will compute what 6 5-bit values to XOR into the last 6 input values, in order to
|
||||||
* make the checksum 0. These 6 values are packed together in a single 30-bit integer. The higher
|
* make the checksum 0. These 6 values are packed together in a single 30-bit integer. The higher
|
||||||
* bits correspond to earlier values. */
|
* bits correspond to earlier values. */
|
||||||
uint32_t PolyMod(const data& v)
|
uint32_t PolyMod(const data &v) {
|
||||||
{
|
|
||||||
// The input is interpreted as a list of coefficients of a polynomial over F = GF(32), with an
|
// The input is interpreted as a list of coefficients of a polynomial over F = GF(32), with an
|
||||||
// implicit 1 in front. If the input is [v0,v1,v2,v3,v4], that polynomial is v(x) =
|
// implicit 1 in front. If the input is [v0,v1,v2,v3,v4], that polynomial is v(x) =
|
||||||
// 1*x^5 + v0*x^4 + v1*x^3 + v2*x^2 + v3*x + v4. The implicit 1 guarantees that
|
// 1*x^5 + v0*x^4 + v1*x^3 + v2*x^2 + v3*x + v4. The implicit 1 guarantees that
|
||||||
|
|
@ -86,24 +82,27 @@ uint32_t PolyMod(const data& v)
|
||||||
c = ((c & 0x1ffffff) << 5) ^ v_i;
|
c = ((c & 0x1ffffff) << 5) ^ v_i;
|
||||||
|
|
||||||
// Finally, for each set bit n in c0, conditionally add {2^n}k(x):
|
// Finally, for each set bit n in c0, conditionally add {2^n}k(x):
|
||||||
if (c0 & 1) c ^= 0x3b6a57b2; // k(x) = {29}x^5 + {22}x^4 + {20}x^3 + {21}x^2 + {29}x + {18}
|
if (c0 & 1)
|
||||||
if (c0 & 2) c ^= 0x26508e6d; // {2}k(x) = {19}x^5 + {5}x^4 + x^3 + {3}x^2 + {19}x + {13}
|
c ^= 0x3b6a57b2; // k(x) = {29}x^5 + {22}x^4 + {20}x^3 + {21}x^2 + {29}x + {18}
|
||||||
if (c0 & 4) c ^= 0x1ea119fa; // {4}k(x) = {15}x^5 + {10}x^4 + {2}x^3 + {6}x^2 + {15}x + {26}
|
if (c0 & 2)
|
||||||
if (c0 & 8) c ^= 0x3d4233dd; // {8}k(x) = {30}x^5 + {20}x^4 + {4}x^3 + {12}x^2 + {30}x + {29}
|
c ^= 0x26508e6d; // {2}k(x) = {19}x^5 + {5}x^4 + x^3 + {3}x^2 + {19}x + {13}
|
||||||
if (c0 & 16) c ^= 0x2a1462b3; // {16}k(x) = {21}x^5 + x^4 + {8}x^3 + {24}x^2 + {21}x + {19}
|
if (c0 & 4)
|
||||||
|
c ^= 0x1ea119fa; // {4}k(x) = {15}x^5 + {10}x^4 + {2}x^3 + {6}x^2 + {15}x + {26}
|
||||||
|
if (c0 & 8)
|
||||||
|
c ^= 0x3d4233dd; // {8}k(x) = {30}x^5 + {20}x^4 + {4}x^3 + {12}x^2 + {30}x + {29}
|
||||||
|
if (c0 & 16)
|
||||||
|
c ^= 0x2a1462b3; // {16}k(x) = {21}x^5 + x^4 + {8}x^3 + {24}x^2 + {21}x + {19}
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Convert to lower case. */
|
/** Convert to lower case. */
|
||||||
inline unsigned char LowerCase(unsigned char c)
|
inline unsigned char LowerCase(unsigned char c) {
|
||||||
{
|
|
||||||
return (c >= 'A' && c <= 'Z') ? (c - 'A') + 'a' : c;
|
return (c >= 'A' && c <= 'Z') ? (c - 'A') + 'a' : c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Expand a HRP for use in checksum computation. */
|
/** Expand a HRP for use in checksum computation. */
|
||||||
data ExpandHRP(const std::string& hrp)
|
data ExpandHRP(const std::string &hrp) {
|
||||||
{
|
|
||||||
data ret;
|
data ret;
|
||||||
ret.reserve(hrp.size() + 90);
|
ret.reserve(hrp.size() + 90);
|
||||||
ret.resize(hrp.size() * 2 + 1);
|
ret.resize(hrp.size() * 2 + 1);
|
||||||
|
|
@ -117,8 +116,7 @@ data ExpandHRP(const std::string& hrp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Verify a checksum. */
|
/** Verify a checksum. */
|
||||||
bool VerifyChecksum(const std::string& hrp, const data& values)
|
bool VerifyChecksum(const std::string &hrp, const data &values) {
|
||||||
{
|
|
||||||
// PolyMod computes what value to xor into the final values to make the checksum 0. However,
|
// PolyMod computes what value to xor into the final values to make the checksum 0. However,
|
||||||
// if we required that the checksum was 0, it would be the case that appending a 0 to a valid
|
// if we required that the checksum was 0, it would be the case that appending a 0 to a valid
|
||||||
// list of values would result in a new valid list. For that reason, Bech32 requires the
|
// list of values would result in a new valid list. For that reason, Bech32 requires the
|
||||||
|
|
@ -127,8 +125,7 @@ bool VerifyChecksum(const std::string& hrp, const data& values)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a checksum. */
|
/** Create a checksum. */
|
||||||
data CreateChecksum(const std::string& hrp, const data& values)
|
data CreateChecksum(const std::string &hrp, const data &values) {
|
||||||
{
|
|
||||||
data enc = Cat(ExpandHRP(hrp), values);
|
data enc = Cat(ExpandHRP(hrp), values);
|
||||||
enc.resize(enc.size() + 6); // Append 6 zeroes
|
enc.resize(enc.size() + 6); // Append 6 zeroes
|
||||||
uint32_t mod = PolyMod(enc) ^ 1; // Determine what to XOR into those 6 zeroes.
|
uint32_t mod = PolyMod(enc) ^ 1; // Determine what to XOR into those 6 zeroes.
|
||||||
|
|
@ -161,11 +158,15 @@ std::pair<std::string, data> Decode(const std::string& str) {
|
||||||
bool lower = false, upper = false;
|
bool lower = false, upper = false;
|
||||||
for (size_t i = 0; i < str.size(); ++i) {
|
for (size_t i = 0; i < str.size(); ++i) {
|
||||||
unsigned char c = str[i];
|
unsigned char c = str[i];
|
||||||
if (c < 33 || c > 126) return {};
|
if (c < 33 || c > 126)
|
||||||
if (c >= 'a' && c <= 'z') lower = true;
|
return {};
|
||||||
if (c >= 'A' && c <= 'Z') upper = true;
|
if (c >= 'a' && c <= 'z')
|
||||||
|
lower = true;
|
||||||
|
if (c >= 'A' && c <= 'Z')
|
||||||
|
upper = true;
|
||||||
}
|
}
|
||||||
if (lower && upper) return {};
|
if (lower && upper)
|
||||||
|
return {};
|
||||||
size_t pos = str.rfind('1');
|
size_t pos = str.rfind('1');
|
||||||
if (str.size() > 90 || pos == str.npos || pos == 0 || pos + 7 > str.size()) {
|
if (str.size() > 90 || pos == str.npos || pos == 0 || pos + 7 > str.size()) {
|
||||||
return {};
|
return {};
|
||||||
|
|
@ -189,4 +190,4 @@ std::pair<std::string, data> Decode(const std::string& str) {
|
||||||
return {hrp, data(values.begin(), values.end() - 6)};
|
return {hrp, data(values.begin(), values.end() - 6)};
|
||||||
}
|
}
|
||||||
|
|
||||||
} } } }// namespace sidechain::bech32
|
}}}} // namespace graphene::peerplays_sidechain::bitcoin::bech32
|
||||||
|
|
|
||||||
100
libraries/plugins/peerplays_sidechain/bitcoin/bitcoin_address.cpp
Executable file → Normal file
100
libraries/plugins/peerplays_sidechain/bitcoin/bitcoin_address.cpp
Executable file → Normal file
|
|
@ -1,8 +1,8 @@
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_address.hpp>
|
|
||||||
#include <sstream>
|
|
||||||
#include <fc/crypto/base58.hpp>
|
#include <fc/crypto/base58.hpp>
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/segwit_addr.hpp>
|
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_address.hpp>
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_script.hpp>
|
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_script.hpp>
|
||||||
|
#include <graphene/peerplays_sidechain/bitcoin/segwit_addr.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
||||||
|
|
||||||
|
|
@ -13,8 +13,7 @@ bool bitcoin_address::operator==( const bitcoin_address& btc_addr ) const {
|
||||||
(this->network_type == btc_addr.network_type);
|
(this->network_type == btc_addr.network_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes bitcoin_address::get_script() const
|
bytes bitcoin_address::get_script() const {
|
||||||
{
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case payment_type::NULLDATA:
|
case payment_type::NULLDATA:
|
||||||
return script_builder() << op::RETURN << raw_address;
|
return script_builder() << op::RETURN << raw_address;
|
||||||
|
|
@ -34,8 +33,7 @@ bytes bitcoin_address::get_script() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
payment_type bitcoin_address::determine_type()
|
payment_type bitcoin_address::determine_type() {
|
||||||
{
|
|
||||||
if (is_p2pk()) {
|
if (is_p2pk()) {
|
||||||
return payment_type::P2PK;
|
return payment_type::P2PK;
|
||||||
} else if (is_p2wpkh()) {
|
} else if (is_p2wpkh()) {
|
||||||
|
|
@ -51,8 +49,7 @@ payment_type bitcoin_address::determine_type()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes bitcoin_address::determine_raw_address()
|
bytes bitcoin_address::determine_raw_address() {
|
||||||
{
|
|
||||||
bytes result;
|
bytes result;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case payment_type::P2PK: {
|
case payment_type::P2PK: {
|
||||||
|
|
@ -61,8 +58,7 @@ bytes bitcoin_address::determine_raw_address()
|
||||||
}
|
}
|
||||||
case payment_type::P2WPKH:
|
case payment_type::P2WPKH:
|
||||||
case payment_type::P2WSH: {
|
case payment_type::P2WSH: {
|
||||||
std::string prefix( address.compare(0,4,"bcrt") == 0 ? std::string( address.begin(), address.begin() + 4 ) :
|
std::string prefix(address.compare(0, 4, "bcrt") == 0 ? std::string(address.begin(), address.begin() + 4) : std::string(address.begin(), address.begin() + 2));
|
||||||
std::string( address.begin(), address.begin() + 2 ) );
|
|
||||||
const auto &decode_bech32 = segwit_addr::decode(prefix, address);
|
const auto &decode_bech32 = segwit_addr::decode(prefix, address);
|
||||||
result = bytes(decode_bech32.second.begin(), decode_bech32.second.end());
|
result = bytes(decode_bech32.second.begin(), decode_bech32.second.end());
|
||||||
break;
|
break;
|
||||||
|
|
@ -75,15 +71,15 @@ bytes bitcoin_address::determine_raw_address()
|
||||||
result = bytes(hex_addr.begin() + 1, hex_addr.begin() + 21);
|
result = bytes(hex_addr.begin() + 1, hex_addr.begin() + 21);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case payment_type::NULLDATA : return result;
|
case payment_type::NULLDATA:
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bitcoin_address::check_segwit_address(const size_segwit_address &size) const {
|
bool bitcoin_address::check_segwit_address(const size_segwit_address &size) const {
|
||||||
if (!address.compare(0, 4, "bcrt") || !address.compare(0, 2, "bc") || !address.compare(0, 2, "tb")) {
|
if (!address.compare(0, 4, "bcrt") || !address.compare(0, 2, "bc") || !address.compare(0, 2, "tb")) {
|
||||||
std::string prefix( !address.compare(0,4,"bcrt") ? std::string(address.begin(), address.begin() + 4) :
|
std::string prefix(!address.compare(0, 4, "bcrt") ? std::string(address.begin(), address.begin() + 4) : std::string(address.begin(), address.begin() + 2));
|
||||||
std::string(address.begin(), address.begin() + 2) );
|
|
||||||
|
|
||||||
const auto &decode_bech32 = segwit_addr::decode(prefix, address);
|
const auto &decode_bech32 = segwit_addr::decode(prefix, address);
|
||||||
|
|
||||||
|
|
@ -96,8 +92,7 @@ bool bitcoin_address::check_segwit_address( const size_segwit_address& size ) co
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bitcoin_address::is_p2pk() const
|
bool bitcoin_address::is_p2pk() const {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
bool prefix = !address.compare(0, 2, "02") || !address.compare(0, 2, "03");
|
bool prefix = !address.compare(0, 2, "02") || !address.compare(0, 2, "03");
|
||||||
if (address.size() == 66 && prefix) {
|
if (address.size() == 66 && prefix) {
|
||||||
|
|
@ -110,18 +105,15 @@ bool bitcoin_address::is_p2pk() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bitcoin_address::is_p2wpkh() const
|
bool bitcoin_address::is_p2wpkh() const {
|
||||||
{
|
|
||||||
return check_segwit_address(size_segwit_address::P2WPKH);
|
return check_segwit_address(size_segwit_address::P2WPKH);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bitcoin_address::is_p2wsh() const
|
bool bitcoin_address::is_p2wsh() const {
|
||||||
{
|
|
||||||
return check_segwit_address(size_segwit_address::P2WSH);
|
return check_segwit_address(size_segwit_address::P2WSH);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bitcoin_address::is_p2pkh() const
|
bool bitcoin_address::is_p2pkh() const {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
bytes hex_addr = fc::from_base58(address);
|
bytes hex_addr = fc::from_base58(address);
|
||||||
if (hex_addr.size() == 25 && (static_cast<unsigned char>(hex_addr[0]) == 0x00 ||
|
if (hex_addr.size() == 25 && (static_cast<unsigned char>(hex_addr[0]) == 0x00 ||
|
||||||
|
|
@ -134,8 +126,7 @@ bool bitcoin_address::is_p2pkh() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bitcoin_address::is_p2sh() const
|
bool bitcoin_address::is_p2sh() const {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
bytes hex_addr = fc::from_base58(address);
|
bytes hex_addr = fc::from_base58(address);
|
||||||
if (hex_addr.size() == 25 && (static_cast<unsigned char>(hex_addr[0]) == 0x05 ||
|
if (hex_addr.size() == 25 && (static_cast<unsigned char>(hex_addr[0]) == 0x05 ||
|
||||||
|
|
@ -149,29 +140,28 @@ bool bitcoin_address::is_p2sh() const
|
||||||
}
|
}
|
||||||
|
|
||||||
btc_multisig_address::btc_multisig_address(const size_t n_required, const accounts_keys &keys) :
|
btc_multisig_address::btc_multisig_address(const size_t n_required, const accounts_keys &keys) :
|
||||||
keys_required ( n_required ), witnesses_keys( keys )
|
keys_required(n_required),
|
||||||
{
|
witnesses_keys(keys) {
|
||||||
create_redeem_script();
|
create_redeem_script();
|
||||||
create_address();
|
create_address();
|
||||||
type = payment_type::P2SH;
|
type = payment_type::P2SH;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t btc_multisig_address::count_intersection( const accounts_keys& keys ) const
|
size_t btc_multisig_address::count_intersection(const accounts_keys &keys) const {
|
||||||
{
|
|
||||||
FC_ASSERT(keys.size() > 0);
|
FC_ASSERT(keys.size() > 0);
|
||||||
|
|
||||||
int intersections_count = 0;
|
int intersections_count = 0;
|
||||||
for (auto &key : keys) {
|
for (auto &key : keys) {
|
||||||
auto witness_key = witnesses_keys.find(key.first);
|
auto witness_key = witnesses_keys.find(key.first);
|
||||||
if( witness_key == witnesses_keys.end() ) continue;
|
if (witness_key == witnesses_keys.end())
|
||||||
|
continue;
|
||||||
if (key.second == witness_key->second)
|
if (key.second == witness_key->second)
|
||||||
intersections_count++;
|
intersections_count++;
|
||||||
}
|
}
|
||||||
return intersections_count;
|
return intersections_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void btc_multisig_address::create_redeem_script()
|
void btc_multisig_address::create_redeem_script() {
|
||||||
{
|
|
||||||
FC_ASSERT(keys_required > 0);
|
FC_ASSERT(keys_required > 0);
|
||||||
FC_ASSERT(keys_required < witnesses_keys.size());
|
FC_ASSERT(keys_required < witnesses_keys.size());
|
||||||
redeem_script.clear();
|
redeem_script.clear();
|
||||||
|
|
@ -187,8 +177,7 @@ void btc_multisig_address::create_redeem_script()
|
||||||
redeem_script.push_back(OP_CHECKMULTISIG);
|
redeem_script.push_back(OP_CHECKMULTISIG);
|
||||||
}
|
}
|
||||||
|
|
||||||
void btc_multisig_address::create_address()
|
void btc_multisig_address::create_address() {
|
||||||
{
|
|
||||||
FC_ASSERT(redeem_script.size() > 0);
|
FC_ASSERT(redeem_script.size() > 0);
|
||||||
raw_address.clear();
|
raw_address.clear();
|
||||||
fc::sha256 hash256 = fc::sha256::hash(redeem_script.data(), redeem_script.size());
|
fc::sha256 hash256 = fc::sha256::hash(redeem_script.data(), redeem_script.size());
|
||||||
|
|
@ -205,15 +194,13 @@ void btc_multisig_address::create_address()
|
||||||
}
|
}
|
||||||
|
|
||||||
btc_multisig_segwit_address::btc_multisig_segwit_address(const size_t n_required, const accounts_keys &keys) :
|
btc_multisig_segwit_address::btc_multisig_segwit_address(const size_t n_required, const accounts_keys &keys) :
|
||||||
btc_multisig_address( n_required, keys )
|
btc_multisig_address(n_required, keys) {
|
||||||
{
|
|
||||||
create_witness_script();
|
create_witness_script();
|
||||||
create_segwit_address();
|
create_segwit_address();
|
||||||
type = payment_type::P2SH;
|
type = payment_type::P2SH;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool btc_multisig_segwit_address::operator==( const btc_multisig_segwit_address& addr ) const
|
bool btc_multisig_segwit_address::operator==(const btc_multisig_segwit_address &addr) const {
|
||||||
{
|
|
||||||
if (address != addr.address || redeem_script != addr.redeem_script ||
|
if (address != addr.address || redeem_script != addr.redeem_script ||
|
||||||
witnesses_keys != addr.witnesses_keys || witness_script != addr.witness_script ||
|
witnesses_keys != addr.witnesses_keys || witness_script != addr.witness_script ||
|
||||||
raw_address != addr.raw_address)
|
raw_address != addr.raw_address)
|
||||||
|
|
@ -229,16 +216,14 @@ std::vector<public_key_type> btc_multisig_segwit_address::get_keys() {
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
void btc_multisig_segwit_address::create_witness_script()
|
void btc_multisig_segwit_address::create_witness_script() {
|
||||||
{
|
|
||||||
const auto redeem_sha256 = fc::sha256::hash(redeem_script.data(), redeem_script.size());
|
const auto redeem_sha256 = fc::sha256::hash(redeem_script.data(), redeem_script.size());
|
||||||
witness_script.push_back(OP_0);
|
witness_script.push_back(OP_0);
|
||||||
witness_script.push_back(0x20); // PUSH_32
|
witness_script.push_back(0x20); // PUSH_32
|
||||||
witness_script.insert(witness_script.end(), redeem_sha256.data(), redeem_sha256.data() + redeem_sha256.data_size());
|
witness_script.insert(witness_script.end(), redeem_sha256.data(), redeem_sha256.data() + redeem_sha256.data_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void btc_multisig_segwit_address::create_segwit_address()
|
void btc_multisig_segwit_address::create_segwit_address() {
|
||||||
{
|
|
||||||
fc::sha256 hash256 = fc::sha256::hash(witness_script.data(), witness_script.size());
|
fc::sha256 hash256 = fc::sha256::hash(witness_script.data(), witness_script.size());
|
||||||
fc::ripemd160 hash160 = fc::ripemd160::hash(hash256.data(), hash256.data_size());
|
fc::ripemd160 hash160 = fc::ripemd160::hash(hash256.data(), hash256.data_size());
|
||||||
|
|
||||||
|
|
@ -246,8 +231,7 @@ void btc_multisig_segwit_address::create_segwit_address()
|
||||||
address = fc::to_base58(get_address_bytes(raw_address));
|
address = fc::to_base58(get_address_bytes(raw_address));
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes btc_multisig_segwit_address::get_address_bytes( const bytes& script_hash )
|
bytes btc_multisig_segwit_address::get_address_bytes(const bytes &script_hash) {
|
||||||
{
|
|
||||||
bytes address_bytes(1, TESTNET_SCRIPT); // 1 byte version
|
bytes address_bytes(1, TESTNET_SCRIPT); // 1 byte version
|
||||||
address_bytes.insert(address_bytes.end(), script_hash.begin(), script_hash.end());
|
address_bytes.insert(address_bytes.end(), script_hash.begin(), script_hash.end());
|
||||||
fc::sha256 hash256 = fc::sha256::hash(fc::sha256::hash(address_bytes.data(), address_bytes.size()));
|
fc::sha256 hash256 = fc::sha256::hash(fc::sha256::hash(address_bytes.data(), address_bytes.size()));
|
||||||
|
|
@ -256,10 +240,8 @@ bytes btc_multisig_segwit_address::get_address_bytes( const bytes& script_hash )
|
||||||
return address_bytes;
|
return address_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
btc_weighted_multisig_address::btc_weighted_multisig_address(const std::vector<std::pair<fc::ecc::public_key, uint16_t>> &keys_data,
|
btc_weighted_multisig_address::btc_weighted_multisig_address(const std::vector<std::pair<fc::ecc::public_key, uint16_t>> &keys_data,
|
||||||
network ntype)
|
network ntype) {
|
||||||
{
|
|
||||||
network_type = ntype;
|
network_type = ntype;
|
||||||
create_redeem_script(keys_data);
|
create_redeem_script(keys_data);
|
||||||
create_witness_script();
|
create_witness_script();
|
||||||
|
|
@ -267,8 +249,7 @@ btc_weighted_multisig_address::btc_weighted_multisig_address(const std::vector<s
|
||||||
type = payment_type::P2WSH;
|
type = payment_type::P2WSH;
|
||||||
}
|
}
|
||||||
|
|
||||||
void btc_weighted_multisig_address::create_redeem_script(const std::vector<std::pair<fc::ecc::public_key, uint16_t>>& keys_data)
|
void btc_weighted_multisig_address::create_redeem_script(const std::vector<std::pair<fc::ecc::public_key, uint16_t>> &keys_data) {
|
||||||
{
|
|
||||||
script_builder builder;
|
script_builder builder;
|
||||||
uint32_t total_weight = 0;
|
uint32_t total_weight = 0;
|
||||||
builder << uint32_t(0);
|
builder << uint32_t(0);
|
||||||
|
|
@ -292,8 +273,7 @@ void btc_weighted_multisig_address::create_redeem_script(const std::vector<std::
|
||||||
raw_address = bytes(sh.data(), sh.data() + sh.data_size());
|
raw_address = bytes(sh.data(), sh.data() + sh.data_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void btc_weighted_multisig_address::create_witness_script()
|
void btc_weighted_multisig_address::create_witness_script() {
|
||||||
{
|
|
||||||
script_builder builder;
|
script_builder builder;
|
||||||
builder << op::_0;
|
builder << op::_0;
|
||||||
builder << fc::sha256::hash(redeem_script_.data(), redeem_script_.size());
|
builder << fc::sha256::hash(redeem_script_.data(), redeem_script_.size());
|
||||||
|
|
@ -301,11 +281,9 @@ void btc_weighted_multisig_address::create_witness_script()
|
||||||
witness_script_ = builder;
|
witness_script_ = builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
void btc_weighted_multisig_address::create_segwit_address()
|
void btc_weighted_multisig_address::create_segwit_address() {
|
||||||
{
|
|
||||||
std::string hrp;
|
std::string hrp;
|
||||||
switch(network_type)
|
switch (network_type) {
|
||||||
{
|
|
||||||
case (network::mainnet):
|
case (network::mainnet):
|
||||||
hrp = "bc";
|
hrp = "bc";
|
||||||
break;
|
break;
|
||||||
|
|
@ -374,8 +352,7 @@ void btc_one_or_m_of_n_multisig_address::create_segwit_address() {
|
||||||
|
|
||||||
btc_one_or_weighted_multisig_address::btc_one_or_weighted_multisig_address(const fc::ecc::public_key &user_key_data,
|
btc_one_or_weighted_multisig_address::btc_one_or_weighted_multisig_address(const fc::ecc::public_key &user_key_data,
|
||||||
const std::vector<std::pair<fc::ecc::public_key, uint16_t>> &keys_data,
|
const std::vector<std::pair<fc::ecc::public_key, uint16_t>> &keys_data,
|
||||||
bitcoin_address::network ntype)
|
bitcoin_address::network ntype) {
|
||||||
{
|
|
||||||
network_type = ntype;
|
network_type = ntype;
|
||||||
create_redeem_script(user_key_data, keys_data);
|
create_redeem_script(user_key_data, keys_data);
|
||||||
create_witness_script();
|
create_witness_script();
|
||||||
|
|
@ -383,8 +360,7 @@ btc_one_or_weighted_multisig_address::btc_one_or_weighted_multisig_address(const
|
||||||
type = payment_type::P2WSH;
|
type = payment_type::P2WSH;
|
||||||
}
|
}
|
||||||
|
|
||||||
void btc_one_or_weighted_multisig_address::create_redeem_script(const fc::ecc::public_key &user_key_data, const std::vector<std::pair<fc::ecc::public_key, uint16_t> > &keys_data)
|
void btc_one_or_weighted_multisig_address::create_redeem_script(const fc::ecc::public_key &user_key_data, const std::vector<std::pair<fc::ecc::public_key, uint16_t>> &keys_data) {
|
||||||
{
|
|
||||||
script_builder builder;
|
script_builder builder;
|
||||||
builder << user_key_data.serialize();
|
builder << user_key_data.serialize();
|
||||||
builder << op::CHECKSIG;
|
builder << op::CHECKSIG;
|
||||||
|
|
@ -412,16 +388,14 @@ void btc_one_or_weighted_multisig_address::create_redeem_script(const fc::ecc::p
|
||||||
raw_address = bytes(sh.data(), sh.data() + sh.data_size());
|
raw_address = bytes(sh.data(), sh.data() + sh.data_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void btc_one_or_weighted_multisig_address::create_witness_script()
|
void btc_one_or_weighted_multisig_address::create_witness_script() {
|
||||||
{
|
|
||||||
script_builder builder;
|
script_builder builder;
|
||||||
builder << op::_0;
|
builder << op::_0;
|
||||||
builder << fc::sha256::hash(redeem_script_.data(), redeem_script_.size());
|
builder << fc::sha256::hash(redeem_script_.data(), redeem_script_.size());
|
||||||
witness_script_ = builder;
|
witness_script_ = builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
void btc_one_or_weighted_multisig_address::create_segwit_address()
|
void btc_one_or_weighted_multisig_address::create_segwit_address() {
|
||||||
{
|
|
||||||
std::string hrp;
|
std::string hrp;
|
||||||
switch (network_type) {
|
switch (network_type) {
|
||||||
case (network::mainnet):
|
case (network::mainnet):
|
||||||
|
|
@ -439,4 +413,4 @@ void btc_one_or_weighted_multisig_address::create_segwit_address()
|
||||||
address = segwit_addr::encode(hrp, 0, hash_data);
|
address = segwit_addr::encode(hrp, 0, hash_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
} } }
|
}}} // namespace graphene::peerplays_sidechain::bitcoin
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
||||||
|
|
||||||
script_builder& script_builder::operator<<( op opcode )
|
script_builder &script_builder::operator<<(op opcode) {
|
||||||
{
|
|
||||||
const auto op_byte = static_cast<uint8_t>(opcode);
|
const auto op_byte = static_cast<uint8_t>(opcode);
|
||||||
if (op_byte < 0 || op_byte > 0xff)
|
if (op_byte < 0 || op_byte > 0xff)
|
||||||
throw std::runtime_error("script_builder::operator<<(OP): invalid opcode");
|
throw std::runtime_error("script_builder::operator<<(OP): invalid opcode");
|
||||||
|
|
@ -12,8 +11,7 @@ script_builder& script_builder::operator<<( op opcode )
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
script_builder& script_builder::operator<<( uint32_t number )
|
script_builder &script_builder::operator<<(uint32_t number) {
|
||||||
{
|
|
||||||
if (number == 0) {
|
if (number == 0) {
|
||||||
script.push_back(static_cast<uint8_t>(op::_0));
|
script.push_back(static_cast<uint8_t>(op::_0));
|
||||||
} else if (number <= 16) {
|
} else if (number <= 16) {
|
||||||
|
|
@ -35,8 +33,7 @@ script_builder& script_builder::operator<<( uint32_t number )
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
script_builder& script_builder::operator<<( size_t size )
|
script_builder &script_builder::operator<<(size_t size) {
|
||||||
{
|
|
||||||
write_compact_size(script, size);
|
write_compact_size(script, size);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -47,25 +44,22 @@ script_builder& script_builder::operator<<( const bytes& sc ) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
script_builder& script_builder::operator<<( const fc::sha256& hash )
|
script_builder &script_builder::operator<<(const fc::sha256 &hash) {
|
||||||
{
|
|
||||||
write_compact_size(script, hash.data_size());
|
write_compact_size(script, hash.data_size());
|
||||||
script.insert(script.end(), hash.data(), hash.data() + hash.data_size());
|
script.insert(script.end(), hash.data(), hash.data() + hash.data_size());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
script_builder& script_builder::operator<<( const fc::ripemd160& hash )
|
script_builder &script_builder::operator<<(const fc::ripemd160 &hash) {
|
||||||
{
|
|
||||||
write_compact_size(script, hash.data_size());
|
write_compact_size(script, hash.data_size());
|
||||||
script.insert(script.end(), hash.data(), hash.data() + hash.data_size());
|
script.insert(script.end(), hash.data(), hash.data() + hash.data_size());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
script_builder& script_builder::operator<<( const fc::ecc::public_key_data& pubkey_data )
|
script_builder &script_builder::operator<<(const fc::ecc::public_key_data &pubkey_data) {
|
||||||
{
|
|
||||||
write_compact_size(script, pubkey_data.size());
|
write_compact_size(script, pubkey_data.size());
|
||||||
script.insert(script.end(), pubkey_data.begin(), pubkey_data.begin() + pubkey_data.size());
|
script.insert(script.end(), pubkey_data.begin(), pubkey_data.begin() + pubkey_data.size());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
} } }
|
}}} // namespace graphene::peerplays_sidechain::bitcoin
|
||||||
|
|
|
||||||
|
|
@ -1,59 +1,50 @@
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_transaction.hpp>
|
|
||||||
#include <fc/crypto/base58.hpp>
|
#include <fc/crypto/base58.hpp>
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_script.hpp>
|
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_script.hpp>
|
||||||
|
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_transaction.hpp>
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/serialize.hpp>
|
#include <graphene/peerplays_sidechain/bitcoin/serialize.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
||||||
|
|
||||||
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;
|
||||||
|
|
@ -61,8 +52,7 @@ bool tx_out::is_p2pkh() const
|
||||||
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;
|
||||||
|
|
@ -70,16 +60,14 @@ bool tx_out::is_p2sh() const
|
||||||
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()) {
|
||||||
|
|
@ -92,36 +80,31 @@ bytes tx_out::get_data_or_script() const
|
||||||
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;
|
||||||
|
|
@ -136,18 +119,15 @@ size_t bitcoin_transaction::get_vsize() const
|
||||||
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;
|
||||||
|
|
@ -159,8 +139,7 @@ void bitcoin_transaction_builder::add_in( payment_type type, const fc::sha256& t
|
||||||
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:
|
||||||
|
|
@ -183,15 +162,13 @@ void bitcoin_transaction_builder::add_in( payment_type type, tx_in txin, const b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
|
@ -204,8 +181,7 @@ void bitcoin_transaction_builder::add_out( payment_type type, int64_t amount, co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
@ -217,8 +193,7 @@ void bitcoin_transaction_builder::add_out( payment_type type, int64_t amount, co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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());
|
||||||
|
|
@ -244,8 +219,7 @@ void bitcoin_transaction_builder::add_out_all_type( const uint64_t& amount, cons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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:
|
||||||
|
|
@ -257,8 +231,7 @@ inline bool bitcoin_transaction_builder::is_payment_to_pubkey( payment_type type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
@ -278,4 +251,4 @@ bytes bitcoin_transaction_builder::get_script_pubkey( payment_type type, const b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} } }
|
}}} // namespace graphene::peerplays_sidechain::bitcoin
|
||||||
|
|
|
||||||
21
libraries/plugins/peerplays_sidechain/bitcoin/segwit_addr.cpp
Executable file → Normal file
21
libraries/plugins/peerplays_sidechain/bitcoin/segwit_addr.cpp
Executable file → Normal file
|
|
@ -19,11 +19,10 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/segwit_addr.hpp>
|
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/bech32.hpp>
|
#include <graphene/peerplays_sidechain/bitcoin/bech32.hpp>
|
||||||
|
#include <graphene/peerplays_sidechain/bitcoin/segwit_addr.hpp>
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
{
|
|
||||||
|
|
||||||
typedef std::vector<uint8_t> data;
|
typedef std::vector<uint8_t> data;
|
||||||
|
|
||||||
|
|
@ -44,25 +43,26 @@ bool convertbits(data& out, const data& in) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pad) {
|
if (pad) {
|
||||||
if (bits) out.push_back((acc << (tobits - bits)) & maxv);
|
if (bits)
|
||||||
|
out.push_back((acc << (tobits - bits)) & maxv);
|
||||||
} else if (bits >= frombits || ((acc << (tobits - bits)) & maxv)) {
|
} else if (bits >= frombits || ((acc << (tobits - bits)) & maxv)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain { namespace bitcoin { namespace segwit_addr {
|
namespace graphene { namespace peerplays_sidechain { namespace bitcoin { namespace segwit_addr {
|
||||||
|
|
||||||
/** Decode a SegWit address. */
|
/** Decode a SegWit address. */
|
||||||
std::pair<int, data> decode(const std::string &hrp, const std::string &addr) {
|
std::pair<int, data> decode(const std::string &hrp, const std::string &addr) {
|
||||||
std::pair<std::string, data> dec = bech32::Decode(addr);
|
std::pair<std::string, data> dec = bech32::Decode(addr);
|
||||||
if (dec.first != hrp || dec.second.size() < 1) return std::make_pair(-1, data());
|
if (dec.first != hrp || dec.second.size() < 1)
|
||||||
|
return std::make_pair(-1, data());
|
||||||
data conv;
|
data conv;
|
||||||
if (!convertbits<5, 8, false>(conv, data(dec.second.begin() + 1, dec.second.end())) ||
|
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() < 2 || conv.size() > 40 || dec.second[0] > 16 || (dec.second[0] == 0 && conv.size() != 20 && conv.size() != 32)) {
|
||||||
conv.size() != 20 && conv.size() != 32)) {
|
|
||||||
return std::make_pair(-1, data());
|
return std::make_pair(-1, data());
|
||||||
}
|
}
|
||||||
return std::make_pair(dec.second[0], conv);
|
return std::make_pair(dec.second[0], conv);
|
||||||
|
|
@ -74,8 +74,9 @@ std::string encode(const std::string& hrp, int witver, const data& witprog) {
|
||||||
enc.push_back(witver);
|
enc.push_back(witver);
|
||||||
convertbits<8, 5, true>(enc, witprog);
|
convertbits<8, 5, true>(enc, witprog);
|
||||||
std::string ret = bech32::Encode(hrp, enc);
|
std::string ret = bech32::Encode(hrp, enc);
|
||||||
if (decode(hrp, ret).first == -1) return "";
|
if (decode(hrp, ret).first == -1)
|
||||||
|
return "";
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
} } } }
|
}}}} // namespace graphene::peerplays_sidechain::bitcoin::segwit_addr
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,15 @@
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.hpp>
|
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/serialize.hpp>
|
#include <graphene/peerplays_sidechain/bitcoin/serialize.hpp>
|
||||||
|
#include <graphene/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
||||||
|
|
||||||
const secp256k1_context_t *btc_context()
|
const secp256k1_context_t *btc_context() {
|
||||||
{
|
|
||||||
static secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN);
|
static secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
fc::sha256 get_signature_hash(const bitcoin_transaction &tx, const bytes &scriptCode, int64_t amount,
|
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 )
|
size_t in_index, int hash_type, bool is_witness) {
|
||||||
{
|
|
||||||
fc::datastream<size_t> ps;
|
fc::datastream<size_t> ps;
|
||||||
if (is_witness)
|
if (is_witness)
|
||||||
pack_tx_witness_signature(ps, scriptCode, tx, in_index, amount, hash_type);
|
pack_tx_witness_signature(ps, scriptCode, tx, in_index, amount, hash_type);
|
||||||
|
|
@ -30,8 +28,7 @@ fc::sha256 get_signature_hash( const bitcoin_transaction& tx, const bytes& scrip
|
||||||
return fc::sha256::hash(fc::sha256::hash(vec.data(), vec.size()));
|
return fc::sha256::hash(fc::sha256::hash(vec.data(), vec.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<char> privkey_sign( const bytes& privkey, const fc::sha256 &hash, const secp256k1_context_t* context_sign )
|
std::vector<char> privkey_sign(const bytes &privkey, const fc::sha256 &hash, const secp256k1_context_t *context_sign) {
|
||||||
{
|
|
||||||
bytes sig;
|
bytes sig;
|
||||||
sig.resize(72);
|
sig.resize(72);
|
||||||
int sig_len = sig.size();
|
int sig_len = sig.size();
|
||||||
|
|
@ -52,8 +49,7 @@ std::vector<char> privkey_sign( const bytes& privkey, const fc::sha256 &hash, co
|
||||||
|
|
||||||
std::vector<bytes> sign_witness_transaction_part(const bitcoin_transaction &tx, const std::vector<bytes> &redeem_scripts,
|
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 std::vector<uint64_t> &amounts, const bytes &privkey,
|
||||||
const secp256k1_context_t* context_sign, int hash_type )
|
const secp256k1_context_t *context_sign, int hash_type) {
|
||||||
{
|
|
||||||
FC_ASSERT(tx.vin.size() == redeem_scripts.size() && tx.vin.size() == amounts.size());
|
FC_ASSERT(tx.vin.size() == redeem_scripts.size() && tx.vin.size() == amounts.size());
|
||||||
FC_ASSERT(!privkey.empty());
|
FC_ASSERT(!privkey.empty());
|
||||||
|
|
||||||
|
|
@ -68,8 +64,7 @@ std::vector<bytes> sign_witness_transaction_part( const bitcoin_transaction& tx,
|
||||||
return signatures;
|
return signatures;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sign_witness_transaction_finalize( bitcoin_transaction& tx, const std::vector<bytes>& redeem_scripts, bool use_mulisig_workaround )
|
void sign_witness_transaction_finalize(bitcoin_transaction &tx, const std::vector<bytes> &redeem_scripts, bool use_mulisig_workaround) {
|
||||||
{
|
|
||||||
FC_ASSERT(tx.vin.size() == redeem_scripts.size());
|
FC_ASSERT(tx.vin.size() == redeem_scripts.size());
|
||||||
|
|
||||||
for (size_t i = 0; i < tx.vin.size(); i++) {
|
for (size_t i = 0; i < tx.vin.size(); i++) {
|
||||||
|
|
@ -79,8 +74,7 @@ void sign_witness_transaction_finalize( bitcoin_transaction& tx, const std::vect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool verify_sig( const bytes& sig, const bytes& pubkey, const bytes& msg, const secp256k1_context_t* context )
|
bool verify_sig(const bytes &sig, const bytes &pubkey, const bytes &msg, const secp256k1_context_t *context) {
|
||||||
{
|
|
||||||
std::vector<unsigned char> sig_temp(sig.begin(), sig.end());
|
std::vector<unsigned char> sig_temp(sig.begin(), sig.end());
|
||||||
std::vector<unsigned char> pubkey_temp(pubkey.begin(), pubkey.end());
|
std::vector<unsigned char> pubkey_temp(pubkey.begin(), pubkey.end());
|
||||||
std::vector<unsigned char> msg_temp(msg.begin(), msg.end());
|
std::vector<unsigned char> msg_temp(msg.begin(), msg.end());
|
||||||
|
|
@ -90,13 +84,14 @@ 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,
|
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 )
|
const std::vector<uint64_t> &amounts, const secp256k1_context_t *context) {
|
||||||
{
|
|
||||||
FC_ASSERT(redeem_scripts.size() == amounts.size());
|
FC_ASSERT(redeem_scripts.size() == amounts.size());
|
||||||
|
|
||||||
using data = std::pair<size_t, bytes>;
|
using data = std::pair<size_t, bytes>;
|
||||||
struct comp {
|
struct comp {
|
||||||
bool operator() (const data& lhs, const data& rhs) const { return lhs.first < rhs.first; }
|
bool operator()(const data &lhs, const data &rhs) const {
|
||||||
|
return lhs.first < rhs.first;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::vector<bytes>> new_stacks;
|
std::vector<std::vector<bytes>> new_stacks;
|
||||||
|
|
@ -129,8 +124,7 @@ std::vector<std::vector<bytes>> sort_sigs( const bitcoin_transaction& tx, const
|
||||||
return new_stacks;
|
return new_stacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_signatures_to_transaction_multisig( bitcoin_transaction &tx, std::vector<std::vector<bytes>> &signature_set )
|
void add_signatures_to_transaction_multisig(bitcoin_transaction &tx, std::vector<std::vector<bytes>> &signature_set) {
|
||||||
{
|
|
||||||
for (unsigned int i = 0; i < signature_set.size(); i++) {
|
for (unsigned int i = 0; i < signature_set.size(); i++) {
|
||||||
std::vector<bytes> signatures = signature_set[i];
|
std::vector<bytes> signatures = signature_set[i];
|
||||||
FC_ASSERT(signatures.size() == tx.vin.size(), "Invalid signatures number");
|
FC_ASSERT(signatures.size() == tx.vin.size(), "Invalid signatures number");
|
||||||
|
|
@ -139,8 +133,7 @@ void add_signatures_to_transaction_multisig( bitcoin_transaction &tx, std::vecto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_signatures_to_transaction_weighted_multisig(bitcoin_transaction &tx, std::vector<std::vector<bytes>> &signature_set)
|
void add_signatures_to_transaction_weighted_multisig(bitcoin_transaction &tx, std::vector<std::vector<bytes>> &signature_set) {
|
||||||
{
|
|
||||||
for (unsigned int i = 0; i < signature_set.size(); i++) {
|
for (unsigned int i = 0; i < signature_set.size(); i++) {
|
||||||
std::vector<bytes> signatures = signature_set[i];
|
std::vector<bytes> signatures = signature_set[i];
|
||||||
FC_ASSERT(signatures.size() == tx.vin.size(), "Invalid signatures number");
|
FC_ASSERT(signatures.size() == tx.vin.size(), "Invalid signatures number");
|
||||||
|
|
@ -150,4 +143,4 @@ void add_signatures_to_transaction_weighted_multisig(bitcoin_transaction &tx, st
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} } }
|
}}} // namespace graphene::peerplays_sidechain::bitcoin
|
||||||
|
|
|
||||||
19
libraries/plugins/peerplays_sidechain/bitcoin/utils.cpp
Executable file → Normal file
19
libraries/plugins/peerplays_sidechain/bitcoin/utils.cpp
Executable file → Normal file
|
|
@ -1,10 +1,9 @@
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/utils.hpp>
|
|
||||||
#include <fc/crypto/base58.hpp>
|
#include <fc/crypto/base58.hpp>
|
||||||
|
#include <graphene/peerplays_sidechain/bitcoin/utils.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
||||||
|
|
||||||
fc::ecc::public_key_data create_public_key_data( const std::vector<char>& public_key )
|
fc::ecc::public_key_data create_public_key_data(const std::vector<char> &public_key) {
|
||||||
{
|
|
||||||
FC_ASSERT(public_key.size() == 33);
|
FC_ASSERT(public_key.size() == 33);
|
||||||
fc::ecc::public_key_data key;
|
fc::ecc::public_key_data key;
|
||||||
for (size_t i = 0; i < 33; i++) {
|
for (size_t i = 0; i < 33; i++) {
|
||||||
|
|
@ -13,22 +12,19 @@ fc::ecc::public_key_data create_public_key_data( const std::vector<char>& public
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes get_privkey_bytes( const std::string& privkey_base58 )
|
bytes get_privkey_bytes(const std::string &privkey_base58) {
|
||||||
{
|
|
||||||
const auto privkey = fc::from_base58(privkey_base58);
|
const auto privkey = fc::from_base58(privkey_base58);
|
||||||
// Remove version and hash
|
// Remove version and hash
|
||||||
return bytes(privkey.cbegin() + 1, privkey.cbegin() + 1 + 32);
|
return bytes(privkey.cbegin() + 1, privkey.cbegin() + 1 + 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes parse_hex( const std::string& str )
|
bytes parse_hex(const std::string &str) {
|
||||||
{
|
|
||||||
bytes vec(str.size() / 2);
|
bytes vec(str.size() / 2);
|
||||||
fc::from_hex(str, vec.data(), vec.size());
|
fc::from_hex(str, vec.data(), vec.size());
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<bytes> get_pubkey_from_redeemScript( bytes script )
|
std::vector<bytes> get_pubkey_from_redeemScript(bytes script) {
|
||||||
{
|
|
||||||
FC_ASSERT(script.size() >= 37);
|
FC_ASSERT(script.size() >= 37);
|
||||||
|
|
||||||
script.erase(script.begin());
|
script.erase(script.begin());
|
||||||
|
|
@ -42,12 +38,11 @@ std::vector<bytes> get_pubkey_from_redeemScript( bytes script )
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes public_key_data_to_bytes( const fc::ecc::public_key_data& key )
|
bytes public_key_data_to_bytes(const fc::ecc::public_key_data &key) {
|
||||||
{
|
|
||||||
bytes result;
|
bytes result;
|
||||||
result.resize(key.size());
|
result.resize(key.size());
|
||||||
std::copy(key.begin(), key.end(), result.begin());
|
std::copy(key.begin(), key.end(), result.begin());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
} } }
|
}}} // namespace graphene::peerplays_sidechain::bitcoin
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <boost/property_tree/json_parser.hpp>
|
||||||
#include <fc/crypto/base58.hpp>
|
#include <fc/crypto/base58.hpp>
|
||||||
#include <fc/crypto/elliptic.hpp>
|
#include <fc/crypto/elliptic.hpp>
|
||||||
#include <fc/crypto/ripemd160.hpp>
|
#include <fc/crypto/ripemd160.hpp>
|
||||||
|
|
@ -5,7 +6,6 @@
|
||||||
#include <fc/io/raw.hpp>
|
#include <fc/io/raw.hpp>
|
||||||
#include <graphene/peerplays_sidechain/bitcoin_utils.hpp>
|
#include <graphene/peerplays_sidechain/bitcoin_utils.hpp>
|
||||||
#include <secp256k1.h>
|
#include <secp256k1.h>
|
||||||
#include <boost/property_tree/json_parser.hpp>
|
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain {
|
namespace graphene { namespace peerplays_sidechain {
|
||||||
|
|
||||||
|
|
|
||||||
2
libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/bech32.hpp
Executable file → Normal file
2
libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/bech32.hpp
Executable file → Normal file
|
|
@ -21,4 +21,4 @@ std::string Encode(const std::string& hrp, const std::vector<uint8_t>& values);
|
||||||
/** Decode a Bech32 string. Returns (hrp, data). Empty hrp means failure. */
|
/** Decode a Bech32 string. Returns (hrp, data). Empty hrp means failure. */
|
||||||
std::pair<std::string, std::vector<uint8_t>> Decode(const std::string &str);
|
std::pair<std::string, std::vector<uint8_t>> Decode(const std::string &str);
|
||||||
|
|
||||||
} } } } // namespace sidechain::bech32
|
}}}} // namespace graphene::peerplays_sidechain::bitcoin::bech32
|
||||||
|
|
|
||||||
84
libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/bitcoin_address.hpp
Executable file → Normal file
84
libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/bitcoin_address.hpp
Executable file → Normal file
|
|
@ -9,8 +9,7 @@ namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
||||||
|
|
||||||
const bytes op_num = {0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}; // OP_1 - OP_15
|
const bytes op_num = {0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}; // OP_1 - OP_15
|
||||||
|
|
||||||
class bitcoin_address
|
class bitcoin_address {
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum network {
|
enum network {
|
||||||
|
|
@ -21,25 +20,36 @@ public:
|
||||||
|
|
||||||
bitcoin_address() = default;
|
bitcoin_address() = default;
|
||||||
|
|
||||||
bitcoin_address( const std::string& addr, network ntype = network::regtest ) : address( addr ), type( determine_type() ),
|
bitcoin_address(const std::string &addr, network ntype = network::regtest) :
|
||||||
raw_address( determine_raw_address() ), network_type(ntype) {}
|
address(addr),
|
||||||
|
type(determine_type()),
|
||||||
|
raw_address(determine_raw_address()),
|
||||||
|
network_type(ntype) {
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(const bitcoin_address &btc_addr) const;
|
bool operator==(const bitcoin_address &btc_addr) const;
|
||||||
|
|
||||||
payment_type get_type() const { return type; }
|
payment_type get_type() const {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
std::string get_address() const { return address; }
|
std::string get_address() const {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
bytes get_raw_address() const { return raw_address; }
|
bytes get_raw_address() const {
|
||||||
|
return raw_address;
|
||||||
|
}
|
||||||
|
|
||||||
bytes get_script() const;
|
bytes get_script() const;
|
||||||
|
|
||||||
network get_network_type() const {
|
network get_network_type() const {
|
||||||
return network_type;
|
return network_type;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
|
|
||||||
enum size_segwit_address { P2WSH = 32, P2WPKH = 20 };
|
private:
|
||||||
|
enum size_segwit_address { P2WSH = 32,
|
||||||
|
P2WPKH = 20 };
|
||||||
|
|
||||||
payment_type determine_type();
|
payment_type determine_type();
|
||||||
|
|
||||||
|
|
@ -58,7 +68,6 @@ private:
|
||||||
bool is_p2sh() const;
|
bool is_p2sh() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
std::string address;
|
std::string address;
|
||||||
|
|
||||||
payment_type type;
|
payment_type type;
|
||||||
|
|
@ -66,61 +75,60 @@ public:
|
||||||
bytes raw_address;
|
bytes raw_address;
|
||||||
|
|
||||||
network network_type;
|
network network_type;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class btc_multisig_address : public bitcoin_address
|
class btc_multisig_address : public bitcoin_address {
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
btc_multisig_address() = default;
|
btc_multisig_address() = default;
|
||||||
|
|
||||||
btc_multisig_address(const size_t n_required, const accounts_keys &keys);
|
btc_multisig_address(const size_t n_required, const accounts_keys &keys);
|
||||||
|
|
||||||
size_t count_intersection(const accounts_keys &keys) const;
|
size_t count_intersection(const accounts_keys &keys) const;
|
||||||
|
|
||||||
bytes get_redeem_script() const { return redeem_script; }
|
bytes get_redeem_script() const {
|
||||||
|
return redeem_script;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void create_redeem_script();
|
void create_redeem_script();
|
||||||
|
|
||||||
void create_address();
|
void create_address();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum address_types { MAINNET_SCRIPT = 5,
|
||||||
|
TESTNET_SCRIPT = 196 };
|
||||||
|
|
||||||
enum address_types { MAINNET_SCRIPT = 5, TESTNET_SCRIPT = 196 };
|
enum { OP_0 = 0x00,
|
||||||
|
OP_EQUAL = 0x87,
|
||||||
enum { OP_0 = 0x00, OP_EQUAL = 0x87, OP_HASH160 = 0xa9, OP_CHECKMULTISIG = 0xae };
|
OP_HASH160 = 0xa9,
|
||||||
|
OP_CHECKMULTISIG = 0xae };
|
||||||
|
|
||||||
bytes redeem_script;
|
bytes redeem_script;
|
||||||
|
|
||||||
size_t keys_required = 0;
|
size_t keys_required = 0;
|
||||||
|
|
||||||
accounts_keys witnesses_keys;
|
accounts_keys witnesses_keys;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// multisig segwit address (P2WSH)
|
// multisig segwit address (P2WSH)
|
||||||
// https://0bin.net/paste/nfnSf0HcBqBUGDto#7zJMRUhGEBkyh-eASQPEwKfNHgQ4D5KrUJRsk8MTPSa
|
// https://0bin.net/paste/nfnSf0HcBqBUGDto#7zJMRUhGEBkyh-eASQPEwKfNHgQ4D5KrUJRsk8MTPSa
|
||||||
class btc_multisig_segwit_address : public btc_multisig_address
|
class btc_multisig_segwit_address : public btc_multisig_address {
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
btc_multisig_segwit_address() = default;
|
btc_multisig_segwit_address() = default;
|
||||||
|
|
||||||
btc_multisig_segwit_address(const size_t n_required, const accounts_keys &keys);
|
btc_multisig_segwit_address(const size_t n_required, const accounts_keys &keys);
|
||||||
|
|
||||||
bool operator==(const btc_multisig_segwit_address &addr) const;
|
bool operator==(const btc_multisig_segwit_address &addr) const;
|
||||||
|
|
||||||
bytes get_witness_script() const { return witness_script; }
|
bytes get_witness_script() const {
|
||||||
|
return witness_script;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<public_key_type> get_keys();
|
std::vector<public_key_type> get_keys();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void create_witness_script();
|
void create_witness_script();
|
||||||
|
|
||||||
void create_segwit_address();
|
void create_segwit_address();
|
||||||
|
|
@ -128,13 +136,10 @@ private:
|
||||||
bytes get_address_bytes(const bytes &script_hash);
|
bytes get_address_bytes(const bytes &script_hash);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bytes witness_script;
|
bytes witness_script;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class btc_weighted_multisig_address : public bitcoin_address
|
class btc_weighted_multisig_address : public bitcoin_address {
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
btc_weighted_multisig_address() = default;
|
btc_weighted_multisig_address() = default;
|
||||||
|
|
@ -142,10 +147,14 @@ public:
|
||||||
btc_weighted_multisig_address(const std::vector<std::pair<fc::ecc::public_key, uint16_t>> &keys_data,
|
btc_weighted_multisig_address(const std::vector<std::pair<fc::ecc::public_key, uint16_t>> &keys_data,
|
||||||
network network_type = network::regtest);
|
network network_type = network::regtest);
|
||||||
|
|
||||||
bytes get_redeem_script() const { return redeem_script_; }
|
bytes get_redeem_script() const {
|
||||||
bytes get_witness_script() const { return witness_script_; }
|
return redeem_script_;
|
||||||
private:
|
}
|
||||||
|
bytes get_witness_script() const {
|
||||||
|
return witness_script_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
void create_redeem_script(const std::vector<std::pair<fc::ecc::public_key, uint16_t>> &keys_data);
|
void create_redeem_script(const std::vector<std::pair<fc::ecc::public_key, uint16_t>> &keys_data);
|
||||||
void create_witness_script();
|
void create_witness_script();
|
||||||
void create_segwit_address();
|
void create_segwit_address();
|
||||||
|
|
@ -166,10 +175,12 @@ public:
|
||||||
bytes get_witness_script() const {
|
bytes get_witness_script() const {
|
||||||
return witness_script_;
|
return witness_script_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void create_redeem_script(const fc::ecc::public_key &user_key_data, const uint8_t nrequired, const std::vector<fc::ecc::public_key> &keys_data);
|
void create_redeem_script(const fc::ecc::public_key &user_key_data, const uint8_t nrequired, const std::vector<fc::ecc::public_key> &keys_data);
|
||||||
void create_witness_script();
|
void create_witness_script();
|
||||||
void create_segwit_address();
|
void create_segwit_address();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bytes redeem_script_;
|
bytes redeem_script_;
|
||||||
bytes witness_script_;
|
bytes witness_script_;
|
||||||
|
|
@ -186,22 +197,21 @@ public:
|
||||||
bytes get_witness_script() const {
|
bytes get_witness_script() const {
|
||||||
return witness_script_;
|
return witness_script_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void create_redeem_script(const fc::ecc::public_key &user_key_data, const std::vector<std::pair<fc::ecc::public_key, uint16_t>> &keys_data);
|
void create_redeem_script(const fc::ecc::public_key &user_key_data, const std::vector<std::pair<fc::ecc::public_key, uint16_t>> &keys_data);
|
||||||
void create_witness_script();
|
void create_witness_script();
|
||||||
void create_segwit_address();
|
void create_segwit_address();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bytes redeem_script_;
|
bytes redeem_script_;
|
||||||
bytes witness_script_;
|
bytes witness_script_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} } }
|
}}} // namespace graphene::peerplays_sidechain::bitcoin
|
||||||
|
|
||||||
FC_REFLECT_ENUM(graphene::peerplays_sidechain::bitcoin::bitcoin_address::network,
|
FC_REFLECT_ENUM(graphene::peerplays_sidechain::bitcoin::bitcoin_address::network,
|
||||||
(mainnet)
|
(mainnet)(testnet)(regtest))
|
||||||
(testnet)
|
|
||||||
(regtest)
|
|
||||||
)
|
|
||||||
|
|
||||||
FC_REFLECT(graphene::peerplays_sidechain::bitcoin::bitcoin_address, (address)(type)(raw_address)(network_type));
|
FC_REFLECT(graphene::peerplays_sidechain::bitcoin::bitcoin_address, (address)(type)(raw_address)(network_type));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,6 @@ enum class op {
|
||||||
class script_builder {
|
class script_builder {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
script_builder &operator<<(op opcode);
|
script_builder &operator<<(op opcode);
|
||||||
|
|
||||||
script_builder &operator<<(uint32_t number);
|
script_builder &operator<<(uint32_t number);
|
||||||
|
|
@ -69,12 +68,12 @@ public:
|
||||||
|
|
||||||
script_builder &operator<<(const fc::ecc::public_key_data &pubkey_data);
|
script_builder &operator<<(const fc::ecc::public_key_data &pubkey_data);
|
||||||
|
|
||||||
operator bytes() const { return std::move( script ); }
|
operator bytes() const {
|
||||||
|
return std::move(script);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bytes script;
|
bytes script;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} } }
|
}}} // namespace graphene::peerplays_sidechain::bitcoin
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,10 @@ struct out_point {
|
||||||
fc::sha256 hash;
|
fc::sha256 hash;
|
||||||
uint32_t n = 0;
|
uint32_t n = 0;
|
||||||
out_point() = default;
|
out_point() = default;
|
||||||
out_point( fc::sha256 _hash, uint32_t _n ) : hash( _hash ), n( _n ) {}
|
out_point(fc::sha256 _hash, uint32_t _n) :
|
||||||
|
hash(_hash),
|
||||||
|
n(_n) {
|
||||||
|
}
|
||||||
bool operator==(const out_point &op) const;
|
bool operator==(const out_point &op) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -54,14 +57,14 @@ struct bitcoin_transaction {
|
||||||
size_t get_vsize() const;
|
size_t get_vsize() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class bitcoin_transaction_builder
|
class bitcoin_transaction_builder {
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bitcoin_transaction_builder() = default;
|
bitcoin_transaction_builder() = default;
|
||||||
|
|
||||||
bitcoin_transaction_builder( const bitcoin_transaction _tx ) : tx( _tx ) {}
|
bitcoin_transaction_builder(const bitcoin_transaction _tx) :
|
||||||
|
tx(_tx) {
|
||||||
|
}
|
||||||
|
|
||||||
void set_version(int32_t version);
|
void set_version(int32_t version);
|
||||||
|
|
||||||
|
|
@ -80,19 +83,19 @@ public:
|
||||||
|
|
||||||
void add_out_all_type(const uint64_t &amount, const bitcoin_address &address, bool front = false);
|
void add_out_all_type(const uint64_t &amount, const bitcoin_address &address, bool front = false);
|
||||||
|
|
||||||
bitcoin_transaction get_transaction() const { return tx; }
|
bitcoin_transaction get_transaction() const {
|
||||||
|
return tx;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
inline bool is_payment_to_pubkey(payment_type type);
|
inline bool is_payment_to_pubkey(payment_type type);
|
||||||
|
|
||||||
bytes get_script_pubkey(payment_type type, const bytes &script_code);
|
bytes get_script_pubkey(payment_type type, const bytes &script_code);
|
||||||
|
|
||||||
bitcoin_transaction tx;
|
bitcoin_transaction tx;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} } }
|
}}} // namespace graphene::peerplays_sidechain::bitcoin
|
||||||
|
|
||||||
FC_REFLECT(graphene::peerplays_sidechain::bitcoin::out_point, (hash)(n))
|
FC_REFLECT(graphene::peerplays_sidechain::bitcoin::out_point, (hash)(n))
|
||||||
FC_REFLECT(graphene::peerplays_sidechain::bitcoin::tx_in, (prevout)(scriptSig)(nSequence)(scriptWitness))
|
FC_REFLECT(graphene::peerplays_sidechain::bitcoin::tx_in, (prevout)(scriptSig)(nSequence)(scriptWitness))
|
||||||
|
|
|
||||||
4
libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/segwit_addr.hpp
Executable file → Normal file
4
libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/segwit_addr.hpp
Executable file → Normal file
|
|
@ -20,8 +20,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain { namespace bitcoin { namespace segwit_addr {
|
namespace graphene { namespace peerplays_sidechain { namespace bitcoin { namespace segwit_addr {
|
||||||
|
|
||||||
|
|
@ -31,4 +31,4 @@ std::pair<int, std::vector<uint8_t> > decode(const std::string& hrp, const std::
|
||||||
/** Encode a SegWit address. Empty string means failure. */
|
/** Encode a SegWit address. Empty string means failure. */
|
||||||
std::string encode(const std::string &hrp, int witver, const std::vector<uint8_t> &witprog);
|
std::string encode(const std::string &hrp, int witver, const std::vector<uint8_t> &witprog);
|
||||||
|
|
||||||
} } } }
|
}}}} // namespace graphene::peerplays_sidechain::bitcoin::segwit_addr
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/types.hpp>
|
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_transaction.hpp>
|
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_transaction.hpp>
|
||||||
|
#include <graphene/peerplays_sidechain/bitcoin/types.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
||||||
|
|
||||||
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) {
|
||||||
|
|
@ -28,8 +27,7 @@ inline void write_compact_size( bytes& vec, size_t size )
|
||||||
}
|
}
|
||||||
|
|
||||||
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()) {
|
||||||
|
|
@ -45,8 +43,7 @@ inline void pack_compact_size(Stream& s, size_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;
|
||||||
|
|
||||||
|
|
@ -80,24 +77,25 @@ inline uint64_t unpack_compact_size( Stream& s )
|
||||||
return size_ret;
|
return size_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Stream>
|
||||||
|
inline void unpack(Stream &s, int64_t &u, uint32_t _max_depth = FC_PACK_MAX_DEPTH) {
|
||||||
|
s.read((char *)&u, sizeof(u));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Stream>
|
template <typename Stream>
|
||||||
inline void unpack( Stream& s, int64_t& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { s.read( (char*)&u, sizeof(u) ); }
|
inline void unpack(Stream &s, int32_t &u, uint32_t _max_depth = FC_PACK_MAX_DEPTH) {
|
||||||
|
s.read((char *)&u, sizeof(u));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Stream>
|
template <typename Stream>
|
||||||
inline void unpack( Stream& s, int32_t& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { s.read( (char*)&u, sizeof(u) ); }
|
inline void pack(Stream &s, const std::vector<char> &v) {
|
||||||
|
|
||||||
template<typename Stream>
|
|
||||||
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)
|
||||||
|
|
@ -105,20 +103,17 @@ inline void unpack( Stream& s, std::vector<char>& v )
|
||||||
}
|
}
|
||||||
|
|
||||||
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());
|
||||||
|
|
@ -126,8 +121,7 @@ inline void pack( Stream& s, const out_point& op )
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
@ -138,38 +132,33 @@ inline void unpack( Stream& s, out_point& op )
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
|
@ -208,8 +197,7 @@ inline void pack( Stream& s, const bitcoin_transaction& tx, bool with_witness =
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
@ -250,8 +238,7 @@ inline void unpack( Stream& s, bitcoin_transaction& tx )
|
||||||
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());
|
||||||
|
|
@ -263,19 +250,20 @@ inline std::vector<char> pack( const bitcoin_transaction& v, bool 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());
|
||||||
|
|
@ -298,8 +286,7 @@ inline void pack_tx_signature( Stream& s, const std::vector<char>& scriptPubKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
@ -364,4 +351,4 @@ inline void pack_tx_witness_signature( Stream& s, const std::vector<char>& scrip
|
||||||
pack(s, hash_type);
|
pack(s, hash_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
} } }
|
}}} // namespace graphene::peerplays_sidechain::bitcoin
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/types.hpp>
|
|
||||||
#include <fc/crypto/sha256.hpp>
|
#include <fc/crypto/sha256.hpp>
|
||||||
|
#include <graphene/peerplays_sidechain/bitcoin/types.hpp>
|
||||||
#include <secp256k1.h>
|
#include <secp256k1.h>
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
||||||
|
|
@ -30,4 +30,4 @@ void add_signatures_to_transaction_multisig( bitcoin_transaction &tx, std::vecto
|
||||||
|
|
||||||
void add_signatures_to_transaction_weighted_multisig(bitcoin_transaction &tx, std::vector<std::vector<bytes>> &signature_set);
|
void add_signatures_to_transaction_weighted_multisig(bitcoin_transaction &tx, std::vector<std::vector<bytes>> &signature_set);
|
||||||
|
|
||||||
} } }
|
}}} // namespace graphene::peerplays_sidechain::bitcoin
|
||||||
|
|
|
||||||
23
libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/types.hpp
Executable file → Normal file
23
libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/types.hpp
Executable file → Normal file
|
|
@ -1,9 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <fc/reflect/reflect.hpp>
|
#include <fc/reflect/reflect.hpp>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <graphene/chain/protocol/types.hpp>
|
#include <graphene/chain/protocol/types.hpp>
|
||||||
|
|
||||||
|
|
@ -15,8 +15,7 @@ using bytes = std::vector<char>;
|
||||||
using accounts_keys = std::map<graphene::chain::son_id_type, graphene::chain::public_key_type>;
|
using accounts_keys = std::map<graphene::chain::son_id_type, graphene::chain::public_key_type>;
|
||||||
using full_btc_transaction = std::pair<bitcoin_transaction, uint64_t>;
|
using full_btc_transaction = std::pair<bitcoin_transaction, uint64_t>;
|
||||||
|
|
||||||
enum class payment_type
|
enum class payment_type {
|
||||||
{
|
|
||||||
NULLDATA,
|
NULLDATA,
|
||||||
P2PK,
|
P2PK,
|
||||||
P2PKH,
|
P2PKH,
|
||||||
|
|
@ -27,21 +26,17 @@ enum class payment_type
|
||||||
P2SH_WSH
|
P2SH_WSH
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class sidechain_proposal_type
|
enum class sidechain_proposal_type {
|
||||||
{
|
|
||||||
ISSUE_BTC,
|
ISSUE_BTC,
|
||||||
SEND_BTC_TRANSACTION,
|
SEND_BTC_TRANSACTION,
|
||||||
REVERT_BTC_TRANSACTION
|
REVERT_BTC_TRANSACTION
|
||||||
};
|
};
|
||||||
|
|
||||||
struct prev_out
|
struct prev_out {
|
||||||
{
|
bool operator!=(const prev_out &obj) const {
|
||||||
bool operator!=( const prev_out& obj ) const
|
|
||||||
{
|
|
||||||
if (this->hash_tx != obj.hash_tx ||
|
if (this->hash_tx != obj.hash_tx ||
|
||||||
this->n_vout != obj.n_vout ||
|
this->n_vout != obj.n_vout ||
|
||||||
this->amount != obj.amount )
|
this->amount != obj.amount) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -52,7 +47,7 @@ struct prev_out
|
||||||
uint64_t amount;
|
uint64_t amount;
|
||||||
};
|
};
|
||||||
|
|
||||||
} } }
|
}}} // namespace graphene::peerplays_sidechain::bitcoin
|
||||||
|
|
||||||
FC_REFLECT_ENUM(graphene::peerplays_sidechain::bitcoin::payment_type, (NULLDATA)(P2PK)(P2PKH)(P2SH)(P2WPKH)(P2WSH)(P2SH_WPKH)(P2SH_WSH));
|
FC_REFLECT_ENUM(graphene::peerplays_sidechain::bitcoin::payment_type, (NULLDATA)(P2PK)(P2PKH)(P2SH)(P2WPKH)(P2WSH)(P2SH_WPKH)(P2SH_WSH));
|
||||||
FC_REFLECT_ENUM(graphene::peerplays_sidechain::bitcoin::sidechain_proposal_type, (ISSUE_BTC)(SEND_BTC_TRANSACTION)(REVERT_BTC_TRANSACTION));
|
FC_REFLECT_ENUM(graphene::peerplays_sidechain::bitcoin::sidechain_proposal_type, (ISSUE_BTC)(SEND_BTC_TRANSACTION)(REVERT_BTC_TRANSACTION));
|
||||||
|
|
|
||||||
6
libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/utils.hpp
Executable file → Normal file
6
libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/utils.hpp
Executable file → Normal file
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <graphene/peerplays_sidechain/bitcoin/types.hpp>
|
|
||||||
#include <fc/crypto/hex.hpp>
|
|
||||||
#include <fc/crypto/elliptic.hpp>
|
#include <fc/crypto/elliptic.hpp>
|
||||||
|
#include <fc/crypto/hex.hpp>
|
||||||
|
#include <graphene/peerplays_sidechain/bitcoin/types.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {
|
||||||
|
|
||||||
|
|
@ -15,4 +15,4 @@ std::vector<bytes> get_pubkey_from_redeemScript( bytes script );
|
||||||
|
|
||||||
bytes public_key_data_to_bytes(const fc::ecc::public_key_data &key);
|
bytes public_key_data_to_bytes(const fc::ecc::public_key_data &key);
|
||||||
|
|
||||||
} } }
|
}}} // namespace graphene::peerplays_sidechain::bitcoin
|
||||||
|
|
@ -1454,15 +1454,13 @@ std::string sidechain_net_handler_bitcoin::send_transaction(const sidechain_tran
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<bitcoin::bytes> read_byte_arrays_from_string(const std::string &string_buf)
|
std::vector<bitcoin::bytes> read_byte_arrays_from_string(const std::string &string_buf) {
|
||||||
{
|
|
||||||
std::stringstream ss(string_buf);
|
std::stringstream ss(string_buf);
|
||||||
boost::property_tree::ptree json;
|
boost::property_tree::ptree json;
|
||||||
boost::property_tree::read_json(ss, json);
|
boost::property_tree::read_json(ss, json);
|
||||||
|
|
||||||
std::vector<bitcoin::bytes> data;
|
std::vector<bitcoin::bytes> data;
|
||||||
for(auto &v: json)
|
for (auto &v : json) {
|
||||||
{
|
|
||||||
std::string hex = v.second.data();
|
std::string hex = v.second.data();
|
||||||
bitcoin::bytes item;
|
bitcoin::bytes item;
|
||||||
item.resize(hex.size() / 2);
|
item.resize(hex.size() / 2);
|
||||||
|
|
@ -1472,8 +1470,7 @@ std::vector<bitcoin::bytes> read_byte_arrays_from_string(const std::string &stri
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string write_byte_arrays_to_string(const std::vector<bitcoin::bytes>& data)
|
std::string write_byte_arrays_to_string(const std::vector<bitcoin::bytes> &data) {
|
||||||
{
|
|
||||||
std::string res = "[";
|
std::string res = "[";
|
||||||
for (unsigned int idx = 0; idx < data.size(); ++idx) {
|
for (unsigned int idx = 0; idx < data.size(); ++idx) {
|
||||||
res += "\"" + fc::to_hex((char *)&data[idx][0], data[idx].size()) + "\"";
|
res += "\"" + fc::to_hex((char *)&data[idx][0], data[idx].size()) + "\"";
|
||||||
|
|
@ -1484,8 +1481,7 @@ std::string write_byte_arrays_to_string(const std::vector<bitcoin::bytes>& data)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_tx_data_from_string(const std::string &string_buf, std::vector<unsigned char> &tx, std::vector<uint64_t> &in_amounts)
|
void read_tx_data_from_string(const std::string &string_buf, std::vector<unsigned char> &tx, std::vector<uint64_t> &in_amounts) {
|
||||||
{
|
|
||||||
std::stringstream ss(string_buf);
|
std::stringstream ss(string_buf);
|
||||||
boost::property_tree::ptree json;
|
boost::property_tree::ptree json;
|
||||||
boost::property_tree::read_json(ss, json);
|
boost::property_tree::read_json(ss, json);
|
||||||
|
|
@ -1498,8 +1494,7 @@ void read_tx_data_from_string(const std::string &string_buf, std::vector<unsigne
|
||||||
in_amounts.push_back(fc::to_uint64(v.second.data()));
|
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)
|
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);
|
std::stringstream ss(string_buf);
|
||||||
boost::property_tree::ptree json;
|
boost::property_tree::ptree json;
|
||||||
boost::property_tree::read_json(ss, json);
|
boost::property_tree::read_json(ss, json);
|
||||||
|
|
@ -1509,8 +1504,7 @@ void read_tx_data_from_string(const std::string &string_buf, std::string &tx_hex
|
||||||
in_amounts.push_back(fc::to_uint64(v.second.data()));
|
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 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\":[";
|
std::string res = "{\"tx_hex\":\"" + fc::to_hex((const char *)&tx[0], tx.size()) + "\",\"in_amounts\":[";
|
||||||
for (unsigned int idx = 0; idx < in_amounts.size(); ++idx) {
|
for (unsigned int idx = 0; idx < in_amounts.size(); ++idx) {
|
||||||
res += fc::to_string(in_amounts[idx]);
|
res += fc::to_string(in_amounts[idx]);
|
||||||
|
|
@ -1521,8 +1515,7 @@ std::string save_tx_data_to_string(const std::vector<unsigned char> &tx, const s
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string save_tx_data_to_string(const std::string &tx, const std::vector<uint64_t> &in_amounts)
|
std::string save_tx_data_to_string(const std::string &tx, const std::vector<uint64_t> &in_amounts) {
|
||||||
{
|
|
||||||
std::string res = "{\"tx_hex\":\"" + tx + "\",\"in_amounts\":[";
|
std::string res = "{\"tx_hex\":\"" + tx + "\",\"in_amounts\":[";
|
||||||
for (unsigned int idx = 0; idx < in_amounts.size(); ++idx) {
|
for (unsigned int idx = 0; idx < in_amounts.size(); ++idx) {
|
||||||
res += fc::to_string(in_amounts[idx]);
|
res += fc::to_string(in_amounts[idx]);
|
||||||
|
|
@ -1767,8 +1760,7 @@ std::string sidechain_net_handler_bitcoin::sign_transaction_standalone(const sid
|
||||||
//const auto privkey_signing = get_privkey_bytes( prvkey );
|
//const auto privkey_signing = get_privkey_bytes( prvkey );
|
||||||
|
|
||||||
fc::optional<fc::ecc::private_key> btc_private_key = graphene::utilities::wif_to_key(prvkey);
|
fc::optional<fc::ecc::private_key> btc_private_key = graphene::utilities::wif_to_key(prvkey);
|
||||||
if (!btc_private_key)
|
if (!btc_private_key) {
|
||||||
{
|
|
||||||
elog("Invalid private key ${pk}", ("pk", prvkey));
|
elog("Invalid private key ${pk}", ("pk", prvkey));
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue