Parsing the leaf version from control block:
7. Tapscript Leaf Version Explained
Every script in a Taproot script tree is tagged with a leaf version byte. This byte identifies which scripting language or rule set applies when that script is executed. The current standard is leaf version 0xc0, which means BIP 342 Tapscript.
Where the Leaf Version Lives
In a Taproot script tree, each leaf contains:
TapLeaf:
- leaf_version: 1 byte
- script: variable length
TapLeaf hash:
hash = tagged_hash("TapLeaf", leaf_version_byte + compact_size(len(script)) + script)
The leaf version is also encoded in the control block that is provided when spending via the script path:
Control block structure:
- (leaf_version | parity_bit): 1 byte
└── High 7 bits: leaf version (e.g., 0xc0 >> 1 = 0x60)
└── Low 1 bit: parity of the internal key's y-coordinate
- internal_pubkey: 32 bytes
- merkle_path: 0 to 128 × 32 bytes (the branch hashes to the root)
python
# Parsing the leaf version from control block:
control_block = witness_stack[-1] # Last item (before annex if present)
leaf_version = control_block[0] & 0xfe # Mask off the parity bit
# leaf_version should be 0xc0 for standard Tapscript
Valid Leaf Versions
BIP 341 specifies that leaf versions must be even numbers in the range 0x00 to 0xfe. This leaves 128 possible leaf versions. Currently:
0xc0 → BIP 342 Tapscript (the only currently defined version)
0x00 → Reserved (would be confusable with OP_0, avoided)
0x02–0xbe (even values) → Reserved for future use
0xc2–0xfe (even values) → Reserved for future use
Odd leaf version values are invalid and cause script failure. This is enforced to ensure the parity bit in the control block is always distinguishable from the leaf version.
Using Leaf Versions for Script Evolution
Leaf versions provide a clean mechanism for introducing entirely new scripting languages into Bitcoin. Unlike OP_SUCCESS opcodes (which modify individual opcode behavior within Tapscript), leaf versions allow defining a completely different execution environment.
Future possibility:
Leaf version 0xc2: "Tapscript v2"
- Could re-enable OP_CAT natively (not via OP_SUCCESS soft fork)
- Could introduce new numeric ranges (5-byte script numbers)
- Could change stack item size limits
- Could add new opcodes without the OP_SUCCESS mechanism
Leaf version 0xc4: "Simplicity" (the functional scripting language)
- A completely different language with formal verification properties
- Already designed to be deployed via a Taproot leaf version
Practical Implications for Script Writers
When constructing a Taproot script tree, you must specify the leaf version for each leaf. Standard wallets and libraries default to 0xc0. If you are using a future leaf version in a custom script, you must ensure both the sender and recipient understand the semantics.
# Building a TapLeaf in Python (using python-bitcoinlib or similar):
def make_tap_leaf(script_bytes, leaf_version=0xc0):
"""Create a TapLeaf with the specified version."""
return tagged_hash(
"TapLeaf",
bytes([leaf_version]) + compact_size(len(script_bytes)) + script_bytes
)
Technical Insight
This topic covers essential mechanics for Chapter 11. Understanding these details is key to mastering advanced Bitcoin script constructions like Taproot and specialized covenants.
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: