From aac8793c7a2ee7630641dd74be6ba2ead50c2aee Mon Sep 17 00:00:00 2001 From: ismaelsadeeq Date: Thu, 23 Mar 2023 11:59:29 +0100 Subject: [PATCH 1/2] test: test_bech32_decode in address.py Adds bech32_to_bytes() which can decode a bech32 address and return the version as an `int` and the payload in bytes. bech32_to_bytes() is used by the test_bech32_decode unit test to test decoding of segwit addresses. --- test/functional/test_framework/address.py | 30 ++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/test/functional/test_framework/address.py b/test/functional/test_framework/address.py index 959a2a65bd0..d1bf186b9d1 100644 --- a/test/functional/test_framework/address.py +++ b/test/functional/test_framework/address.py @@ -20,8 +20,11 @@ from .script import ( sha256, taproot_construct, ) -from .segwit_addr import encode_segwit_address from .util import assert_equal +from test_framework.segwit_addr import ( + decode_segwit_address, + encode_segwit_address, +) ADDRESS_BCRT1_UNSPENDABLE = 'bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj' ADDRESS_BCRT1_UNSPENDABLE_DESCRIPTOR = 'addr(bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj)#juyq9d97' @@ -159,6 +162,16 @@ def check_script(script): assert False +def bech32_to_bytes(address): + hrp = address.split('1')[0] + if hrp not in ['bc', 'tb', 'bcrt']: + return (None, None) + version, payload = decode_segwit_address(hrp, address) + if version is None: + return (None, None) + return version, bytearray(payload) + + class TestFrameworkScript(unittest.TestCase): def test_base58encodedecode(self): def check_base58(data, version): @@ -176,3 +189,18 @@ class TestFrameworkScript(unittest.TestCase): check_base58(bytes.fromhex('0041c1eaf111802559bad61b60d62b1f897c63928a'), 0) check_base58(bytes.fromhex('000041c1eaf111802559bad61b60d62b1f897c63928a'), 0) check_base58(bytes.fromhex('00000041c1eaf111802559bad61b60d62b1f897c63928a'), 0) + + + def test_bech32_decode(self): + def check_bech32_decode(payload, version): + hrp = "tb" + self.assertEqual(bech32_to_bytes(encode_segwit_address(hrp, version, payload)), (version, payload)) + + check_bech32_decode(bytes.fromhex('36e3e2a33f328de12e4b43c515a75fba2632ecc3'), 0) + check_bech32_decode(bytes.fromhex('823e9790fc1d1782321140d4f4aa61aabd5e045b'), 0) + check_bech32_decode(bytes.fromhex('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), 1) + check_bech32_decode(bytes.fromhex('39cf8ebd95134f431c39db0220770bd127f5dd3cc103c988b7dcd577ae34e354'), 1) + check_bech32_decode(bytes.fromhex('708244006d27c757f6f1fc6f853b6ec26268b727866f7ce632886e34eb5839a3'), 1) + check_bech32_decode(bytes.fromhex('616211ab00dffe0adcb6ce258d6d3fd8cbd901e2'), 0) + check_bech32_decode(bytes.fromhex('b6a7c98b482d7fb21c9fa8e65692a0890410ff22'), 0) + check_bech32_decode(bytes.fromhex('f0c2109cb1008cfa7b5a09cc56f7267cd8e50929'), 0) From d178082996dc3000f42816f89afcf3fa4d31e159 Mon Sep 17 00:00:00 2001 From: ismaelsadeeq Date: Thu, 23 Mar 2023 12:00:54 +0100 Subject: [PATCH 2/2] test: add bech32 decoding support to address_to_scriptpubkey() This permits functional tests to decode bech32 addresses to scriptpubkeys. --- test/functional/test_framework/wallet.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/functional/test_framework/wallet.py b/test/functional/test_framework/wallet.py index f3253630c46..eab8fbda470 100644 --- a/test/functional/test_framework/wallet.py +++ b/test/functional/test_framework/wallet.py @@ -14,6 +14,7 @@ from typing import ( ) from test_framework.address import ( base58_to_byte, + bech32_to_bytes, create_deterministic_address_bcrt1_p2tr_op_true, key_to_p2pkh, key_to_p2sh_p2wpkh, @@ -49,6 +50,7 @@ from test_framework.script_util import ( key_to_p2sh_p2wpkh_script, key_to_p2wpkh_script, keyhash_to_p2pkh_script, + program_to_witness_script, scripthash_to_p2sh_script, ) from test_framework.util import ( @@ -414,6 +416,9 @@ def getnewdestination(address_type='bech32m'): def address_to_scriptpubkey(address): """Converts a given address to the corresponding output script (scriptPubKey).""" + version, payload = bech32_to_bytes(address) + if version is not None: + return program_to_witness_script(version, payload) # testnet segwit scriptpubkey payload, version = base58_to_byte(address) if version == 111: # testnet pubkey hash return keyhash_to_p2pkh_script(payload)