Part IV · The Taproot Era Chapter 12

Tapscript: The Script Path

"Merkle branches let us only reveal the actually executed part of the script to the blockchain, as opposed to all possible ways a script can be executed."—BIP 341, Design

In Chapter 11, we saw Taproot's elegant key path: a single Schnorr signature, verified against the output key, with no scripts revealed. But the output key \(Q\) is more than it appears. Recall that \(Q = P + tG\), where \(t = H(\texttt{"TapTweak"},\; P_x \| c)\) and \(c\) is the Merkle root of a tree of scripts. In the key path, that tree remained invisible—a silent promise of alternative spending conditions that were never needed.

This chapter explores what happens when the key path isn't available. Perhaps one party has lost their key. Perhaps a timelock has expired. Perhaps the cooperative case failed and a fallback condition must be exercised. In these situations, the spender reaches into the script tree and reveals exactly one branch—the script path—while every other branch remains hidden.

Our specimen comes from the same historic block as Chapter 11: block 709,635, just three blocks after Taproot activation. It contains two inputs spending from the same parent transaction—one via key path, one via script path—making it a perfect side-by-side comparison. The script path input reveals a simple TapScript, a control block with a Merkle proof, and the internal key that was hidden during key path spending.

12.1The Specimen

Our specimen is from block 709,635 (November 14, 2021)—the same block as our Chapter 11 specimen. It spends two P2TR outputs from the same parent transaction, one via key path and one via script path.

Txid:

37777defed8717c581b4c0509329550e344bdc14ac38f71fc050096887e535c8

MetricValueNotes
Total size358 BIncluding witness
Stripped size123 BWithout marker, flag, witness
Weight727 WU\(123 \times 3 + 358\)
vsize182 vB\(727/4\)
Fee18,200 sats\(491,750 + 491,750 - 965,300\)
Fee rate100.0 sat/vBClean round number

Both inputs spend from vanity P2TR addresses whose bech32m encoding begins with bc1ptapr00t—literally spelling "taproot" in the address. These were bruteforced by grinding key pairs until the bech32m encoding produced the desired prefix. On Taproot's activation day, these vanity addresses served as a celebration and demonstration of the new address format.

12.2Two Inputs, Two Spending Paths

This transaction has two inputs, both spending from the same parent transaction but from different outputs (vout 0 and vout 1). The critical difference is in their witnesses:

Input 0Input 1
Spending pathKey pathScript path
Witness items13
Witness data64-byte Schnorr sig64-byte sig + 34-byte TapScript + 65-byte control block
Witness bytes66167

Input 0 is a key path spend—identical to Chapter 11. The witness contains a single 64-byte Schnorr signature verified against the output key. We parsed this pattern thoroughly in the previous chapter.

Input 1 is a script path spend—the subject of this chapter. Its witness contains three items, and parsing them will reveal the internal key, the Merkle proof, and the actual script being executed.

How Nodes Distinguish the Paths

The spending path is determined entirely by the witness structure (BIP 341):

No flag byte, no version field—just the element count.

12.3The Script Path Witness

Input 1's witness contains three items:

Witness for Input 1 (Script Path — 3 items)

Item count: 03 (3 items)

Item 0 — Schnorr signature (64 bytes):

7b 5d 61 4a 46 10 bf 91 96 77 57 91 fc c5 89 59

7c a0 66 dc d1 00 48 e0 04 cd 4c 73 41 bb 4b b9

0c ee 47 05 19 2f 3f 7d b5 24 e8 06 7a 52 22 c7

f0 9b af 29 ef 6b 80 5b 83 27 ec d1 e5 ab 83 ca

Item 1 — TapScript (34 bytes):

20 f5 b0 59 b9 a7 22 98 cc be ff f5 9d 9b 94 3f

7e 0f c9 1d 8a 3b 94 4a 95 e7 b6 39 0c c9 9e b5

f4 ac

Item 2 — Control block (65 bytes):

c0 d9 df df 0f e3 c8 3e 98 70 09 5d 67 ff f5 9a

80 56 da d2 8c 6d fb 94 4b b7 1c f6 4b 90 ac e9

a7 77 6b 22 a1 18 5f b2 dc 95 24 f6 b1 78 e2 69

31 89 bf 01 65 5d 7f 38 f0 43 92 36 68 dc 5a f4

5b

