Exemplo n.º 1
0
def test_p2ms_p2sh() -> None:
    "BIP67 test vectors https://en.bitcoin.it/wiki/BIP_0067"

    data_folder = path.join(path.dirname(__file__), "test_data")
    filename = path.join(data_folder, "bip67_test_vectors.json")
    with open(filename, "r") as f:
        # json.dump(test_vectors, f, indent=4)
        test_vectors = json.load(f)

    m = 2
    for i in test_vectors:
        keys, address = test_vectors[i]
        errmsg = f"Test vector #{int(i)}"
        scriptPubKey = p2ms(keys, m)
        addr = base58address.p2sh(scriptPubKey)
        assert addr.decode() == address, errmsg

        scriptPubKey = scriptPubKey_from_payload("p2ms", keys, m)
        addr = base58address.p2sh(scriptPubKey)
        assert addr.decode() == address, errmsg

        script_type, payload, m2 = payload_from_scriptPubKey(scriptPubKey)
        assert script_type == "p2ms", errmsg
        for key, k in zip(sorted(keys), payload):
            assert key == k.hex(), errmsg
        assert m2 == m, errmsg
Exemplo n.º 2
0
    def test_p2ms_p2sh(self):
        test_vectors = [
            [0,
                ['022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da',
                 '03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9',
                 '021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18',
                 ],
             b'3Q4sF6tv9wsdqu2NtARzNCpQgwifm2rAba'
             ],
            [1,
                ['02ff12471208c14bd580709cb2358d98975247d8765f92bc25eab3b2763ed605f8',
                 '02fe6f0a5a297eb38c391581c4413e084773ea23954d93f7753db7dc0adc188b2f',
                 ],
                b'39bgKC7RFbpoCRbtD5KEdkYKtNyhpsNa3Z'
             ],
            [2,
                ['02632b12f4ac5b1d1b72b2a3b508c19172de44f6f46bcee50ba33f3f9291e47ed0',
                 '027735a29bae7780a9755fae7a1c4374c656ac6a69ea9f3697fda61bb99a4f3e77',
                 '02e2cc6bd5f45edd43bebe7cb9b675f0ce9ed3efe613b177588290ad188d11b404',
                 ],
                b'3CKHTjBKxCARLzwABMu9yD85kvtm7WnMfH'
             ],
            [3,
                ['030000000000000000000000000000000000004141414141414141414141414141',
                 '020000000000000000000000000000000000004141414141414141414141414141',
                 '020000000000000000000000000000000000004141414141414141414141414140',
                 '030000000000000000000000000000000000004141414141414141414141414140',
                 ],
                b'32V85igBri9zcfBRVupVvwK18NFtS37FuD'
             ],
            [4,
                ['022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da',
                 '03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9',
                 '021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18',
                 ],
                b'3Q4sF6tv9wsdqu2NtARzNCpQgwifm2rAba'
             ],
        ]

        m = 2
        for i, keys, address in test_vectors:
            errmsg = f"Test vector #{int(i)}"
            script = p2ms(keys, m)
            addr = base58address.p2sh(script)
            self.assertEqual(addr, address, errmsg)

            script = scriptPubKey_from_payload('p2ms', keys, m)
            addr = base58address.p2sh(script)
            self.assertEqual(addr, address, errmsg)

            script_type, payload, m2 = payload_from_scriptPubKey(script)
            self.assertEqual(script_type, 'p2ms', errmsg)
            for key, k in zip(sorted(keys), payload):
                self.assertEqual(key, k.hex(), errmsg)
            self.assertEqual(m2, m, errmsg)
