Custom Python P2PKH Auditor
Custom Python P2PKH Auditor
In this final guide, we will build a Python script that takes a raw P2PKH ScriptPubKey and extracts the 20-byte hash. To make it human-readable, we will implement the Base58Check encoding to convert that hash back into a legacy "1" address.
The P2PKH Address Auditor
import hashlib
# Standard Base58 alphabet
BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
def base58_encode(raw_bytes):
# Convert bytes to an integer
n = int.from_bytes(raw_bytes, 'big')
res = ""
while n \u003e 0:
n, r = divmod(n, 58)
res = BASE58_ALPHABET[r] + res
# Handle leading zeros (which become '1' in Base58)
pad = 0
for b in raw_bytes:
if b == 0: pad += 1
else: break
return "1" * pad + res
def decode_p2pkh(script_hex):
# 1. Check for standard P2PKH pattern
# 76 (DUP) a9 (HASH160) 14 (PUSH 20) ... 88 (EQUALVERIFY) ac (CHECKSIG)
if not (script_hex.startswith("76a914") and script_hex.endswith("88ac")):
print("[ERROR] Not a standard P2PKH script!")
return
# 2. Extract the 20-byte hash
pkh_hex = script_hex[6:-4]
pkh_bytes = bytes.fromhex(pkh_hex)
print(f"--- P2PKH Script Audit ---")
print(f"[*] Raw Script: {script_hex}")
print(f"[*] Key Hash: {pkh_hex}")
# 3. Base58Check Encoding
# Step A: Prepend Version Byte (0x00 for Mainnet)
versioned_pkh = b'\\x00' + pkh_bytes
# Step B: Double SHA256 for checksum
first_sha = hashlib.sha256(versioned_pkh).digest()
checksum = hashlib.sha256(first_sha).digest()[:4]
# Step C: Append Checksum and Encode
final_payload = versioned_pkh + checksum
address = base58_encode(final_payload)
print(f"[*] Final Address: {address}")
# --- Simulation ---
# Case: A real-world legacy address ScriptPubKey
# address: 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
p2pkh_script = "76a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1888ac"
decode_p2pkh(p2pkh_script)
How to Run the Auditor
-
Ensure you have Python 3 installed.
-
Copy the code into a file named
p2pkh_auditor.py. -
Run it using
python3 p2pkh_auditor.py.
Technical Takeaways
-
Hashed Identity: Notice how the address is just a representation of the hash. The original public key is nowhere to be found in this script.
-
Safety First: The checksum we calculated ensures that the address we generated is mathematically consistent. Wallets do this same check before every transaction.
-
Efficiency: By reducing a 65-byte public key to a 20-byte hash, Bitcoin's P2PKH saved nearly 60% of the space required to define a payment destination.
Congratulations! You have completed the P2PKH (Pay-to-Public-Key-Hash) module. You now understand how legacy Bitcoin addresses work under the hood.
TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation: