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
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)
def test_p2sh(self): # https://medium.com/@darosior/bitcoin-raw-transactions-part-2-p2sh-94df206fee8d script = ['OP_2DUP', 'OP_EQUAL', 'OP_NOT', 'OP_VERIFY', 'OP_SHA1', 'OP_SWAP', 'OP_SHA1', 'OP_EQUAL'] script_bytes = encode(script) self.assertEqual(script_bytes.hex(), '6e879169a77ca787') network = 'mainnet' addr = p2sh(script_bytes, network) self.assertEqual(addr, b'37k7toV1Nv4DfmQbmZ8KuZDQCYK9x5KpzP') _, redeem_script_hash, network2, is_p2sh = h160_from_b58address(addr) self.assertEqual(network, network2) self.assertTrue(is_p2sh) self.assertEqual(redeem_script_hash, hash160(script_bytes)) self.assertEqual(redeem_script_hash.hex(), '4266fc6f2c2861d7fe229b279a79803afca7ba34') output_script = ['OP_HASH160', redeem_script_hash.hex(), 'OP_EQUAL'] _ = encode(output_script) # address with trailing/leading spaces _, h160, _, _ = h160_from_b58address( ' 37k7toV1Nv4DfmQbmZ8KuZDQCYK9x5KpzP ') self.assertEqual(redeem_script_hash, h160)
def test_p2sh(self): script_type = "p2sh" # self-consistency pubkey = "02" "cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf" pubkey_hash = hash160(pubkey) redeem_script = scriptPubKey_from_payload("p2pkh", pubkey_hash) payload = hash160(redeem_script) script = encode(["OP_HASH160", payload, "OP_EQUAL"]) # straight to the scriptPubKey scriptPubKey = p2sh(redeem_script) self.assertEqual(scriptPubKey.hex(), script.hex()) # to the scriptPubKey in two steps (through payload) scriptPubKey = scriptPubKey_from_payload(script_type, payload) 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(0, m2) self.assertEqual(payload.hex(), payload2.hex()) script_type2, payload2, m2 = payload_from_scriptPubKey(script) self.assertEqual(script_type, script_type2) self.assertEqual(0, m2) self.assertEqual(payload.hex(), payload2.hex()) # data -> payload is not invertible (hash functions) # address network = "mainnet" address = base58address.p2sh(decode(redeem_script), network) address2 = address_from_scriptPubKey(scriptPubKey, network) self.assertEqual(address, address2) prefix = NETWORKS[network]["p2sh"] address2 = b58address_from_h160(prefix, payload, network) self.assertEqual(address, address2) scriptPubKey2, network2 = scriptPubKey_from_address(address) self.assertEqual(scriptPubKey2, scriptPubKey) self.assertEqual(network2, network) # documented test case: https://learnmeabitcoin.com/guide/p2sh payload = "748284390f9e263a4b766a75d0633c50426eb875" script = "a914748284390f9e263a4b766a75d0633c50426eb87587" scriptPubKey = scriptPubKey_from_payload(script_type, payload) self.assertEqual(scriptPubKey.hex(), script) network = "mainnet" address = b"3CK4fEwbMP7heJarmU4eqA3sMbVJyEnU3V" address2 = address_from_scriptPubKey(scriptPubKey, network) self.assertEqual(address, address2) scriptPubKey2, network2 = scriptPubKey_from_address(address) self.assertEqual(scriptPubKey2, scriptPubKey) self.assertEqual(network2, network) # invalid size: 21 bytes instead of 20 self.assertRaises(ValueError, scriptPubKey_from_payload, "00" * 21, "p2sh")
def test_p2sh() -> None: # self-consistency pubkey = "02 cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf" pubkey_hash = hash160(pubkey) redeem_script = script_pubkey_from_payload("p2pkh", pubkey_hash) payload = hash160(redeem_script) script_pubkey = script.serialize(["OP_HASH160", payload, "OP_EQUAL"]) assert script_pubkey == p2sh(redeem_script) # to the script_pubkey in two steps (through payload) script_type = "p2sh" assert script_pubkey == script_pubkey_from_payload(script_type, payload) # back from the script_pubkey to the payload assert (script_type, payload, 0) == payload_from_script_pubkey(script_pubkey) # base58 address network = "mainnet" address = base58address.p2sh(script.deserialize(redeem_script), network) assert address == address_from_script_pubkey(script_pubkey, network) prefix = NETWORKS[network].p2sh assert address == b58address_from_h160(prefix, payload, network) # back from the address to the script_pubkey assert (script_pubkey, network) == script_pubkey_from_address(address) # documented test case: https://learnmeabitcoin.com/guide/p2sh payload = "748284390f9e263a4b766a75d0633c50426eb875" script_pubkey = "a914" + payload + "87" assert script_pubkey == script_pubkey_from_payload(script_type, payload).hex() address = b"3CK4fEwbMP7heJarmU4eqA3sMbVJyEnU3V" assert address == address_from_script_pubkey(script_pubkey, network) assert (bytes.fromhex(script_pubkey), network) == script_pubkey_from_address(address) # invalid size: 21 bytes instead of 20 err_msg = "invalid size: " with pytest.raises(BTClibValueError, match=err_msg): script_pubkey_from_payload(script_type, "00" * 21)
def test_p2sh() -> None: # https://medium.com/@darosior/bitcoin-raw-transactions-part-2-p2sh-94df206fee8d scriptPubKey: List[ScriptToken] = [ "OP_2DUP", "OP_EQUAL", "OP_NOT", "OP_VERIFY", "OP_SHA1", "OP_SWAP", "OP_SHA1", "OP_EQUAL", ] assert script.serialize(scriptPubKey).hex() == "6e879169a77ca787" network = "mainnet" addr = p2sh(scriptPubKey, network) assert addr == b"37k7toV1Nv4DfmQbmZ8KuZDQCYK9x5KpzP" _, redeem_script_hash, network2, is_script_hash = h160_from_b58address( addr) assert network == network2 assert is_script_hash assert redeem_script_hash == hash160(script.serialize(scriptPubKey)) assert redeem_script_hash.hex( ) == "4266fc6f2c2861d7fe229b279a79803afca7ba34" output_script: List[ScriptToken] = [ "OP_HASH160", redeem_script_hash.hex(), "OP_EQUAL", ] script.serialize(output_script) # address with trailing/leading spaces _, h160, network2, is_script_hash = h160_from_b58address( " 37k7toV1Nv4DfmQbmZ8KuZDQCYK9x5KpzP ") assert network == network2 assert is_script_hash assert redeem_script_hash == h160
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)