The three items are processed in reverse order during verification:

  1. The control block (last item) provides the internal key and Merkle proof to reconstruct the output key \(Q\).
  2. The TapScript (second-to-last) is the script being executed.
  3. The signature (and any other preceding items) are the inputs to that script—pushed onto the stack before execution.

12.4The TapScript

The 34-byte TapScript is:

HexOpcodeMeaning
20OP_PUSHBYTES_32Push next 32 bytes
f5b059b9…9eb5f4x-only pubkey32-byte public key
acOP_CHECKSIGVerify Schnorr signature

This is the simplest possible TapScript: push a public key, check a signature. It is functionally identical to the P2PK scripts of Chapter 4—but with x-only keys and Schnorr signatures instead of uncompressed keys and ECDSA.

Execution proceeds as follows: the 64-byte Schnorr signature (witness item 0) is on the stack. The TapScript pushes the 32-byte public key, then OP_CHECKSIG pops both and verifies the Schnorr signature against the key. If valid, OP_TRUE is pushed; the script succeeds.

OP_CHECKSIG in TapScript \(\neq\) OP_CHECKSIG in Legacy

Although both use the opcode 0xac, OP_CHECKSIG behaves differently in TapScript (BIP 342):

12.5The Control Block

The 65-byte control block carries everything the verifier needs to reconstruct the output key from the TapScript:

FieldSizeValue
Leaf version + parity1 Bc0
Internal key \(P\)32 Bd9dfdf0f… ace9a7
Merkle sibling hash32 B776b22a1…5af45b

12.5.1The First Byte: Leaf Version and Parity

The first byte c0 encodes two pieces of information:

12.5.2The Internal Key

The next 32 bytes are the internal key \(P\) (x-only):

d9dfdf0f e3c83e98 70095d67 fff59a80 56dad28c 6dfb944b b71cf64b 90ace9a7

This is the key that was hidden during key path spending. In a key path spend (Input 0), the internal key is never revealed—only the tweaked output key \(Q\) appears. In a script path spend, the internal key must be disclosed so the verifier can recompute the tweak and confirm that \(Q = P + tG\).

12.5.3The Merkle Proof

The remaining bytes are the Merkle proof: a sequence of 32-byte hashes, one per level of the tree. Our specimen has exactly one hash:

776b22a1 185fb2dc 9524f6b1 78e26931 89bf0165 5d7f38f0 43923668 dc5af45b

This tells us the tree has two leaves—the TapScript we are executing and one sibling script. The sibling script is never revealed. We know only its hash, which is all we need to reconstruct the Merkle root.

Control Block Size = Tree Depth

The control block is always \(33 + 32d\) bytes, where \(d\) is the depth of the executed leaf in the Merkle tree. For our specimen: \(33 + 32 \times 1 = 65\) bytes (depth 1, two-leaf tree). A deeper tree with 8 leaves would have \(d = 3\) and a control block of \(33 + 96 = 129\) bytes. The maximum depth is 128 (BIP 341), giving a theoretical control block of \(33 + 4,096 = 4,129\) bytes—but in practice, trees rarely exceed depth 4 or 5.

12.6Building the Merkle Tree

To verify the script path spend, the node must reconstruct the Merkle root from the TapScript and the Merkle proof, then verify that the output key \(Q\) commits to that root. The construction uses two tagged hashes.

12.6.1Step 1: TapLeaf Hash

Each leaf in the tree is hashed with the TapLeaf tag: \[ \text{TapLeaf}(s) = \text{tagged\_hash}(\texttt{"TapLeaf"},\; v \| \text{compact\_size}(|s|) \| s) \] where \(v\) is the leaf version byte and \(s\) is the TapScript.

For our specimen:

v = c0
s = 20f5b059… f4ac (34 bytes)
compact_size(34) = 22
TapLeaf(s) = tagged_hash("TapLeaf", c0 \| 22 \| s)

The resulting leaf hash is:

36471a88 c27bfaba f3f6ffd3 84fc7981 6b595d23 48f50f82 a08b4dde 15f2933e

12.6.2Step 2: TapBranch Hash

Internal nodes combine two children using the TapBranch tag. To ensure a canonical ordering (so the same tree always produces the same root regardless of construction order), the two children are sorted lexicographically: \[ \text{TapBranch}(a, b) = \text{tagged\_hash}(\texttt{"TapBranch"},\; \text{sort}(a, b)) \]

