The Lock With a Hundred Keys, Only One of Which You Show
You open the safe, hand over the one combination that worked, and walk out. Nobody in the room learns how many other combinations existed. Nobody learns their structure, their number, or whether one of them would have unlocked something even more interesting. The safe is closed. The question never gets asked.
That is not a loose analogy for Bitcoin's Tapscript. It is, with only minor compression, the actual mechanism.
Tapscript, activated as part of the Taproot upgrade at block 709,632, lets you embed multiple spending conditions into a single Bitcoin output. When you spend it, you reveal only the branch you actually used. Every other branch stays hidden, permanently, in a cryptographic structure that can be verified without being fully exposed. The privacy here is not cosmetic. It is structural, and that distinction matters more than most introductions to this subject admit.
How the Tree Gets Built
The underlying data structure is called a Merklized Abstract Syntax Tree, or MAST. The name is dense; the idea is not.
Suppose you want to lock a UTXO with three possible spending conditions:
- Alice's signature alone (a hot wallet fallback)
- A 2-of-3 multisig between Alice, Bob, and Carol (normal business operation)
- Alice's signature plus a 90-day timelock (a cold recovery path)
Each condition is written as a small script, called a leaf. Each leaf gets hashed. Pairs of hashes get hashed together, and that process repeats until a single 32-byte value sits at the top: the Merkle root.
That root is then tweaked into a public key using a well-defined elliptic curve operation. The resulting point goes on-chain as the output address. It looks, to any observer, like a plain public key. You cannot tell from the address alone whether there is one spending condition or fifty.
When Alice wants to spend using condition 2, she broadcasts the 2-of-3 multisig script, the three signatures satisfying it, and a Merkle proof: the minimum set of sibling hashes needed to prove that her script is a genuine leaf of that tree. The verifier recomputes the root, checks that it matches the tweaked key, and if it does, the spend is valid.
Conditions 1 and 3 never appear on-chain. Not their content, not even their hashes, not a hint they exist.
A Worked Example With Real Numbers
Consider Alice and Bob, business partners who set up an output with three leaves:
- Leaf A: Alice's key alone (for operational payments)
- Leaf B: Both signatures required (for large transfers)
- Leaf C: Either key after a 52,560-block timelock, roughly one year (the dead-hand recovery clause)
The tree has three leaves, so one gets paired with the hash of the other two. Leaf A pairs with a combined hash of Leaves B and C. The root is computed from those two.
Normal day: Alice pays a vendor using Leaf A. She provides her signature, the Leaf A script (`OP_CHECKSIG` against her public key), and a Merkle proof containing exactly one 32-byte sibling hash. That is the hash of the B+C subtree. Total overhead: one hash.
An observer sees a script-path spend with a single script and a single sibling hash. They learn Alice had a unilateral spending option. The joint-signature path, the timelock recovery, the structure of the partnership itself: all invisible. If the tree had 128 leaves instead of 3, a spend from any one leaf would require at most 7 sibling hashes (log base 2 of 128). Privacy and efficiency scale together, which is rarer than it should be in protocol design.
The Part That Surprises Most People
Many explanations of Taproot stop at key-path spending: if everyone agrees, you cooperate to produce a single Schnorr signature, and the output spends without revealing any script at all. Clean, minimal, private. That is the happy path.
Tapscript runs when cooperation breaks down, or when a specific condition must be provably satisfied.
What surprises people is that script-path spending is still remarkably private. You might assume that revealing a MAST structure leaks the depth or breadth of the tree. It does not. The Merkle proof proves membership without revealing the set size. A proof of depth 7 could mean a perfectly balanced tree of 128 leaves, or a lopsided tree of 8 leaves where one branch runs deep. You cannot distinguish them from the proof alone. The proof is, in this sense, like a library call number: it locates the book without describing the collection.
There is an honest caveat worth stating precisely. The number of sibling hashes in the proof does leak the depth of that specific leaf in the tree. A designer who wants to minimize even that signal can pad the tree with dummy leaves, or arrange frequently-used conditions near the root to shorten proof length. These are real engineering choices with real tradeoffs. Tapscript provides the tooling; it does not make every implementation automatically private.
One more point deserves emphasis: if a condition is never spent, it is hidden forever. If it is spent, it is revealed at that moment. The privacy guarantee runs in one direction only. Plan accordingly.
Why Leaf Ordering Is an Engineering Decision, Not a Formality
Because Merkle proof length leaks leaf depth, the order you assign to leaves affects both fees and fingerprinting. This is where protocol design becomes genuinely interesting, and where naive implementations diverge from careful ones.
Put your most common spending condition at the shallowest position in the tree. It will carry the shortest proof, the lowest fee, and incidentally reveal the least about the tree's overall structure. Put rare or sensitive conditions deeper: the timelock recovery, the court-ordered override, the multisig quorum for exceptional decisions.
Here is the scenario in concrete terms. Two developers, Marcus and Priya, both build a 2-of-3 multisig wallet with a unilateral fallback. Marcus places the unilateral key at depth 3, the multisig at depth 1. Priya does the reverse. Every time Marcus's wallet executes a routine payment via the unilateral key, it costs more in fees and emits a longer proof than Priya's. Over a year of regular transactions, that gap compounds. It is not a catastrophic error. It is precisely the kind of decision that separates a thoughtful implementation from a naive one, and reviewers should be asking about it.
You can verify this in Bitcoin's reference implementation. The `TaprootBuilder` class in Bitcoin Core lets you specify the depth for each leaf explicitly, rather than deferring to an automatically balanced tree. That design choice was deliberate, and it rewards developers who understand why it exists.
So ask yourself: when you last reviewed a Taproot wallet implementation, did the documentation say anything about leaf ordering? If it did not, that is worth a follow-up question.
The Leaves You Never Spend Are the Most Private Thing in Bitcoin
Two readings of Tapscript's privacy model are defensible. The first holds that the protection is modest, a marginal improvement over prior script structures, because any script-path spend does reveal the leaf used and its depth. The second holds that the protection is genuinely meaningful, because unspent leaves are not merely hidden but cryptographically committed and permanently invisible absent a spend event. The second reading is correct, and the gap between the two is not small.
For anyone building covenants, vaults, time-locked inheritance schemes, or complex multisig governance structures, MAST means you can encode richness and contingency without broadcasting that richness to every full node on the network. The complexity lives off-chain until the moment it is needed, and even then, only the necessary slice of it surfaces.
A spending condition that is cryptographically committed, verifiably present in a UTXO, and permanently invisible because it was never triggered: that is not obfuscation, not mixing, not a zero-knowledge proof layered on top of an otherwise leaky structure. It is the cleanest form of on-chain privacy available in base-layer Bitcoin today, and the implementations that treat leaf ordering as an afterthought are leaving it on the table.