Custom Python P2WPKH Auditor
Custom Python P2WPKH Auditor
In this final guide, we will build a Python script that parses a Native SegWit (P2WPKH) ScriptPubKey. The script will extract the 20-byte hash and convert it into a human-readable bc1q address using a simplified Bech32 implementation.
The P2WPKH Address Auditor
# Bech32 constants
CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
def bech32_polymod(values):
generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]
chk = 1
for value in values:
top = chk \u003e\u003e 25
chk = (chk \u0026 0x1ffffff) \u003c\u003c 5 ^ value
for i in range(5):
chk ^= generator[i] if ((top \u003e\u003e i) \u0026 1) else 0
return chk
def bech32_hrp_expand(hrp):
return [ord(x) \u003e\u003e 5 for x in hrp] + [0] + [ord(x) \u0026 31 for x in hrp]
def convertbits(data, frombits, tobits, pad=True):
acc = 0
bits = 0
ret = []
maxv = (1 \u003c\u003c tobits) - 1
for value in data:
acc = (acc \u003c\u003c frombits) | value
bits += frombits
while bits \u003e= tobits:
bits -= tobits
ret.append((acc \u003e\u003e bits) \u0026 maxv)
if pad:
if bits:
ret.append((acc \u003c\u003c (tobits - bits)) \u0026 maxv)
return ret
def audit_p2wpkh(script_hex):
# 1. Identify the Pattern (00 14 [20-byte hash])
if not (script_hex.startswith("0014") and len(script_hex) == 44):
print("[ERROR] Not a standard P2WPKH ScriptPubKey!")
return
pkh_hex = script_hex[4:]
pkh_bytes = list(bytes.fromhex(pkh_hex))
print(f"--- Native SegWit Audit ---")
print(f"[*] ScriptPubKey: {script_hex}")
print(f"[*] Key Hash: {pkh_hex}")
# 2. Convert bytes to 5-bit groups for Bech32
data = [0] + convertbits(pkh_bytes, 8, 5) # 0 is the witness version
# 3. Calculate Checksum
hrp = "bc"
combined = bech32_hrp_expand(hrp) + data
mod = bech32_polymod(combined + [0, 0, 0, 0, 0, 0]) ^ 1
checksum = [(mod \u003e\u003e 5 * (5 - i)) \u0026 31 for i in range(6)]
# 4. Final Encoding
address = hrp + "1" + "".join([CHARSET[d] for d in data + checksum])
print(f"[*] Derived Address: {address}")
# --- Simulation ---
# Case: A real-world bc1q address ScriptPubKey
# address: bc1qypmlegh4p9824mlegvlegvlegvlegvlegvleg
# (simplified test case hash)
p2wpkh_script = "001462e907b15cbf27d5425399ebf6f0fb50ebb88f18"
audit_p2wpkh(p2wpkh_script)
How to Run the Auditor
-
Ensure you have Python 3 installed.
-
Copy the code into a file named
p2wpkh_auditor.py. -
Run it using
python3 p2wpkh_auditor.py.
Technical Takeaways
-
Version Zero: Notice how the first byte of the data (
0) corresponds to the 'q' in the address. If this were a Version 1 (Taproot) address, the byte would be1and the address would start withbc1p. -
Bit Packing: Bech32 is more complex than Base58 because it requires converting 8-bit bytes into 5-bit chunks. This allows the alphabet to stay small and safe.
-
Modern Footprint: At 22 bytes, P2WPKH is the smallest non-custom locking script in Bitcoin history. It represents the pinnacle of single-signature optimization.
Congratulations! You have completed the P2WPKH (Native SegWit) module. You now understand the modern standard for personal Bitcoin wallets.
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: