#!/usr/bin/env python3 # Copyright (c) 2023 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test validateaddress for main chain""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal INVALID_DATA = [ # BIP 173 ( "tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty", "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # Invalid hrp [], ), ("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5", "Invalid Bech32 checksum", [41]), ( "BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2", "Version 1+ witness address must use Bech32m checksum", [], ), ( "bc1rw5uspcuh", "Version 1+ witness address must use Bech32m checksum", # Invalid program length [], ), ( "bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90", "Version 1+ witness address must use Bech32m checksum", # Invalid program length [], ), ( "BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P", "Invalid Bech32 v0 address program size (16 bytes), per BIP141", [], ), ( "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7", "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Mixed case [], ), ( "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3t4", "Invalid character or mixed case", # bc1, Mixed case, not in BIP 173 test vectors [40], ), ( "bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du", "Version 1+ witness address must use Bech32m checksum", # Wrong padding [], ), ( "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv", "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Non-zero padding in 8-to-5 conversion [], ), ("bc1gmk9yu", "Empty Bech32 data section", []), # BIP 350 ( "tc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vq5zuyut", "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # Invalid human-readable part [], ), ( "bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqh2y7hd", "Version 1+ witness address must use Bech32m checksum", # Invalid checksum (Bech32 instead of Bech32m) [], ), ( "tb1z0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqglt7rf", "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Invalid checksum (Bech32 instead of Bech32m) [], ), ( "BC1S0XLXVLHEMJA6C4DQV22UAPCTQUPFHLXM9H8Z3K2E72Q4K9HCZ7VQ54WELL", "Version 1+ witness address must use Bech32m checksum", # Invalid checksum (Bech32 instead of Bech32m) [], ), ( "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kemeawh", "Version 0 witness address must use Bech32 checksum", # Invalid checksum (Bech32m instead of Bech32) [], ), ( "tb1q0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vq24jc47", "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Invalid checksum (Bech32m instead of Bech32) [], ), ( "bc1p38j9r5y49hruaue7wxjce0updqjuyyx0kh56v8s25huc6995vvpql3jow4", "Invalid Base 32 character", # Invalid character in checksum [59], ), ( "BC130XLXVLHEMJA6C4DQV22UAPCTQUPFHLXM9H8Z3K2E72Q4K9HCZ7VQ7ZWS8R", "Invalid Bech32 address witness version", [], ), ("bc1pw5dgrnzv", "Invalid Bech32 address program size (1 byte)", []), ( "bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7v8n0nx0muaewav253zgeav", "Invalid Bech32 address program size (41 bytes)", [], ), ( "BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P", "Invalid Bech32 v0 address program size (16 bytes), per BIP141", [], ), ( "tb1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vq47Zagq", "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Mixed case [], ), ( "bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7v07qwwzcrf", "Invalid padding in Bech32 data section", # zero padding of more than 4 bits [], ), ( "tb1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vpggkg4j", "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Non-zero padding in 8-to-5 conversion [], ), ("bc1gmk9yu", "Empty Bech32 data section", []), ] VALID_DATA = [ # BIP 350 ( "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4", "0014751e76e8199196d454941c45d1b3a323f1433bd6", ), # ( # "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7", # "00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262", # ), ( "bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3", "00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262", ), ( "bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kt5nd6y", "5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6", ), ("BC1SW50QGDZ25J", "6002751e"), ("bc1zw508d6qejxtdg4y5r3zarvaryvaxxpcs", "5210751e76e8199196d454941c45d1b3a323"), # ( # "tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy", # "0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433", # ), ( "bc1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvses5wp4dt", "0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433", ), # ( # "tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c", # "5120000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433", # ), ( "bc1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvses7epu4h", "5120000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433", ), ( "bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0", "512079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", ), # PayToAnchor(P2A) ( "bc1pfeessrawgf", "51024e73", ), ] class ValidateAddressMainTest(BitcoinTestFramework): def set_test_params(self): self.setup_clean_chain = True self.chain = "" # main self.num_nodes = 1 self.extra_args = [["-prune=899"]] * self.num_nodes def check_valid(self, addr, spk): info = self.nodes[0].validateaddress(addr) assert_equal(info["isvalid"], True) assert_equal(info["scriptPubKey"], spk) assert "error" not in info assert "error_locations" not in info def check_invalid(self, addr, error_str, error_locations): res = self.nodes[0].validateaddress(addr) assert_equal(res["isvalid"], False) assert_equal(res["error"], error_str) assert_equal(res["error_locations"], error_locations) def test_validateaddress(self): for (addr, error, locs) in INVALID_DATA: self.check_invalid(addr, error, locs) for (addr, spk) in VALID_DATA: self.check_valid(addr, spk) def run_test(self): self.test_validateaddress() if __name__ == "__main__": ValidateAddressMainTest(__file__).main()