Exemplo n.º 3
0
    def test_p2ms(self):

        script_type = "p2ms"

        # self-consistency
        pubkey1 = (
            "04"
            "cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf"
            "f7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4"
        )
        pubkey2 = (
            "04"
            "61cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d765"
            "19aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af"
        )
        pubkeys = [bytes.fromhex(pubkey1), bytes.fromhex(pubkey2)]
        m = 1

        # straight to the scriptPubKey
        scriptPubKey = p2ms(pubkeys, m)
        n = len(pubkeys)
        script = encode([m] + sorted(pubkeys) + [n, "OP_CHECKMULTISIG"])
        self.assertEqual(scriptPubKey.hex(), script.hex())

        # to the scriptPubKey in two steps (through payload)
        scriptPubKey = scriptPubKey_from_payload(script_type, pubkeys, m)
        self.assertEqual(scriptPubKey.hex(), script.hex())

        # back from the scriptPubKey to the payload
        script_type2, payload2, m2 = payload_from_scriptPubKey(scriptPubKey)
        self.assertEqual(script_type, script_type2)
        self.assertEqual(m, m2)
        self.assertEqual(sorted(pubkeys), payload2)
        script_type2, payload2, m2 = payload_from_scriptPubKey(script)
        self.assertEqual(script_type, script_type2)
        self.assertEqual(m, m2)
        self.assertEqual(sorted(pubkeys), payload2)

        # data -> payload in this case is invertible (no hash functions)

        # No address for p2ms script
        self.assertRaises(ValueError, address_from_scriptPubKey, scriptPubKey)
        # address_from_scriptPubKey(scriptPubKey)

        # documented test case: https://learnmeabitcoin.com/guide/p2ms
        pubkey1 = (
            "04"
            "cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf"
            "f7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4"
        )
        pubkey2 = (
            "04"
            "61cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d765"
            "19aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af"
        )
        pubkeys = [bytes.fromhex(pubkey1), bytes.fromhex(pubkey2)]
        m = 1
        n = 2
        script = (
            "51"  # OP_1
            "41"  # canonical 65-bytes push
            "04"
            "cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf"
            "f7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4"
            "41"  # canonical 65-bytes push
            "04"
            "61cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d765"
            "19aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af"
            "52"  # OP_2
            "ae"  # OP_CHECKMULTISIG
        )
        scriptPubKey = p2ms(pubkeys, 1, lexicographic_sort=False)
        self.assertEqual(scriptPubKey.hex(), script)

        # Impossible m>n 3-of-2 multisignature
        self.assertRaises(ValueError, p2ms, pubkeys, 3)
        # p2ms(pubkeys, 3)

        # Invalid m (0) for p2ms script
        self.assertRaises(ValueError, p2ms, pubkeys, 0)
        # p2ms(pubkeys, 0)

        # Invalid size: 66 bytes instead of 65
        self.assertRaises(ValueError, p2ms, [pubkey1 + "00", pubkey2], 1)
        # p2ms([pubkey1 + "00", pubkey2], 1)

        # Invalid n (17) in 3-of-17 multisignature
        self.assertRaises(ValueError, p2ms, [pubkey1] * 17, 3)
        # p2ms([pubkey1]*17, 3)

        # Invalid key length (66) in p2ms
        badpubkeys = sorted(pubkeys)
        badpubkeys[0] = badpubkeys[0] + b"\x00"
        self.assertRaises(
            ValueError, scriptPubKey_from_payload, script_type, badpubkeys, m
        )
        # scriptPubKey_from_payload(script_type, badpubkeys, m)

        # Invalid key length (66) in p2ms
        script = encode([m] + sorted(badpubkeys) + [n, "OP_CHECKMULTISIG"])
        self.assertRaises(ValueError, payload_from_scriptPubKey, script)
        # payload_from_scriptPubKey(script)

        # Invalid key in p2ms
        script = encode([m] + [0, pubkeys[1]] + [n, "OP_CHECKMULTISIG"])
        self.assertRaises(ValueError, payload_from_scriptPubKey, script)
        # payload_from_scriptPubKey(script)

        # Invalid m (0) for p2ms script
        self.assertRaises(
            ValueError, scriptPubKey_from_payload, script_type, pubkeys, 17
        )
Exemplo n.º 4
0
    def test_p2ms_p2sh(self):
        "BIP67 test vectors https://en.bitcoin.it/wiki/BIP_0067"

        test_vectors = {
            0: [
                [
                    (
                        "022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b1"
                        "50a0f85014da"
                    ),
                    (
                        "03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209"
                        "fba0d90de6e9"
                    ),
                    (
                        "021f2f6e1e50cb6a953935c3601284925decd3fd21bc4457125768"
                        "73fb8c6ebc18"
                    ),
                ],
                b"3Q4sF6tv9wsdqu2NtARzNCpQgwifm2rAba",
            ],
            1: [
                [
                    (
                        "02ff12471208c14bd580709cb2358d98975247d8765f92bc25eab3"
                        "b2763ed605f8"
                    ),
                    (
                        "02fe6f0a5a297eb38c391581c4413e084773ea23954d93f7753db7"
                        "dc0adc188b2f"
                    ),
                ],
                b"39bgKC7RFbpoCRbtD5KEdkYKtNyhpsNa3Z",
            ],
            2: [
                [
                    (
                        "02632b12f4ac5b1d1b72b2a3b508c19172de44f6f46bcee50ba33f"
                        "3f9291e47ed0"
                    ),
                    (
                        "027735a29bae7780a9755fae7a1c4374c656ac6a69ea9f3697fda6"
                        "1bb99a4f3e77"
                    ),
                    (
                        "02e2cc6bd5f45edd43bebe7cb9b675f0ce9ed3efe613b177588290"
                        "ad188d11b404"
                    ),
                ],
                b"3CKHTjBKxCARLzwABMu9yD85kvtm7WnMfH",
            ],
            3: [
                [
                    (
                        "030000000000000000000000000000000000004141414141414141"
                        "414141414141"
                    ),
                    (
                        "020000000000000000000000000000000000004141414141414141"
                        "414141414141"
                    ),
                    (
                        "020000000000000000000000000000000000004141414141414141"
                        "414141414140"
                    ),
                    (
                        "030000000000000000000000000000000000004141414141414141"
                        "414141414140"
                    ),
                ],
                b"32V85igBri9zcfBRVupVvwK18NFtS37FuD",
            ],
            4: [
                [
                    (
                        "022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b1"
                        "50a0f85014da"
                    ),
                    (
                        "03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209"
                        "fba0d90de6e9"
                    ),
                    (
                        "021f2f6e1e50cb6a953935c3601284925decd3fd21bc4457125768"
                        "73fb8c6ebc18"
                    ),
                ],
                b"3Q4sF6tv9wsdqu2NtARzNCpQgwifm2rAba",
            ],
        }

        m = 2
        for i in test_vectors:
            keys, address = test_vectors[i]
            errmsg = f"Test vector #{int(i)}"
            script = p2ms(keys, m)
            addr = base58address.p2sh(script)
            self.assertEqual(addr, address, errmsg)

            script = scriptPubKey_from_payload("p2ms", keys, m)
            addr = base58address.p2sh(script)
            self.assertEqual(addr, address, errmsg)

            script_type, payload, m2 = payload_from_scriptPubKey(script)
            self.assertEqual(script_type, "p2ms", errmsg)
            for key, k in zip(sorted(keys), payload):
                self.assertEqual(key, k.hex(), errmsg)
            self.assertEqual(m2, m, errmsg)
