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_p2pkh(self): script_type = 'p2pkh' # self-consistency pubkey = "04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4" payload = hash160(pubkey) script = encode(['OP_DUP', 'OP_HASH160', payload, 'OP_EQUALVERIFY', 'OP_CHECKSIG']) # straight to the scriptPubKey scriptPubKey = p2pkh(pubkey) 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.p2pkh(pubkey, network) address2 = address_from_scriptPubKey(scriptPubKey, network) self.assertEqual(address, address2) prefix = p2pkh_prefix_from_network(network) address2 = b58address_from_h160(prefix, payload) 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/p2pkh payload = "12ab8dc588ca9d5787dde7eb29569da63c3a238c" script = "76a91412ab8dc588ca9d5787dde7eb29569da63c3a238c88ac" scriptPubKey = scriptPubKey_from_payload(script_type, payload) self.assertEqual(scriptPubKey.hex(), script) network = 'mainnet' address = b"12higDjoCCNXSA95xZMWUdPvXNmkAduhWv" 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: 11 bytes instead of 20 self.assertRaises( ValueError, scriptPubKey_from_payload, "00" * 11, 'p2pkh')
def test_b58address_from_h160() -> None: addr = b"1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs" prefix, payload, network, _ = h160_from_b58address(addr) assert addr == b58address_from_h160(prefix, payload, network) addr = b"16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM" prefix, payload, network, _ = h160_from_b58address(addr) assert addr == b58address_from_h160(prefix, payload, network) addr = b"37k7toV1Nv4DfmQbmZ8KuZDQCYK9x5KpzP" prefix, payload, network, _ = h160_from_b58address(addr) assert addr == b58address_from_h160(prefix, payload, network) err_msg = "invalid mainnet base58 address prefix: " with pytest.raises(ValueError, match=err_msg): bad_prefix = b"\xbb" b58address_from_h160(bad_prefix, payload, network)
def test_b58address_from_h160(self): addr = b'1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs' prefix, payload, _, _ = h160_from_b58address(addr) self.assertEqual(addr, b58address_from_h160(prefix, payload)) addr = b'16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM' prefix, payload, _, _ = h160_from_b58address(addr) self.assertEqual(addr, b58address_from_h160(prefix, payload)) addr = b'37k7toV1Nv4DfmQbmZ8KuZDQCYK9x5KpzP' prefix, payload, _, _ = h160_from_b58address(addr) self.assertEqual(addr, b58address_from_h160(prefix, payload)) # Invalid base58 address prefix b'\xbb' bad_prefix = b'\xbb' self.assertRaises(ValueError, b58address_from_h160, bad_prefix, payload)
def test_p2pkh() -> None: # self-consistency pubkey = ( "04 " "cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf" "f7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4") payload = hash160(pubkey) script_pubkey = script.serialize( ["OP_DUP", "OP_HASH160", payload, "OP_EQUALVERIFY", "OP_CHECKSIG"]) assert script_pubkey == p2pkh(pubkey) # to the script_pubkey in two steps (through payload) script_type = "p2pkh" 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.p2pkh(pubkey, network) assert address == address_from_script_pubkey(script_pubkey, network) prefix = NETWORKS[network].p2pkh 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/p2pkh payload = "12ab8dc588ca9d5787dde7eb29569da63c3a238c" script_pubkey = "76a914" + payload + "88ac" assert script_pubkey == script_pubkey_from_payload(script_type, payload).hex() address = b"12higDjoCCNXSA95xZMWUdPvXNmkAduhWv" assert address == address_from_script_pubkey(script_pubkey, network) assert (bytes.fromhex(script_pubkey), network) == script_pubkey_from_address(address) # invalid size: 11 bytes instead of 20 err_msg = "invalid size: " with pytest.raises(BTClibValueError, match=err_msg): script_pubkey_from_payload(script_type, "00" * 11)
def test_p2pkh(self): # https://learnmeabitcoin.com/guide/p2pkh # opcodes = ['OP_DUP', 'OP_HASH160', pubkey_hash.hex(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'] pubkey_hash = "12ab8dc588ca9d5787dde7eb29569da63c3a238c" opcodes = p2pkh_scriptPubKey(pubkey_hash) scriptPubKey = encode(opcodes) self.assertEqual(scriptPubKey.hex(), "76a91412ab8dc588ca9d5787dde7eb29569da63c3a238c88ac") addr = address_from_scriptPubKey(scriptPubKey) prefix = _P2PKH_PREFIXES[_NETWORKS.index('mainnet')] self.assertEqual(addr, b58address_from_h160(prefix, pubkey_hash)) # Wrong size (33-bytes) for uncompressed SEC key pubkey = "03 a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f" self.assertRaises(ValueError, p2pk_scriptPubKey, pubkey) #p2pk_scriptPubKey(pubkey) # Invalid size: 11 bytes instead of 20 self.assertRaises(ValueError, p2pkh_scriptPubKey, "00"*11)
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)