For our specimen, the two children are:

a = TapLeaf hash = 3647…933e
b = sibling hash = 776b… f45b

Since \(a < b\) lexicographically (both start with 3 vs 7), we concatenate \(a \| b\) and hash:

Merkle root = TapBranch(a, b)

= fc547ac3 bb0bc2d6 bfd4c647 e8342ad6 2ed89a15 b005ccc2 dde9efc4 cb8573f0

TapBranch Hash Computation
Merkle Root
= tagged_hash("TapBranch", a ‖ b)
fc547ac3 bb0bc2d6 bfd4c647 e8342ad6…
a = TapLeaf
3647…933e
b = Sibling
776b…f45b
a < b lexicographically → concatenate a ‖ b (canonical ordering)

12.7Verification: From Leaf to Output Key

With the Merkle root in hand, the verifier can now reconstruct the output key and confirm the commitment.

12.7.1Step 3: TapTweak

\[ t = \text{tagged\_hash}(\texttt{"TapTweak"},\; P_x \| \text{Merkle root}) \]

Using our internal key \(P_x\) = d9dfdf0f… ace9a7 and the Merkle root computed above: \[ t = \texttt{cba3d466\;138a3e99\;b46db0de\;59356ee2\;aedbcaa8\;b3862098\;4e0d0205\;3153b335} \]

12.7.2Step 4: Reconstruct the Output Key

