|
5 | 5 | """Encode and decode BASE58, P2PKH and P2SH addresses."""
|
6 | 6 |
|
7 | 7 | import enum
|
| 8 | +import unittest |
8 | 9 |
|
9 | 10 | from .script import hash256, hash160, sha256, CScript, OP_0
|
10 | 11 | from .util import hex_str_to_bytes
|
11 | 12 |
|
12 | 13 | from . import segwit_addr
|
13 | 14 |
|
| 15 | +from test_framework.util import assert_equal |
| 16 | + |
14 | 17 | ADDRESS_BCRT1_UNSPENDABLE = 'bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj'
|
15 | 18 | ADDRESS_BCRT1_UNSPENDABLE_DESCRIPTOR = 'addr(bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj)#juyq9d97'
|
16 | 19 | # Coins sent to this address can be spent with a witness stack of just OP_TRUE
|
@@ -41,7 +44,32 @@ def byte_to_base58(b, version):
|
41 | 44 | str = str[2:]
|
42 | 45 | return result
|
43 | 46 |
|
44 |
| -# TODO: def base58_decode |
| 47 | + |
| 48 | +def base58_to_byte(s, verify_checksum=True): |
| 49 | + if not s: |
| 50 | + return b'' |
| 51 | + n = 0 |
| 52 | + for c in s: |
| 53 | + n *= 58 |
| 54 | + assert c in chars |
| 55 | + digit = chars.index(c) |
| 56 | + n += digit |
| 57 | + h = '%x' % n |
| 58 | + if len(h) % 2: |
| 59 | + h = '0' + h |
| 60 | + res = n.to_bytes((n.bit_length() + 7) // 8, 'big') |
| 61 | + pad = 0 |
| 62 | + for c in s: |
| 63 | + if c == chars[0]: |
| 64 | + pad += 1 |
| 65 | + else: |
| 66 | + break |
| 67 | + res = b'\x00' * pad + res |
| 68 | + if verify_checksum: |
| 69 | + assert_equal(hash256(res[:-4])[:4], res[-4:]) |
| 70 | + |
| 71 | + return res[1:-4], int(res[0]) |
| 72 | + |
45 | 73 |
|
46 | 74 | def keyhash_to_p2pkh(hash, main = False):
|
47 | 75 | assert len(hash) == 20
|
@@ -100,3 +128,22 @@ def check_script(script):
|
100 | 128 | if (type(script) is bytes or type(script) is CScript):
|
101 | 129 | return script
|
102 | 130 | assert False
|
| 131 | + |
| 132 | + |
| 133 | +class TestFrameworkScript(unittest.TestCase): |
| 134 | + def test_base58encodedecode(self): |
| 135 | + def check_base58(data, version): |
| 136 | + self.assertEqual(base58_to_byte(byte_to_base58(data, version)), (data, version)) |
| 137 | + |
| 138 | + check_base58(b'\x1f\x8e\xa1p*{\xd4\x94\x1b\xca\tA\xb8R\xc4\xbb\xfe\xdb.\x05', 111) |
| 139 | + check_base58(b':\x0b\x05\xf4\xd7\xf6l;\xa7\x00\x9fE50)l\x84\\\xc9\xcf', 111) |
| 140 | + check_base58(b'A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111) |
| 141 | + check_base58(b'\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111) |
| 142 | + check_base58(b'\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111) |
| 143 | + check_base58(b'\0\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111) |
| 144 | + check_base58(b'\x1f\x8e\xa1p*{\xd4\x94\x1b\xca\tA\xb8R\xc4\xbb\xfe\xdb.\x05', 0) |
| 145 | + check_base58(b':\x0b\x05\xf4\xd7\xf6l;\xa7\x00\x9fE50)l\x84\\\xc9\xcf', 0) |
| 146 | + check_base58(b'A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0) |
| 147 | + check_base58(b'\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0) |
| 148 | + check_base58(b'\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0) |
| 149 | + check_base58(b'\0\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0) |
0 commit comments