Blockchain/Level IV · Protocol depth/4.2 Upgrades/Lesson 2
Tapscript and script trees (MAST)
The tree that hides the contract
MaterialsA block explorer with witness data inspection capabilitiesA Taproot-compatible wallet that supports script treesGraph paper for sketching binary Merkle trees
Wonder
- Why should spending under one clause of a contract reveal the whole contract?
- What makes a cooperative spend indistinguishable from a simple signature?
- How does a single key commit to an entire library of hidden spending conditions?
Explore
- Merkelized abstract syntax trees (MAST) were first described by Russell O’Connor in 2013 and developed in proposals in 2016 and 2017. The concept placed alternative spending conditions into a Merkle tree, allowing a spender to reveal only the specific branch they were using. While the term ‘abstract syntax tree’ referred to compiler structures where every condition creates a new node, Bitcoin’s implementation evolved differently. Anthony Towns later coined the backronym ‘Merklized Alternative Script Tree’ to describe the structure actually adopted: a set of complete, independent scripts where only one is selected at spend time.
- Taproot integrated this tree structure into the consensus rules via BIP341. Each leaf in the Merkle tree contains a script, and the root of that tree contributes to the final output key. When funds are spent via the ‘script path,’ the spender reveals the specific leaf script, its inputs, and the Merkle proof—the hashes of sibling nodes at each level. The unused branches remain hidden on-chain, preserving privacy for complex arrangements like multisig or timelocks that were previously forced into P2SH wrappers.
- Tapscript (BIP342) is the specific dialect used for these leaf scripts, diverging from legacy Bitcoin Script in several critical ways. OP_CHECKMULTISIG is disabled in tapscript. Its replacement, OP_CHECKSIGADD, checks one signature against one key and adds 1 to a running count; an empty signature adds nothing, while an invalid non-empty one fails the whole script; a script chains one per key and compares the count with the threshold. Each signature is matched to a known key, so there is no trial-and-error matching and signatures can be batch-verified.
- Tapscript also reserves room for upgrades with OP_SUCCESS opcodes: today any script containing one succeeds unconditionally, so no one uses them, and a future soft fork can give them restrictive meanings without invalidating anything in use. The legacy 10,000-byte script size limit is removed in tapscript; instead, script size is bounded only by block weight and policy limits. Additionally, a signature-operations budget scales with witness size, preventing denial-of-service attacks via excessive signature verification.
- Consider a practical example: a user holds funds in a 2-of-2 key path for everyday spending, where both parties sign cooperatively to reveal nothing but a standard Schnorr signature. However, the script tree includes a hidden leaf that allows one key to spend alone after a one-year timelock. If the cooperative partner becomes unresponsive, the user can activate this recovery branch. The Merkle proof reveals only that specific timelock script, keeping other potential branches—such as social recovery or hashlocks—completely private.
- To verify these mechanics, open a block explorer and locate a Taproot transaction spent via the script path. Inspect the witness: the script’s inputs, the leaf script itself, and a control block whose first byte combines the leaf version (0xc0 for tapscript) with a parity bit, followed by the internal key and one 32-byte hash per level of the tree. Compare this with a key-path spend from the same address type; the latter reveals only a 64- or 65-byte signature and no script data, demonstrating how complex contracts remain invisible when not used.
Key facts
- MAST stands for Merklized Alternative Script Tree, a backronym coined by Anthony Towns to describe Taproot’s structure.
- Tapscript removes the legacy 10,000-byte script size limit, bounding scripts only by block weight and policy.
- OP_CHECKSIGADD in tapscript replaces OP_CHECKMULTISIG for batch-friendly threshold checks.
- A script-path spend reveals the leaf script, its inputs, and a Merkle proof of sibling hashes.
- OP_SUCCESS opcodes reserve room for future soft forks without breaking existing tapscripts.
- Leaf version 0xc0 marks tapscript; unknown leaf versions are left unrestricted for future soft forks.
Exercise nine, six, three, one
9CollectList 9 distinct spending conditions (e.g., multisig, timelock, hashlock) that could be placed in a Taproot script tree. Note the primary purpose of each condition.
6ClusterGroup the 9 conditions into 6 categories based on their privacy implications: fully hidden, partially revealed, always visible, or other structural constraints.
3DistillReduce the 6 groups to 3 core reasons why hiding specific script branches matters for chain efficiency and user security.
1CrystallizeWrite 1 sentence explaining how a Merkle tree allows a single public key to commit to multiple mutually exclusive spending rules without revealing them.
Fact check
Dates, figures and claims checked against the published sources listed below.
- BIP341: Taproot: SegWit version 1 spending rules
- BIP342: Validation of Taproot Scripts
- Bitcoin Optech, 'MAST' and 'Tapscript' topics
- Anthony Towns, 'Merklized Alternative Script Trees' proposal discussions