TeachMeBitcoin

Custom Python Witness Parser

From TeachMeBitcoin, the free encyclopedia Reading time: 2 min

Custom Python Witness Parser

In this final guide, we will build a script that parses the Witness section of a raw SegWit transaction. We will extract the signature and the public key for each input and visualize the "Witness Stack."

The Python Witness Parser

def parse_witness_section(witness_hex):
    # Convert hex to raw bytes
    data = bytes.fromhex(witness_hex)
    cursor = 0

    print(f"--- Parsing Witness Data Structure ---")

    # In a real TX, we would know how many inputs there are.
    # For this simulation, we will parse one input's witness stack.

    # 1. Read Item Count
    item_count = data[cursor]
    cursor += 1
    print(f"[*] Witness Item Count: {item_count}")

    for i in range(item_count):
        # 2. Read Item Length
        item_len = data[cursor]
        cursor += 1

        # 3. Extract Item Data
        item_data = data[cursor:cursor+item_len]
        cursor += item_len

        print(f"\n[Item {i}]")
        print(f"[*] Length: {item_len} bytes")
        print(f"[*] Hex:    {item_data.hex()[:40]}...")

        # Heuristic to identify if it's a pubkey
        if item_len == 33:
            print("[*] Inference: This is a Compressed Public Key.")
        elif item_len \u003e 60:
            print("[*] Inference: This is an ECDSA Signature.")

# --- Simulation ---
# A raw witness hex for a P2WPKH input:
# [02] -> Item Count (2)
# [47] -> Item 1 Len (71)
# [3044...] -> Signature
# [21] -> Item 2 Len (33)
# [02...] -> Pubkey
sample_witness = (
    "02" + 
    "47" + "3044022026859367ca7e2c943806297491730419266993a46611f71a0673c683c316226a022003c274191730419266993a46611f71a0673c683c316226a01" + 
    "21" + "0281cd6495d3550e553c3066d40026a090ef666993a46611f71a0673c683c31622"
)

parse_witness_section(sample_witness)

How to Run the Parser

  1. Ensure you have Python 3 installed.

  2. Copy the code into a file named witness_parser.py.

  3. Run it using python3 witness_parser.py.

Technical Takeaways

  1. Cleaner Logic: Notice how the witness data is just a sequence of length-prefixed chunks. This is much cleaner than the old ScriptSig format, which required a full Script interpreter to parse correctly.

  2. Segregated Proof: Because this data is at the end of the transaction, it's easy for nodes to download the "Headers" and "Transactions" first, and only download the "Witness" if they want to fully verify the block.

  3. Flexible Stack: The stack-based nature of the witness allows for new features (like Taproot) to be added without breaking the core transaction format.

Congratulations! You have completed the Witness module. You now understand the most significant architectural upgrade in Bitcoin's history.

☕ Help support TeachMeBitcoin

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:

Ethereum: 0x578417C51783663D8A6A811B3544E1f779D39A85
Bitcoin: bc1q77k9e95rn669kpzyjr8ke9w95zhk7pa5s63qzz
Solana: 4ycT2ayqeMucixj3wS8Ay8Tq9NRDYRPKYbj3UGESyQ4J
Address copied to clipboard!