Browse Source
0.168213838
[Qt] tolerate BIP173/bech32 addresses during input validation (Jonas Schnelli)06eaca6
[RPC] Wallet: test importing of native witness scripts (NicolasDorier)fd0041a
Use BIP173 addresses in segwit.py test (Pieter Wuille)e278f12
Support BIP173 in addwitnessaddress (Pieter Wuille)c091b99
Implement BIP173 addresses and tests (Pieter Wuille)bd355b8
Add regtest testing to base58_tests (Pieter Wuille)6565c55
Convert base58_tests from type/payload to scriptPubKey comparison (Pieter Wuille)8fd2267
Import Bech32 C++ reference code & tests (Pieter Wuille)1e46ebd
Implement {Encode,Decode}Destination without CBitcoinAddress (Pieter Wuille) Pull request description: Builds on top of #11117. This adds support for: * Creating BIP173 addresses for testing (through `addwitnessaddress`, though by default it still produces P2SH versions) * Sending to BIP173 addresses (including non-v0 ones) * Analysing BIP173 addresses (through `validateaddress`) It includes a reformatted version of the [C++ Bech32 reference code](https://github.com/sipa/bech32/tree/master/ref/c%2B%2B) and an independent implementation of the address encoding/decoding logic (integrated with CTxDestination). All BIP173 test vectors are included. Not included (and intended for other PRs): * Full wallet support for SegWit (which would include automatically adding witness scripts to the wallet during automatic keypool topup, SegWit change outputs, ...) [see #11403] * Splitting base58.cpp and tests/base58_tests.cpp up into base58-specific code, and "address encoding"-code [see #11372] * Error locating in UI for BIP173 addresses. Tree-SHA512: 238031185fd07f3ac873c586043970cc2db91bf7735c3c168cb33a3db39a7bda81d4891b649685bb17ef90dc63af0328e7705d8cd3e8dafd6c4d3c08fb230341
Wladimir J. van der Laan
7 years ago
30 changed files with 1290 additions and 531 deletions
@ -0,0 +1,191 @@
@@ -0,0 +1,191 @@
|
||||
// Copyright (c) 2017 Pieter Wuille
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "bech32.h" |
||||
|
||||
namespace |
||||
{ |
||||
|
||||
typedef std::vector<uint8_t> data; |
||||
|
||||
/** The Bech32 character set for encoding. */ |
||||
const char* CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; |
||||
|
||||
/** The Bech32 character set for decoding. */ |
||||
const int8_t CHARSET_REV[128] = { |
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||
15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -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, 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 |
||||
}; |
||||
|
||||
/** Concatenate two byte arrays. */ |
||||
data Cat(data x, const data& y) |
||||
{ |
||||
x.insert(x.end(), y.begin(), y.end()); |
||||
return x; |
||||
} |
||||
|
||||
/** 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 |
||||
* bits correspond to earlier values. */ |
||||
uint32_t PolyMod(const data& v) |
||||
{ |
||||
// 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) =
|
||||
// 1*x^5 + v0*x^4 + v1*x^3 + v2*x^2 + v3*x + v4. The implicit 1 guarantees that
|
||||
// [v0,v1,v2,...] has a distinct checksum from [0,v0,v1,v2,...].
|
||||
|
||||
// The output is a 30-bit integer whose 5-bit groups are the coefficients of the remainder of
|
||||
// v(x) mod g(x), where g(x) is the Bech32 generator,
|
||||
// x^6 + {29}x^5 + {22}x^4 + {20}x^3 + {21}x^2 + {29}x + {18}. g(x) is chosen in such a way
|
||||
// that the resulting code is a BCH code, guaranteeing detection of up to 3 errors within a
|
||||
// window of 1023 characters. Among the various possible BCH codes, one was selected to in
|
||||
// fact guarantee detection of up to 4 errors within a window of 89 characters.
|
||||
|
||||
// Note that the coefficients are elements of GF(32), here represented as decimal numbers
|
||||
// between {}. In this finite field, addition is just XOR of the corresponding numbers. For
|
||||
// example, {27} + {13} = {27 ^ 13} = {22}. Multiplication is more complicated, and requires
|
||||
// treating the bits of values themselves as coefficients of a polynomial over a smaller field,
|
||||
// GF(2), and multiplying those polynomials mod a^5 + a^3 + 1. For example, {5} * {26} =
|
||||
// (a^2 + 1) * (a^4 + a^3 + a) = (a^4 + a^3 + a) * a^2 + (a^4 + a^3 + a) = a^6 + a^5 + a^4 + a
|
||||
// = a^3 + 1 (mod a^5 + a^3 + 1) = {9}.
|
||||
|
||||
// During the course of the loop below, `c` contains the bitpacked coefficients of the
|
||||
// polynomial constructed from just the values of v that were processed so far, mod g(x). In
|
||||
// the above example, `c` initially corresponds to 1 mod (x), and after processing 2 inputs of
|
||||
// v, it corresponds to x^2 + v0*x + v1 mod g(x). As 1 mod g(x) = 1, that is the starting value
|
||||
// for `c`.
|
||||
uint32_t c = 1; |
||||
for (auto v_i : v) { |
||||
// We want to update `c` to correspond to a polynomial with one extra term. If the initial
|
||||
// value of `c` consists of the coefficients of c(x) = f(x) mod g(x), we modify it to
|
||||
// correspond to c'(x) = (f(x) * x + v_i) mod g(x), where v_i is the next input to
|
||||
// process. Simplifying:
|
||||
// c'(x) = (f(x) * x + v_i) mod g(x)
|
||||
// ((f(x) mod g(x)) * x + v_i) mod g(x)
|
||||
// (c(x) * x + v_i) mod g(x)
|
||||
// If c(x) = c0*x^5 + c1*x^4 + c2*x^3 + c3*x^2 + c4*x + c5, we want to compute
|
||||
// c'(x) = (c0*x^5 + c1*x^4 + c2*x^3 + c3*x^2 + c4*x + c5) * x + v_i mod g(x)
|
||||
// = c0*x^6 + c1*x^5 + c2*x^4 + c3*x^3 + c4*x^2 + c5*x + v_i mod g(x)
|
||||
// = c0*(x^6 mod g(x)) + c1*x^5 + c2*x^4 + c3*x^3 + c4*x^2 + c5*x + v_i
|
||||
// If we call (x^6 mod g(x)) = k(x), this can be written as
|
||||
// c'(x) = (c1*x^5 + c2*x^4 + c3*x^3 + c4*x^2 + c5*x + v_i) + c0*k(x)
|
||||
|
||||
// First, determine the value of c0:
|
||||
uint8_t c0 = c >> 25; |
||||
|
||||
// Then compute c1*x^5 + c2*x^4 + c3*x^3 + c4*x^2 + c5*x + v_i:
|
||||
c = ((c & 0x1ffffff) << 5) ^ v_i; |
||||
|
||||
// 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 & 2) c ^= 0x26508e6d; // {2}k(x) = {19}x^5 + {5}x^4 + x^3 + {3}x^2 + {19}x + {13}
|
||||
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; |
||||
} |
||||
|
||||
/** Convert to lower case. */ |
||||
inline unsigned char LowerCase(unsigned char c) |
||||
{ |
||||
return (c >= 'A' && c <= 'Z') ? (c - 'A') + 'a' : c; |
||||
} |
||||
|
||||
/** Expand a HRP for use in checksum computation. */ |
||||
data ExpandHRP(const std::string& hrp) |
||||
{ |
||||
data ret; |
||||
ret.reserve(hrp.size() + 90); |
||||
ret.resize(hrp.size() * 2 + 1); |
||||
for (size_t i = 0; i < hrp.size(); ++i) { |
||||
unsigned char c = hrp[i]; |
||||
ret[i] = c >> 5; |
||||
ret[i + hrp.size() + 1] = c & 0x1f; |
||||
} |
||||
ret[hrp.size()] = 0; |
||||
return ret; |
||||
} |
||||
|
||||
/** Verify a checksum. */ |
||||
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,
|
||||
// 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
|
||||
// resulting checksum to be 1 instead.
|
||||
return PolyMod(Cat(ExpandHRP(hrp), values)) == 1; |
||||
} |
||||
|
||||
/** Create a checksum. */ |
||||
data CreateChecksum(const std::string& hrp, const data& values) |
||||
{ |
||||
data enc = Cat(ExpandHRP(hrp), values); |
||||
enc.resize(enc.size() + 6); // Append 6 zeroes
|
||||
uint32_t mod = PolyMod(enc) ^ 1; // Determine what to XOR into those 6 zeroes.
|
||||
data ret(6); |
||||
for (size_t i = 0; i < 6; ++i) { |
||||
// Convert the 5-bit groups in mod to checksum values.
|
||||
ret[i] = (mod >> (5 * (5 - i))) & 31; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
} // namespace
|
||||
|
||||
namespace bech32 |
||||
{ |
||||
|
||||
/** Encode a Bech32 string. */ |
||||
std::string Encode(const std::string& hrp, const data& values) { |
||||
data checksum = CreateChecksum(hrp, values); |
||||
data combined = Cat(values, checksum); |
||||
std::string ret = hrp + '1'; |
||||
ret.reserve(ret.size() + combined.size()); |
||||
for (auto c : combined) { |
||||
ret += CHARSET[c]; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
/** Decode a Bech32 string. */ |
||||
std::pair<std::string, data> Decode(const std::string& str) { |
||||
bool lower = false, upper = false; |
||||
for (size_t i = 0; i < str.size(); ++i) { |
||||
unsigned char c = str[i]; |
||||
if (c < 33 || c > 126) return {}; |
||||
if (c >= 'a' && c <= 'z') lower = true; |
||||
if (c >= 'A' && c <= 'Z') upper = true; |
||||
} |
||||
if (lower && upper) return {}; |
||||
size_t pos = str.rfind('1'); |
||||
if (str.size() > 90 || pos == str.npos || pos == 0 || pos + 7 > str.size()) { |
||||
return {}; |
||||
} |
||||
data values(str.size() - 1 - pos); |
||||
for (size_t i = 0; i < str.size() - 1 - pos; ++i) { |
||||
unsigned char c = str[i + pos + 1]; |
||||
int8_t rev = (c < 33 || c > 126) ? -1 : CHARSET_REV[c]; |
||||
if (rev == -1) { |
||||
return {}; |
||||
} |
||||
values[i] = rev; |
||||
} |
||||
std::string hrp; |
||||
for (size_t i = 0; i < pos; ++i) { |
||||
hrp += LowerCase(str[i]); |
||||
} |
||||
if (!VerifyChecksum(hrp, values)) { |
||||
return {}; |
||||
} |
||||
return {hrp, data(values.begin(), values.end() - 6)}; |
||||
} |
||||
|
||||
} // namespace bech32
|
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2017 Pieter Wuille
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
// Bech32 is a string encoding format used in newer address types.
|
||||
// The output consists of a human-readable part (alphanumeric), a
|
||||
// separator character (1), and a base32 data section, the last
|
||||
// 6 characters of which are a checksum.
|
||||
//
|
||||
// For more information, see BIP 173.
|
||||
|
||||
#include <stdint.h> |
||||
#include <string> |
||||
#include <vector> |
||||
|
||||
namespace bech32 |
||||
{ |
||||
|
||||
/** Encode a Bech32 string. Returns the empty string in case of failure. */ |
||||
std::string Encode(const std::string& hrp, const std::vector<uint8_t>& values); |
||||
|
||||
/** Decode a Bech32 string. Returns (hrp, data). Empty hrp means failure. */ |
||||
std::pair<std::string, std::vector<uint8_t>> Decode(const std::string& str); |
||||
|
||||
} // namespace bech32
|
@ -0,0 +1,67 @@
@@ -0,0 +1,67 @@
|
||||
// Copyright (c) 2017 Pieter Wuille
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "bech32.h" |
||||
#include "test/test_bitcoin.h" |
||||
|
||||
#include <boost/test/unit_test.hpp> |
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(bech32_tests, BasicTestingSetup) |
||||
|
||||
bool CaseInsensitiveEqual(const std::string &s1, const std::string &s2) |
||||
{ |
||||
if (s1.size() != s2.size()) return false; |
||||
for (size_t i = 0; i < s1.size(); ++i) { |
||||
char c1 = s1[i]; |
||||
if (c1 >= 'A' && c1 <= 'Z') c1 -= ('A' - 'a'); |
||||
char c2 = s2[i]; |
||||
if (c2 >= 'A' && c2 <= 'Z') c2 -= ('A' - 'a'); |
||||
if (c1 != c2) return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
BOOST_AUTO_TEST_CASE(bip173_testvectors_valid) |
||||
{ |
||||
static const std::string CASES[] = { |
||||
"A12UEL5L", |
||||
"a12uel5l", |
||||
"an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs", |
||||
"abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw", |
||||
"11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j", |
||||
"split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w", |
||||
"?1ezyfcl", |
||||
}; |
||||
for (const std::string& str : CASES) { |
||||
auto ret = bech32::Decode(str); |
||||
BOOST_CHECK(!ret.first.empty()); |
||||
std::string recode = bech32::Encode(ret.first, ret.second); |
||||
BOOST_CHECK(!recode.empty()); |
||||
BOOST_CHECK(CaseInsensitiveEqual(str, recode)); |
||||
} |
||||
} |
||||
|
||||
BOOST_AUTO_TEST_CASE(bip173_testvectors_invalid) |
||||
{ |
||||
static const std::string CASES[] = { |
||||
" 1nwldj5", |
||||
"\x7f""1axkwrx", |
||||
"\x80""1eym55h", |
||||
"an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx", |
||||
"pzry9x0s0muk", |
||||
"1pzry9x0s0muk", |
||||
"x1b4n0q5v", |
||||
"li1dgmt3", |
||||
"de1lg7wt\xff", |
||||
"A1G7SGD8", |
||||
"10a06t8", |
||||
"1qzzfhee", |
||||
}; |
||||
for (const std::string& str : CASES) { |
||||
auto ret = bech32::Decode(str); |
||||
BOOST_CHECK(ret.first.empty()); |
||||
} |
||||
} |
||||
|
||||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,452 +1,533 @@
@@ -1,452 +1,533 @@
|
||||
[ |
||||
[ |
||||
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", |
||||
"65a16059864a2fdbc7c99a4723a8395bc6f188eb", |
||||
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", |
||||
"76a91465a16059864a2fdbc7c99a4723a8395bc6f188eb88ac", |
||||
{ |
||||
"addrType": "pubkey", |
||||
"isPrivkey": false, |
||||
"isTestnet": false |
||||
"isPrivkey": false, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou", |
||||
"74f209f6ea907e2ea48f74fae05782ae8a665257", |
||||
"3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou", |
||||
"a91474f209f6ea907e2ea48f74fae05782ae8a66525787", |
||||
{ |
||||
"addrType": "script", |
||||
"isPrivkey": false, |
||||
"isTestnet": false |
||||
"isPrivkey": false, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", |
||||
"53c0307d6851aa0ce7825ba883c6bd9ad242b486", |
||||
"mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", |
||||
"76a91453c0307d6851aa0ce7825ba883c6bd9ad242b48688ac", |
||||
{ |
||||
"addrType": "pubkey", |
||||
"isPrivkey": false, |
||||
"isTestnet": true |
||||
"isPrivkey": false, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", |
||||
"6349a418fc4578d10a372b54b45c280cc8c4382f", |
||||
"mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", |
||||
"76a91453c0307d6851aa0ce7825ba883c6bd9ad242b48688ac", |
||||
{ |
||||
"addrType": "script", |
||||
"isPrivkey": false, |
||||
"isTestnet": true |
||||
"isPrivkey": false, |
||||
"chain": "regtest" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"5Kd3NBUAdUnhyzenEwVLy9pBKxSwXvE9FMPyR4UKZvpe6E3AgLr", |
||||
"eddbdc1168f1daeadbd3e44c1e3f8f5a284c2029f78ad26af98583a499de5b19", |
||||
"2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", |
||||
"a9146349a418fc4578d10a372b54b45c280cc8c4382f87", |
||||
{ |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"isTestnet": false |
||||
"isPrivkey": false, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"Kz6UJmQACJmLtaQj5A3JAge4kVTNQ8gbvXuwbmCj7bsaabudb3RD", |
||||
"55c9bccb9ed68446d1b75273bbce89d7fe013a8acd1625514420fb2aca1a21c4", |
||||
"5Kd3NBUAdUnhyzenEwVLy9pBKxSwXvE9FMPyR4UKZvpe6E3AgLr", |
||||
"eddbdc1168f1daeadbd3e44c1e3f8f5a284c2029f78ad26af98583a499de5b19", |
||||
{ |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"isTestnet": false |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"9213qJab2HNEpMpYNBa7wHGFKKbkDn24jpANDs2huN3yi4J11ko", |
||||
"36cb93b9ab1bdabf7fb9f2c04f1b9cc879933530ae7842398eef5a63a56800c2", |
||||
"Kz6UJmQACJmLtaQj5A3JAge4kVTNQ8gbvXuwbmCj7bsaabudb3RD", |
||||
"55c9bccb9ed68446d1b75273bbce89d7fe013a8acd1625514420fb2aca1a21c4", |
||||
{ |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"isTestnet": true |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"cTpB4YiyKiBcPxnefsDpbnDxFDffjqJob8wGCEDXxgQ7zQoMXJdH", |
||||
"b9f4892c9e8282028fea1d2667c4dc5213564d41fc5783896a0d843fc15089f3", |
||||
"9213qJab2HNEpMpYNBa7wHGFKKbkDn24jpANDs2huN3yi4J11ko", |
||||
"36cb93b9ab1bdabf7fb9f2c04f1b9cc879933530ae7842398eef5a63a56800c2", |
||||
{ |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"isTestnet": true |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"1Ax4gZtb7gAit2TivwejZHYtNNLT18PUXJ", |
||||
"6d23156cbbdcc82a5a47eee4c2c7c583c18b6bf4", |
||||
"9213qJab2HNEpMpYNBa7wHGFKKbkDn24jpANDs2huN3yi4J11ko", |
||||
"36cb93b9ab1bdabf7fb9f2c04f1b9cc879933530ae7842398eef5a63a56800c2", |
||||
{ |
||||
"addrType": "pubkey", |
||||
"isPrivkey": false, |
||||
"isTestnet": false |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"chain": "regtest" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"3QjYXhTkvuj8qPaXHTTWb5wjXhdsLAAWVy", |
||||
"fcc5460dd6e2487c7d75b1963625da0e8f4c5975", |
||||
"cTpB4YiyKiBcPxnefsDpbnDxFDffjqJob8wGCEDXxgQ7zQoMXJdH", |
||||
"b9f4892c9e8282028fea1d2667c4dc5213564d41fc5783896a0d843fc15089f3", |
||||
{ |
||||
"addrType": "script", |
||||
"isPrivkey": false, |
||||
"isTestnet": false |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"n3ZddxzLvAY9o7184TB4c6FJasAybsw4HZ", |
||||
"f1d470f9b02370fdec2e6b708b08ac431bf7a5f7", |
||||
"cTpB4YiyKiBcPxnefsDpbnDxFDffjqJob8wGCEDXxgQ7zQoMXJdH", |
||||
"b9f4892c9e8282028fea1d2667c4dc5213564d41fc5783896a0d843fc15089f3", |
||||
{ |
||||
"addrType": "pubkey", |
||||
"isPrivkey": false, |
||||
"isTestnet": true |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"chain": "regtest" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n", |
||||
"c579342c2c4c9220205e2cdc285617040c924a0a", |
||||
"1Ax4gZtb7gAit2TivwejZHYtNNLT18PUXJ", |
||||
"76a9146d23156cbbdcc82a5a47eee4c2c7c583c18b6bf488ac", |
||||
{ |
||||
"addrType": "script", |
||||
"isPrivkey": false, |
||||
"isTestnet": true |
||||
"isPrivkey": false, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"5K494XZwps2bGyeL71pWid4noiSNA2cfCibrvRWqcHSptoFn7rc", |
||||
"a326b95ebae30164217d7a7f57d72ab2b54e3be64928a19da0210b9568d4015e", |
||||
"3QjYXhTkvuj8qPaXHTTWb5wjXhdsLAAWVy", |
||||
"a914fcc5460dd6e2487c7d75b1963625da0e8f4c597587", |
||||
{ |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"isTestnet": false |
||||
"isPrivkey": false, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"L1RrrnXkcKut5DEMwtDthjwRcTTwED36thyL1DebVrKuwvohjMNi", |
||||
"7d998b45c219a1e38e99e7cbd312ef67f77a455a9b50c730c27f02c6f730dfb4", |
||||
"n3ZddxzLvAY9o7184TB4c6FJasAybsw4HZ", |
||||
"76a914f1d470f9b02370fdec2e6b708b08ac431bf7a5f788ac", |
||||
{ |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"isTestnet": false |
||||
"isPrivkey": false, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"93DVKyFYwSN6wEo3E2fCrFPUp17FtrtNi2Lf7n4G3garFb16CRj", |
||||
"d6bca256b5abc5602ec2e1c121a08b0da2556587430bcf7e1898af2224885203", |
||||
"2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n", |
||||
"a914c579342c2c4c9220205e2cdc285617040c924a0a87", |
||||
{ |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"isTestnet": true |
||||
"isPrivkey": false, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"cTDVKtMGVYWTHCb1AFjmVbEbWjvKpKqKgMaR3QJxToMSQAhmCeTN", |
||||
"a81ca4e8f90181ec4b61b6a7eb998af17b2cb04de8a03b504b9e34c4c61db7d9", |
||||
"5K494XZwps2bGyeL71pWid4noiSNA2cfCibrvRWqcHSptoFn7rc", |
||||
"a326b95ebae30164217d7a7f57d72ab2b54e3be64928a19da0210b9568d4015e", |
||||
{ |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"isTestnet": true |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"1C5bSj1iEGUgSTbziymG7Cn18ENQuT36vv", |
||||
"7987ccaa53d02c8873487ef919677cd3db7a6912", |
||||
"L1RrrnXkcKut5DEMwtDthjwRcTTwED36thyL1DebVrKuwvohjMNi", |
||||
"7d998b45c219a1e38e99e7cbd312ef67f77a455a9b50c730c27f02c6f730dfb4", |
||||
{ |
||||
"addrType": "pubkey", |
||||
"isPrivkey": false, |
||||
"isTestnet": false |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"3AnNxabYGoTxYiTEZwFEnerUoeFXK2Zoks", |
||||
"63bcc565f9e68ee0189dd5cc67f1b0e5f02f45cb", |
||||
"93DVKyFYwSN6wEo3E2fCrFPUp17FtrtNi2Lf7n4G3garFb16CRj", |
||||
"d6bca256b5abc5602ec2e1c121a08b0da2556587430bcf7e1898af2224885203", |
||||
{ |
||||
"addrType": "script", |
||||
"isPrivkey": false, |
||||
"isTestnet": false |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"n3LnJXCqbPjghuVs8ph9CYsAe4Sh4j97wk", |
||||
"ef66444b5b17f14e8fae6e7e19b045a78c54fd79", |
||||
"cTDVKtMGVYWTHCb1AFjmVbEbWjvKpKqKgMaR3QJxToMSQAhmCeTN", |
||||
"a81ca4e8f90181ec4b61b6a7eb998af17b2cb04de8a03b504b9e34c4c61db7d9", |
||||
{ |
||||
"addrType": "pubkey", |
||||
"isPrivkey": false, |
||||
"isTestnet": true |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"2NB72XtkjpnATMggui83aEtPawyyKvnbX2o", |
||||
"c3e55fceceaa4391ed2a9677f4a4d34eacd021a0", |
||||
"1C5bSj1iEGUgSTbziymG7Cn18ENQuT36vv", |
||||
"76a9147987ccaa53d02c8873487ef919677cd3db7a691288ac", |
||||
{ |
||||
"addrType": "script", |
||||
"isPrivkey": false, |
||||
"isTestnet": true |
||||
"isPrivkey": false, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"5KaBW9vNtWNhc3ZEDyNCiXLPdVPHCikRxSBWwV9NrpLLa4LsXi9", |
||||
"e75d936d56377f432f404aabb406601f892fd49da90eb6ac558a733c93b47252", |
||||
"3AnNxabYGoTxYiTEZwFEnerUoeFXK2Zoks", |
||||
"a91463bcc565f9e68ee0189dd5cc67f1b0e5f02f45cb87", |
||||
{ |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"isTestnet": false |
||||
"isPrivkey": false, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"L1axzbSyynNYA8mCAhzxkipKkfHtAXYF4YQnhSKcLV8YXA874fgT", |
||||
"8248bd0375f2f75d7e274ae544fb920f51784480866b102384190b1addfbaa5c", |
||||
"n3LnJXCqbPjghuVs8ph9CYsAe4Sh4j97wk", |
||||
"76a914ef66444b5b17f14e8fae6e7e19b045a78c54fd7988ac", |
||||
{ |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"isTestnet": false |
||||
"isPrivkey": false, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"927CnUkUbasYtDwYwVn2j8GdTuACNnKkjZ1rpZd2yBB1CLcnXpo", |
||||
"44c4f6a096eac5238291a94cc24c01e3b19b8d8cef72874a079e00a242237a52", |
||||
"2NB72XtkjpnATMggui83aEtPawyyKvnbX2o", |
||||
"a914c3e55fceceaa4391ed2a9677f4a4d34eacd021a087", |
||||
{ |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"isTestnet": true |
||||
"isPrivkey": false, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"cUcfCMRjiQf85YMzzQEk9d1s5A4K7xL5SmBCLrezqXFuTVefyhY7", |
||||
"d1de707020a9059d6d3abaf85e17967c6555151143db13dbb06db78df0f15c69", |
||||
"5KaBW9vNtWNhc3ZEDyNCiXLPdVPHCikRxSBWwV9NrpLLa4LsXi9", |
||||
"e75d936d56377f432f404aabb406601f892fd49da90eb6ac558a733c93b47252", |
||||
{ |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"isTestnet": true |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"1Gqk4Tv79P91Cc1STQtU3s1W6277M2CVWu", |
||||
"adc1cc2081a27206fae25792f28bbc55b831549d", |
||||
"L1axzbSyynNYA8mCAhzxkipKkfHtAXYF4YQnhSKcLV8YXA874fgT", |
||||
"8248bd0375f2f75d7e274ae544fb920f51784480866b102384190b1addfbaa5c", |
||||
{ |
||||
"addrType": "pubkey", |
||||
"isPrivkey": false, |
||||
"isTestnet": false |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"33vt8ViH5jsr115AGkW6cEmEz9MpvJSwDk", |
||||
"188f91a931947eddd7432d6e614387e32b244709", |
||||
"927CnUkUbasYtDwYwVn2j8GdTuACNnKkjZ1rpZd2yBB1CLcnXpo", |
||||
"44c4f6a096eac5238291a94cc24c01e3b19b8d8cef72874a079e00a242237a52", |
||||
{ |
||||
"addrType": "script", |
||||
"isPrivkey": false, |
||||
"isTestnet": false |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"mhaMcBxNh5cqXm4aTQ6EcVbKtfL6LGyK2H", |
||||
"1694f5bc1a7295b600f40018a618a6ea48eeb498", |
||||
"cUcfCMRjiQf85YMzzQEk9d1s5A4K7xL5SmBCLrezqXFuTVefyhY7", |
||||
"d1de707020a9059d6d3abaf85e17967c6555151143db13dbb06db78df0f15c69", |
||||
{ |
||||
"addrType": "pubkey", |
||||
"isPrivkey": false, |
||||
"isTestnet": true |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"2MxgPqX1iThW3oZVk9KoFcE5M4JpiETssVN", |
||||
"3b9b3fd7a50d4f08d1a5b0f62f644fa7115ae2f3", |
||||
"1Gqk4Tv79P91Cc1STQtU3s1W6277M2CVWu", |
||||
"76a914adc1cc2081a27206fae25792f28bbc55b831549d88ac", |
||||
{ |
||||
"addrType": "script", |
||||
"isPrivkey": false, |
||||
"isTestnet": true |
||||
"isPrivkey": false, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"5HtH6GdcwCJA4ggWEL1B3jzBBUB8HPiBi9SBc5h9i4Wk4PSeApR", |
||||
"091035445ef105fa1bb125eccfb1882f3fe69592265956ade751fd095033d8d0", |
||||
"33vt8ViH5jsr115AGkW6cEmEz9MpvJSwDk", |
||||
"a914188f91a931947eddd7432d6e614387e32b24470987", |
||||
{ |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"isTestnet": false |
||||
"isPrivkey": false, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"L2xSYmMeVo3Zek3ZTsv9xUrXVAmrWxJ8Ua4cw8pkfbQhcEFhkXT8", |
||||
"ab2b4bcdfc91d34dee0ae2a8c6b6668dadaeb3a88b9859743156f462325187af", |
||||
"mhaMcBxNh5cqXm4aTQ6EcVbKtfL6LGyK2H", |
||||
"76a9141694f5bc1a7295b600f40018a618a6ea48eeb49888ac", |
||||
{ |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"isTestnet": false |
||||
"isPrivkey": false, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"92xFEve1Z9N8Z641KQQS7ByCSb8kGjsDzw6fAmjHN1LZGKQXyMq", |
||||
"b4204389cef18bbe2b353623cbf93e8678fbc92a475b664ae98ed594e6cf0856", |
||||
"2MxgPqX1iThW3oZVk9KoFcE5M4JpiETssVN", |
||||
"a9143b9b3fd7a50d4f08d1a5b0f62f644fa7115ae2f387", |
||||
{ |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"isTestnet": true |
||||
"isPrivkey": false, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"cVM65tdYu1YK37tNoAyGoJTR13VBYFva1vg9FLuPAsJijGvG6NEA", |
||||
"e7b230133f1b5489843260236b06edca25f66adb1be455fbd38d4010d48faeef", |
||||
"5HtH6GdcwCJA4ggWEL1B3jzBBUB8HPiBi9SBc5h9i4Wk4PSeApR", |
||||
"091035445ef105fa1bb125eccfb1882f3fe69592265956ade751fd095033d8d0", |
||||
{ |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"isTestnet": true |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"1JwMWBVLtiqtscbaRHai4pqHokhFCbtoB4", |
||||
"c4c1b72491ede1eedaca00618407ee0b772cad0d", |
||||
"L2xSYmMeVo3Zek3ZTsv9xUrXVAmrWxJ8Ua4cw8pkfbQhcEFhkXT8", |
||||
"ab2b4bcdfc91d34dee0ae2a8c6b6668dadaeb3a88b9859743156f462325187af", |
||||
{ |
||||
"addrType": "pubkey", |
||||
"isPrivkey": false, |
||||
"isTestnet": false |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"3QCzvfL4ZRvmJFiWWBVwxfdaNBT8EtxB5y", |
||||
"f6fe69bcb548a829cce4c57bf6fff8af3a5981f9", |
||||
"92xFEve1Z9N8Z641KQQS7ByCSb8kGjsDzw6fAmjHN1LZGKQXyMq", |
||||
"b4204389cef18bbe2b353623cbf93e8678fbc92a475b664ae98ed594e6cf0856", |
||||
{ |
||||
"addrType": "script", |
||||
"isPrivkey": false, |
||||
"isTestnet": false |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"mizXiucXRCsEriQCHUkCqef9ph9qtPbZZ6", |
||||
"261f83568a098a8638844bd7aeca039d5f2352c0", |
||||
"92xFEve1Z9N8Z641KQQS7ByCSb8kGjsDzw6fAmjHN1LZGKQXyMq", |
||||
"b4204389cef18bbe2b353623cbf93e8678fbc92a475b664ae98ed594e6cf0856", |
||||
{ |
||||
"addrType": "pubkey", |
||||
"isPrivkey": false, |
||||
"isTestnet": true |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"chain": "regtest" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"2NEWDzHWwY5ZZp8CQWbB7ouNMLqCia6YRda", |
||||
"e930e1834a4d234702773951d627cce82fbb5d2e", |
||||
"cVM65tdYu1YK37tNoAyGoJTR13VBYFva1vg9FLuPAsJijGvG6NEA", |
||||
"e7b230133f1b5489843260236b06edca25f66adb1be455fbd38d4010d48faeef", |
||||
{ |
||||
"addrType": "script", |
||||
"isPrivkey": false, |
||||
"isTestnet": true |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"5KQmDryMNDcisTzRp3zEq9e4awRmJrEVU1j5vFRTKpRNYPqYrMg", |
||||
"d1fab7ab7385ad26872237f1eb9789aa25cc986bacc695e07ac571d6cdac8bc0", |
||||
"1JwMWBVLtiqtscbaRHai4pqHokhFCbtoB4", |
||||
"76a914c4c1b72491ede1eedaca00618407ee0b772cad0d88ac", |
||||
{ |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"isTestnet": false |
||||
"isPrivkey": false, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"L39Fy7AC2Hhj95gh3Yb2AU5YHh1mQSAHgpNixvm27poizcJyLtUi", |
||||
"b0bbede33ef254e8376aceb1510253fc3550efd0fcf84dcd0c9998b288f166b3", |
||||
"3QCzvfL4ZRvmJFiWWBVwxfdaNBT8EtxB5y", |
||||
"a914f6fe69bcb548a829cce4c57bf6fff8af3a5981f987", |
||||
{ |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"isTestnet": false |
||||
"isPrivkey": false, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"91cTVUcgydqyZLgaANpf1fvL55FH53QMm4BsnCADVNYuWuqdVys", |
||||
"037f4192c630f399d9271e26c575269b1d15be553ea1a7217f0cb8513cef41cb", |
||||
"mizXiucXRCsEriQCHUkCqef9ph9qtPbZZ6", |
||||
"76a914261f83568a098a8638844bd7aeca039d5f2352c088ac", |
||||
{ |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"isTestnet": true |
||||
"isPrivkey": false, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"cQspfSzsgLeiJGB2u8vrAiWpCU4MxUT6JseWo2SjXy4Qbzn2fwDw", |
||||
"6251e205e8ad508bab5596bee086ef16cd4b239e0cc0c5d7c4e6035441e7d5de", |
||||
"2NEWDzHWwY5ZZp8CQWbB7ouNMLqCia6YRda", |
||||
"a914e930e1834a4d234702773951d627cce82fbb5d2e87", |
||||
{ |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"isTestnet": true |
||||
"isPrivkey": false, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"19dcawoKcZdQz365WpXWMhX6QCUpR9SY4r", |
||||
"5eadaf9bb7121f0f192561a5a62f5e5f54210292", |
||||
"5KQmDryMNDcisTzRp3zEq9e4awRmJrEVU1j5vFRTKpRNYPqYrMg", |
||||
"d1fab7ab7385ad26872237f1eb9789aa25cc986bacc695e07ac571d6cdac8bc0", |
||||
{ |
||||
"addrType": "pubkey", |
||||
"isPrivkey": false, |
||||
"isTestnet": false |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"37Sp6Rv3y4kVd1nQ1JV5pfqXccHNyZm1x3", |
||||
"3f210e7277c899c3a155cc1c90f4106cbddeec6e", |
||||
"L39Fy7AC2Hhj95gh3Yb2AU5YHh1mQSAHgpNixvm27poizcJyLtUi", |
||||
"b0bbede33ef254e8376aceb1510253fc3550efd0fcf84dcd0c9998b288f166b3", |
||||
{ |
||||
"addrType": "script", |
||||
"isPrivkey": false, |
||||
"isTestnet": false |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"myoqcgYiehufrsnnkqdqbp69dddVDMopJu", |
||||
"c8a3c2a09a298592c3e180f02487cd91ba3400b5", |
||||
"91cTVUcgydqyZLgaANpf1fvL55FH53QMm4BsnCADVNYuWuqdVys", |
||||
"037f4192c630f399d9271e26c575269b1d15be553ea1a7217f0cb8513cef41cb", |
||||
{ |
||||
"addrType": "pubkey", |
||||
"isPrivkey": false, |
||||
"isTestnet": true |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"2N7FuwuUuoTBrDFdrAZ9KxBmtqMLxce9i1C", |
||||
"99b31df7c9068d1481b596578ddbb4d3bd90baeb", |
||||
"cQspfSzsgLeiJGB2u8vrAiWpCU4MxUT6JseWo2SjXy4Qbzn2fwDw", |
||||
"6251e205e8ad508bab5596bee086ef16cd4b239e0cc0c5d7c4e6035441e7d5de", |
||||
{ |
||||
"addrType": "script", |
||||
"isPrivkey": false, |
||||
"isTestnet": true |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"5KL6zEaMtPRXZKo1bbMq7JDjjo1bJuQcsgL33je3oY8uSJCR5b4", |
||||
"c7666842503db6dc6ea061f092cfb9c388448629a6fe868d068c42a488b478ae", |
||||
"19dcawoKcZdQz365WpXWMhX6QCUpR9SY4r", |
||||
"76a9145eadaf9bb7121f0f192561a5a62f5e5f5421029288ac", |
||||
{ |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"isTestnet": false |
||||
"isPrivkey": false, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"KwV9KAfwbwt51veZWNscRTeZs9CKpojyu1MsPnaKTF5kz69H1UN2", |
||||
"07f0803fc5399e773555ab1e8939907e9badacc17ca129e67a2f5f2ff84351dd", |
||||
"37Sp6Rv3y4kVd1nQ1JV5pfqXccHNyZm1x3", |
||||
"a9143f210e7277c899c3a155cc1c90f4106cbddeec6e87", |
||||
{ |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"isTestnet": false |
||||
"isPrivkey": false, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"93N87D6uxSBzwXvpokpzg8FFmfQPmvX4xHoWQe3pLdYpbiwT5YV", |
||||
"ea577acfb5d1d14d3b7b195c321566f12f87d2b77ea3a53f68df7ebf8604a801", |
||||
"myoqcgYiehufrsnnkqdqbp69dddVDMopJu", |
||||
"76a914c8a3c2a09a298592c3e180f02487cd91ba3400b588ac", |
||||
{ |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"isTestnet": true |
||||
"isPrivkey": false, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"cMxXusSihaX58wpJ3tNuuUcZEQGt6DKJ1wEpxys88FFaQCYjku9h", |
||||
"0b3b34f0958d8a268193a9814da92c3e8b58b4a4378a542863e34ac289cd830c", |
||||
"2N7FuwuUuoTBrDFdrAZ9KxBmtqMLxce9i1C", |
||||
"a91499b31df7c9068d1481b596578ddbb4d3bd90baeb87", |
||||
{ |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"isTestnet": true |
||||
"isPrivkey": false, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"13p1ijLwsnrcuyqcTvJXkq2ASdXqcnEBLE", |
||||
"1ed467017f043e91ed4c44b4e8dd674db211c4e6", |
||||
"5KL6zEaMtPRXZKo1bbMq7JDjjo1bJuQcsgL33je3oY8uSJCR5b4", |
||||
"c7666842503db6dc6ea061f092cfb9c388448629a6fe868d068c42a488b478ae", |
||||
{ |
||||
"addrType": "pubkey", |
||||
"isPrivkey": false, |
||||
"isTestnet": false |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
], |
||||
[ |
||||
"3ALJH9Y951VCGcVZYAdpA3KchoP9McEj1G", |
||||
"5ece0cadddc415b1980f001785947120acdb36fc", |
||||
"KwV9KAfwbwt51veZWNscRTeZs9CKpojyu1MsPnaKTF5kz69H1UN2", |
||||
"07f0803fc5399e773555ab1e8939907e9badacc17ca129e67a2f5f2ff84351dd", |
||||
{ |
||||
"addrType": "script", |
||||
"isPrivkey": false, |
||||
"isTestnet": false |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
[ |
||||
"93N87D6uxSBzwXvpokpzg8FFmfQPmvX4xHoWQe3pLdYpbiwT5YV", |
||||
"ea577acfb5d1d14d3b7b195c321566f12f87d2b77ea3a53f68df7ebf8604a801", |
||||
{ |
||||
"isCompressed": false, |
||||
"isPrivkey": true, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
[ |
||||
"cMxXusSihaX58wpJ3tNuuUcZEQGt6DKJ1wEpxys88FFaQCYjku9h", |
||||
"0b3b34f0958d8a268193a9814da92c3e8b58b4a4378a542863e34ac289cd830c", |
||||
{ |
||||
"isCompressed": true, |
||||
"isPrivkey": true, |
||||
"chain": "test" |
||||
} |
||||
], |
||||
[ |
||||
"13p1ijLwsnrcuyqcTvJXkq2ASdXqcnEBLE", |
||||
"76a9141ed467017f043e91ed4c44b4e8dd674db211c4e688ac", |
||||
{ |
||||
"isPrivkey": false, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
[ |
||||
"3ALJH9Y951VCGcVZYAdpA3KchoP9McEj1G", |
||||
"a9145ece0cadddc415b1980f001785947120acdb36fc87", |
||||
{ |
||||
"isPrivkey": false, |
||||
"chain": "main" |
||||
} |
||||
], |
||||
[ |
||||
"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4", |
||||
"0014751e76e8199196d454941c45d1b3a323f1433bd6", |
||||
{ |
||||
"isPrivkey": false, |
||||
"chain": "main", |
||||
"tryCaseFlip": true |
||||
} |
||||
], |
||||
[ |
||||
"bcrt1qw508d6qejxtdg4y5r3zarvary0c5xw7kygt080", |
||||
"0014751e76e8199196d454941c45d1b3a323f1433bd6", |
||||
{ |
||||
"isPrivkey": false, |
||||
"chain": "regtest", |
||||
"tryCaseFlip": true |
||||
} |
||||
], |
||||
[ |
||||
"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7", |
||||
"00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262", |
||||
{ |
||||
"isPrivkey": false, |
||||
"chain": "test", |
||||
"tryCaseFlip": true |
||||
} |
||||
], |
||||
[ |
||||
"bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx", |
||||
"5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6", |
||||
{ |
||||
"isPrivkey": false, |
||||
"chain": "main", |
||||
"tryCaseFlip": true |
||||
} |
||||
], |
||||
[ |
||||
"bc1sw50qa3jx3s", |
||||
"6002751e", |
||||
{ |
||||
"isPrivkey": false, |
||||
"chain": "main", |
||||
"tryCaseFlip": true |
||||
} |
||||
], |
||||
[ |
||||
"bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj", |
||||
"5210751e76e8199196d454941c45d1b3a323", |
||||
{ |
||||
"isPrivkey": false, |
||||
"chain": "main", |
||||
"tryCaseFlip": true |
||||
} |
||||
], |
||||
[ |
||||
"tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy", |
||||
"0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433", |
||||
{ |
||||
"isPrivkey": false, |
||||
"chain": "test", |
||||
"tryCaseFlip": true |
||||
} |
||||
], |
||||
[ |
||||
"bcrt1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvseswlauz7", |
||||
"0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433", |
||||
{ |
||||
"isPrivkey": false, |
||||
"chain": "regtest", |
||||
"tryCaseFlip": true |
||||
} |
||||
] |
||||
] |
||||
|
@ -0,0 +1,107 @@
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/env python3 |
||||
# Copyright (c) 2017 Pieter Wuille |
||||
# Distributed under the MIT software license, see the accompanying |
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. |
||||
"""Reference implementation for Bech32 and segwit addresses.""" |
||||
|
||||
|
||||
CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l" |
||||
|
||||
|
||||
def bech32_polymod(values): |
||||
"""Internal function that computes the Bech32 checksum.""" |
||||
generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3] |
||||
chk = 1 |
||||
for value in values: |
||||
top = chk >> 25 |
||||
chk = (chk & 0x1ffffff) << 5 ^ value |
||||
for i in range(5): |
||||
chk ^= generator[i] if ((top >> i) & 1) else 0 |
||||
return chk |
||||
|
||||
|
||||
def bech32_hrp_expand(hrp): |
||||
"""Expand the HRP into values for checksum computation.""" |
||||
return [ord(x) >> 5 for x in hrp] + [0] + [ord(x) & 31 for x in hrp] |
||||
|
||||
|
||||
def bech32_verify_checksum(hrp, data): |
||||
"""Verify a checksum given HRP and converted data characters.""" |
||||
return bech32_polymod(bech32_hrp_expand(hrp) + data) == 1 |
||||
|
||||
|
||||
def bech32_create_checksum(hrp, data): |
||||
"""Compute the checksum values given HRP and data.""" |
||||
values = bech32_hrp_expand(hrp) + data |
||||
polymod = bech32_polymod(values + [0, 0, 0, 0, 0, 0]) ^ 1 |
||||
return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)] |
||||
|
||||
|
||||
def bech32_encode(hrp, data): |
||||
"""Compute a Bech32 string given HRP and data values.""" |
||||
combined = data + bech32_create_checksum(hrp, data) |
||||
return hrp + '1' + ''.join([CHARSET[d] for d in combined]) |
||||
|
||||
|
||||
def bech32_decode(bech): |
||||
"""Validate a Bech32 string, and determine HRP and data.""" |
||||
if ((any(ord(x) < 33 or ord(x) > 126 for x in bech)) or |
||||
(bech.lower() != bech and bech.upper() != bech)): |
||||
return (None, None) |
||||
bech = bech.lower() |
||||
pos = bech.rfind('1') |
||||
if pos < 1 or pos + 7 > len(bech) or len(bech) > 90: |
||||
return (None, None) |
||||
if not all(x in CHARSET for x in bech[pos+1:]): |
||||
return (None, None) |
||||
hrp = bech[:pos] |
||||
data = [CHARSET.find(x) for x in bech[pos+1:]] |
||||
if not bech32_verify_checksum(hrp, data): |
||||
return (None, None) |
||||
return (hrp, data[:-6]) |
||||
|
||||
|
||||
def convertbits(data, frombits, tobits, pad=True): |
||||
"""General power-of-2 base conversion.""" |
||||
acc = 0 |
||||
bits = 0 |
||||
ret = [] |
||||
maxv = (1 << tobits) - 1 |
||||
max_acc = (1 << (frombits + tobits - 1)) - 1 |
||||
for value in data: |
||||
if value < 0 or (value >> frombits): |
||||
return None |
||||
acc = ((acc << frombits) | value) & max_acc |
||||
bits += frombits |
||||
while bits >= tobits: |
||||
bits -= tobits |
||||
ret.append((acc >> bits) & maxv) |
||||
if pad: |
||||
if bits: |
||||
ret.append((acc << (tobits - bits)) & maxv) |
||||
elif bits >= frombits or ((acc << (tobits - bits)) & maxv): |
||||
return None |
||||
return ret |
||||
|
||||
|
||||
def decode(hrp, addr): |
||||
"""Decode a segwit address.""" |
||||
hrpgot, data = bech32_decode(addr) |
||||
if hrpgot != hrp: |
||||
return (None, None) |
||||
decoded = convertbits(data[1:], 5, 8, False) |
||||
if decoded is None or len(decoded) < 2 or len(decoded) > 40: |
||||
return (None, None) |
||||
if data[0] > 16: |
||||
return (None, None) |
||||
if data[0] == 0 and len(decoded) != 20 and len(decoded) != 32: |
||||
return (None, None) |
||||
return (data[0], decoded) |
||||
|
||||
|
||||
def encode(hrp, witver, witprog): |
||||
"""Encode a segwit address.""" |
||||
ret = bech32_encode(hrp, [witver] + convertbits(witprog, 8, 5)) |
||||
if decode(hrp, ret) == (None, None): |
||||
return None |
||||
return ret |
Loading…
Reference in new issue