Exemplo n.º 5
0
def test_p2ms() -> None:

    script_type = "p2ms"

    # self-consistency
    pubkey1 = (
        "04"
        "cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf"
        "f7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4")
    pubkey2 = (
        "04"
        "61cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d765"
        "19aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af")
    pubkeys = [bytes.fromhex(pubkey1), bytes.fromhex(pubkey2)]
    m = 1

    # straight to the scriptPubKey
    payload = sorted(pubkeys)
    n = len(pubkeys)
    scriptPubKey = script.encode([m] + payload + [n, "OP_CHECKMULTISIG"])
    assert scriptPubKey == p2ms(pubkeys, m)

    # to the scriptPubKey in two steps (through payload)
    assert scriptPubKey == scriptPubKey_from_payload(script_type, pubkeys, m)

    # back from the scriptPubKey to the payload
    assert (script_type, payload, m) == payload_from_scriptPubKey(scriptPubKey)

    err_msg = "no address for p2ms scriptPubKey"
    with pytest.raises(ValueError, match=err_msg):
        address_from_scriptPubKey(scriptPubKey)

    # documented test case: https://learnmeabitcoin.com/guide/p2ms
    pubkeys = [bytes.fromhex(pubkey1), bytes.fromhex(pubkey2)]
    m = 1
    n = 2
    scriptPubKey = (  # fmt: off
        "51"  # OP_1
        "41"  # canonical 65-bytes push
        + pubkey1 + "41"  # noqa E148  # canonical 65-bytes push
        + pubkey2 + "52"  # noqa E148  # OP_2
        "ae"  # OP_CHECKMULTISIG
    )  # fmt: on
    assert scriptPubKey == p2ms(pubkeys, 1, lexicographic_sort=False).hex()

    err_msg = "number-of-pubkeys < m in "
    with pytest.raises(ValueError, match=err_msg):
        p2ms(pubkeys, 3)

    err_msg = "invalid m for p2ms scriptPubKey: "
    with pytest.raises(ValueError, match=err_msg):
        p2ms(pubkeys, 0)

    err_msg = "not a private or public key: "
    with pytest.raises(ValueError, match=err_msg):
        p2ms([pubkey1 + "00", pubkey2], 1)

    err_msg = "too many pubkeys in m-of-n multisignature: "
    with pytest.raises(ValueError, match=err_msg):
        p2ms([pubkey1] * 17, 3)

    err_msg = "invalid size: "
    badpubkeys = sorted(pubkeys)
    badpubkeys[0] = badpubkeys[0] + b"\x00"
    with pytest.raises(ValueError, match=err_msg):
        scriptPubKey_from_payload(script_type, badpubkeys, m)

    scriptPubKey = script.encode([m] + sorted(badpubkeys) +
                                 [n, "OP_CHECKMULTISIG"])
    with pytest.raises(ValueError, match=err_msg):
        payload_from_scriptPubKey(scriptPubKey)

    err_msg = "invalid key in p2ms"
    scriptPubKey = script.encode([m] + [0, pubkeys[1]] +
                                 [n, "OP_CHECKMULTISIG"])
    with pytest.raises(ValueError, match=err_msg):
        payload_from_scriptPubKey(scriptPubKey)

    err_msg = "invalid m in m-of-n multisignature: "
    with pytest.raises(ValueError, match=err_msg):
        scriptPubKey_from_payload(script_type, pubkeys, 17)