\[ Q' = P + t \cdot G \]

Lifting \(P_x\) to a full curve point (even \(y\)) and computing the scalar multiplication: \[ Q'_x = \texttt{5f4237bd\;7f93c694\;03a30c6b\;641f27cc\;f5201090\;152fcf15\;96474221\;307831c3} \]

12.7.3Step 5: Compare with the Output

The prevout scriptPubKey for Input 1 is: 51 (OP_1) 20 (push 32) 5f4237bd … 307831c3 (output key \(Q\))

The output key \(Q\) from the scriptPubKey matches \(Q'\) exactly: \[ Q'_x = Q_x \]

The script was indeed committed to by the output key. The verifier now executes the TapScript with the provided witness inputs (the Schnorr signature) and, if the script succeeds, the spend is valid.

Control Block Verification
1. Extract internal key P from control block
2. Hash the leaf script → TapLeaf hash
3. Walk Merkle path using siblings → compute root
4. Compute Q' = P + tagged_hash("TapTweak", P ‖ root)·G
5. Q'x == Qx ? ✓ Script committed

12.8The Hidden Sibling

Our specimen reveals the executed TapScript (<pubkey> OP_CHECKSIG) and one Merkle sibling hash (776b… f45b). But what is the sibling script? We have no idea. The hash is all that was revealed. It could be:

This is Taproot's privacy innovation: unused branches remain invisible. Compare with P2SH (Chapter 6) and P2WSH (Chapter 10), where the entire redeem/witness script is revealed when any branch is executed. A P2WSH 2-of-3 multisig reveals all three public keys, even though only two signed. A Taproot script tree reveals only the leaf that was used.

TypeWhat's revealed at spendWhat remains hidden
P2SHEntire redeem script (all keys, all conditions)Nothing
P2WSHEntire witness script (all keys, all conditions)Nothing
P2TR key pathNothing (just a signature)Internal key, all scripts
P2TR script pathOne script leaf + Merkle proof + internal keyAll other script leaves

For a tree with \(n\) leaves, a script path spend reveals 1 leaf and \(\log_2 n\) hashes. The remaining \(n - 1\) leaves stay hidden. An 8-leaf tree reveals 1 script and 3 hashes; the other 7 scripts remain private.

12.9OP_CHECKSIGADD: Taproot's Multisig

Our specimen uses a simple single-key TapScript, but Tapscript introduces a new opcode for multi-signature schemes: OP_CHECKSIGADD (0xba).

In legacy and SegWit v0 scripts, \(m\)-of-\(n\) multisig used OP_CHECKMULTISIG, which had two problems:

  1. The off-by-one bug requiring a dummy OP_0 (Chapter 7).
  2. \(O(m \times n)\) signature checking: each of \(m\) signatures is tested against potentially all \(n\) public keys.

OP_CHECKSIGADD takes a different approach. It pops three items: a public key, a signature, and a running counter. It verifies the signature against the key; if valid, it increments the counter. A 2-of-3 multisig TapScript looks like:

2-of-3 TapScript using OP_CHECKSIGADD
Push first public key (32 B x-only)
OP_CHECKSIGCheck sig against key_1; push 1 or 0
Push second public key
OP_CHECKSIGADDCheck sig against key_2; add result to counter
Push third public key
OP_CHECKSIGADDCheck sig against key_3; add result to counter
OP_2Push threshold \(m = 2\)
OP_NUMEQUALCounter \(?=\) 2

Each key is checked independently against its corresponding signature. Invalid signatures push an empty byte array (which callers must provide explicitly—no implicit skipping). The counter accumulates the valid signature count, and the final OP_NUMEQUAL checks whether enough signatures were collected.

Why Not Just MuSig2?

If all \(n\) parties are available to cooperate, MuSig2 key aggregation (Chapter 11) compresses the \(n\)-of-\(n\) case into a single key path spend—no script needed at all. OP_CHECKSIGADD is for the \(m\)-of-\(n\) case where \(m < n\), or for complex policies where key aggregation isn't applicable (e.g., combining timelocks with multisig). The script path is the fallback when cooperative key aggregation fails or doesn't apply.

12.10Larger Trees

Our specimen has a two-leaf tree, but real-world P2TR outputs can encode far more complex policies. Consider a wallet with three spending conditions:

  1. Key path: Alice and Bob cooperate (MuSig2 aggregate key).
  2. Leaf A: Alice alone (after a 30-day timelock).
  3. Leaf B: Bob alone (after a 90-day timelock).
  4. Leaf C: 2-of-3 with a recovery key.

The tree structure:

Merkle Root
TapBranch
Leaf C
2-of-3 recovery
Leaf A
Alice after 30 days
Leaf B
Bob after 90 days
Most likely fallback closest to root → shorter control block → fewer bytes

If Leaf A is executed (Alice spending after 30 days), the control block contains:

Total control block: \(33 + 64 = 97\) bytes. Leaf B and Leaf C remain hidden—their scripts are never revealed.

Tree Design Matters

The position of a leaf in the tree affects the size of its Merkle proof. Leaves closer to the root have shorter proofs (fewer sibling hashes). Wallet designers should place the most likely spending conditions near the root and unlikely fallbacks deeper in the tree. This minimizes fees in the common case while keeping fallback options available.

12.11Script Path Weight Analysis

How does a script path spend compare to a key path spend in weight?

Witness componentKey pathScript path (depth 1)
Item count1 B1 B
Signature (+ length prefix)1 + 64 = 65 B1 + 64 = 65 B
TapScript (+ length prefix)1 + 34 = 35 B
Control block (+ length prefix)1 + 65 = 66 B
Total witness66 B167 B

The script path witness is 101 bytes larger—all in witness weight (1 WU per byte). For a single-input transaction, this adds 25 vbytes. The extra cost is the "insurance premium" for the ability to fall back to a script when the key path fails.

In the key path case, the entire script tree is free—it exists only as a commitment in the tweak, consuming zero bytes on-chain. This is the fundamental insight of Taproot: you only pay for the complexity you actually use.

12.12What We Learned

12.12.1Looking Ahead

With Parts I through IV complete, we have parsed every major Bitcoin output type—from Satoshi's original P2PK to Taproot's script path. Part V turns to special transactions: coinbase rewards, data embedding, timelocks, fee management, and the protocol-layer constructions (Lightning, Ordinals, Runes) that build on the primitives we have studied.

Exercises

Litmus (L)

  1. How does a Bitcoin node distinguish between a key path spend and a script path spend in a P2TR witness?
  2. What three items does the witness contain for a script path spend? In what order are they processed during verification?
  3. What is the size formula for a control block? What does each component contribute?
  4. Why does OP_CHECKSIG in TapScript use Schnorr verification instead of ECDSA?
  5. In our specimen, the Merkle sibling hash is 776b… f45b. What does this hash represent? What can we learn about the corresponding script?

Hands-On (H)

  1. Compute the stripped size, weight, and vsize of our specimen from the raw hex. Verify the values in the chapter's table.
  2. Parse the control block byte by byte: identify the leaf version, the parity bit, the internal key, and the Merkle sibling hash.
  3. Verify the TapLeaf hash computation. Using the tagged hash formula, compute \(\text{tagged\_hash}(\texttt{"TapLeaf"},\; \texttt{c0} \| \texttt{22} \| \textit{tapscript})\) and confirm it equals 36471a88…15f2933e.
  4. What is the maximum number of leaves in a Taproot script tree? What is the maximum control block size? (Hint: BIP 341 limits the Merkle proof to 128 hashes.)

Proofs and Reasoning (P)

  1. Prove that the lexicographic sorting in the TapBranch construction guarantees that two trees with the same leaves (but constructed in different order) produce the same root hash.
  2. Explain why the parity bit in the control block is necessary. What would go wrong if the verifier assumed an even \(y\)-coordinate for the output key without checking?
  3. Prove that revealing the Merkle proof for one leaf does not reveal the scripts of any other leaf. Under what cryptographic assumption does this privacy guarantee hold?

Connections (C)

  1. Tree design. You are building a wallet with four spending conditions: (A) cooperative \(n\)-of-\(n\) key path, (B) primary signer with 7-day timelock, (C) backup 2-of-3 multisig, (D) emergency recovery after 365 days. Design the optimal Merkle tree, explaining your depth choices. How many bytes does each control block cost?
  2. Ordinals connection. How does the Ordinals inscription protocol (Chapter 19) use the script path to embed arbitrary data? Why is the witness discount especially important for inscriptions?

Bridge (B)

  1. Chapter 14 covers coinbase transactions. The coinbase has no regular inputs—its "input" is a null reference. Does a coinbase transaction ever use Taproot? What would a P2TR coinbase output look like?
  2. Compare the privacy properties of P2TR script path spending with Lightning Network commitment transactions (Chapter 18). Which reveals more about the underlying contract structure?

Solutions

L1. By the witness stack size. If the witness contains exactly 1 element (64 or 65 bytes), it is a key path spend—the element is a Schnorr signature. If the witness contains 2 or more elements, it is a script path spend—the last element is the control block, the second-to-last is the TapScript, and all preceding elements are inputs to the script.

L2. The three items are: (1) script inputs (e.g., signatures), (2) the TapScript being executed, (3) the control block (internal key + Merkle proof). During verification, the control block is processed first (to reconstruct and verify the output key commitment), then the TapScript is executed with the script inputs on the stack.

L3. \(33 + 32d\) bytes, where \(d\) is the depth of the executed leaf. The first byte is the leaf version + parity bit (1 B), the next 32 bytes are the internal key, and each of the \(d\) Merkle proof levels contributes 32 bytes.

L4. Because TapScript (BIP 342) uses the Taproot execution context, which is defined by BIP 340/341 to use Schnorr signatures. The legacy OP_CHECKSIG used ECDSA because that was the only signature scheme available. Schnorr signatures are fixed-length (64 bytes), non-malleable, and support batch verification and key aggregation—properties ECDSA lacks.

L5. The hash represents a second TapScript leaf in the Merkle tree—a sibling of the executed script. We can learn nothing about the actual script it contains. The hash is a SHA-256 commitment (via the TapLeaf tagged hash); without a preimage, the script is completely hidden. This is by design: only the executed branch is revealed.

H1. From the raw hex (358 bytes total):

H2. The 65-byte control block:

The control block has one 32-byte hash, indicating a tree of depth 1 (two leaves).

H3. The tagged hash formula is:

\[ \text{tagged\_hash}(\text{tag}, m) = \text{SHA-256}(\text{SHA-256}(\text{tag}) \| \text{SHA-256}(\text{tag}) \| m) \]

With \(\text{tag} = \texttt{"TapLeaf"}\) and \(m = \texttt{c0} \| \texttt{22} \| \texttt{20f5b059\ldots f4ac}\) (36 bytes total: 1 + 1 + 34):

  1. Compute \(h = \text{SHA-256}(\texttt{"TapLeaf"})\).
  2. Compute \(\text{SHA-256}(h \| h \| m)\).

Result: 36471a88 c27bfaba f3f6ffd3 84fc7981 6b595d23 48f50f82 a08b4dde 15f2933e.

This was verified computationally using Python's hashlib.sha256.

H4. BIP 341 limits the Merkle proof to 128 hashes (depth 128). Maximum leaves: \(2^{128}\) (astronomically large—far more than any practical application). Maximum control block: \(33 + 32 \times 128 = 33 + 4,096 = 4,129\) bytes.

P1. Let \(a\) and \(b\) be two leaf hashes. TapBranch computes \(H((a,b) \| (a,b))\).

Case 1: Tree built with \(a\) as left child, \(b\) as right: \(H((a,b) \| (a,b))\).

Case 2: Tree built with \(b\) as left, \(a\) as right:
\(H((b,a) \| (b,a)) = H((a,b) \| (a,b))\).

Since \(\text{sort}\) and \(\|\) are symmetric operations, both cases produce identical inputs to the hash. The root is the same regardless of construction order. This extends inductively to all levels: at each TapBranch node, the two children are sorted before hashing.

P2. The verifier reconstructs \(Q' = P + tG\) from the internal key \(P\) and the tweak \(t\). The resulting point \(Q'\) has some \(y\)-coordinate that is either even or odd. The output key \(Q\) on-chain is stored as an x-only key (32 bytes, no parity information). Two distinct curve points share the same \(x\)-coordinate: \((x, y)\) and \((x, p - y)\).

Without the parity bit, the verifier would not know which of these two points is \(Q\). If the verifier chose the wrong one, the comparison \(Q' ?= Q\) would fail even for a legitimate spend. The parity bit (bit 0 of the control block's first byte) resolves this ambiguity: it tells the verifier which square root to select when lifting \(Q_x\) to a full point. If parity is 0, \(Q\) has even \(y\); if 1, odd \(y\).

P3. The Merkle proof for leaf \(i\) reveals the hashes along the path from leaf \(i\) to the root. At each level, the sibling hash is disclosed. However, each sibling hash is the output of \(\text{tagged\_hash}(\texttt{"TapBranch"}, \ldots)\) or \(\text{tagged\_hash}(\texttt{"TapLeaf"}, \ldots)\).

Finding the preimage of a tagged hash requires breaking the preimage resistance of SHA-256: given \(h = \text{SHA-256}(m)\), find \(m\). This is computationally infeasible under the assumption that SHA-256 is a secure hash function (preimage resistance: \(2^{256}\) work).

Therefore, knowing a sibling hash reveals nothing about the sibling's script content. The privacy guarantee holds under the preimage resistance of SHA-256.

C1. Optimal tree design for four conditions (A is key path, B/C/D are scripts):

Suggested tree (depth-weighted by probability):

Probability-Weighted Taproot Tree
Root
B: primary + 7d
depth 1 (most likely)
Branch
A: Alice solo
depth 2
C: 2-of-3
depth 2 (least likely)
Key path (Alice+Bob): no tree needed — just P
Most likely fallback at depth 1 → shortest control block

Control block sizes: Leaf B: \(33 + 32 = 65\) bytes (depth 1). Leaf C or D: \(33 + 64 = 97\) bytes (depth 2). The most likely fallback (B) has the cheapest proof.

C2. The Ordinals protocol creates a TapScript containing an "envelope":

OP_FALSE OP_IF OP_ENDIF

The OP_FALSE OP_IF … OP_ENDIF block is never executed (dead code), but the data is part of the TapScript and thus committed to by the Merkle tree. The inscription is "revealed" by spending via the script path, which discloses the TapScript (including the embedded data) in the witness.

The witness discount is critical: witness data costs 1 WU per byte vs 4 WU for non-witness. An inscription of 100 KB costs 100,000 WU in the witness vs 400,000 WU if it were in the non-witness part. This \(4\times\) discount makes large data embeddings economically viable within the 4,000,000 WU block weight limit.

B1. A coinbase transaction creates outputs but has no regular inputs to spend. The coinbase output can be any valid scriptPubKey type, including P2TR. A P2TR coinbase output would be 34 bytes: OP_1 <32-byte output key>. The miner would later spend it via key path (single Schnorr sig) or script path. As Taproot adoption increased, many mining pools switched their coinbase outputs from P2PKH or P2SH to P2TR for the privacy and flexibility benefits.

B2. Lightning commitment transactions use P2WSH outputs that reveal the full witness script when spent. A force-close reveals the complete HTLC structure, including timelocks, revocation keys, and payment hashes—exposing the channel's internal mechanics. P2TR script path reveals only the executed leaf; unused conditions (other timelocks, other HTLCs) remain hidden. This is why Lightning implementations are migrating to Taproot channels ("simple taproot channels")—force-closes reveal less about the channel structure, improving privacy even in adversarial scenarios.

← Ch. 11 Ch. 13 →