Merkle Inclusion Proof
A cryptographic proof that a given transaction is included in a block's Merkle tree.
A merkle inclusion proof is the smallest data structure that lets a verifier confirm a specific transaction belongs in a given block, without having to download all the other transactions in that block. It exploits the merkle tree that Bitcoin builds over each block's transaction list.
How it works:
- Each block header commits to a single 32-byte merkle root, derived by pairwise hashing the block's transaction txids until one root remains.
- To prove transaction
Tis in blockB, you provideTitself plus the sibling hashes along the path fromT's leaf up to the root - typicallylog_2(N)hashes for a block with N transactions. - The verifier hashes
Twith its sibling, then that result with the next sibling, walking up the tree. - If the final hash matches the merkle root committed to in the block header,
Tis provably inB.
Proof size for typical Bitcoin blocks: ~10-12 sibling hashes (since blocks contain 2,000-3,000 transactions in busy times), so roughly 320-384 bytes plus the transaction itself. Vastly cheaper than fetching the entire block.
Where merkle inclusion proofs show up:
- SPV light clients. Wallets that don't validate the full chain ask trusted peers for block headers (verifying difficulty and chain continuity) plus merkle inclusion proofs for transactions they care about. The wallet trusts proof-of-work for the chain tip and verifies cryptographic proofs for individual transaction inclusion.
- Bitcoin Core's
gettxoutproofRPC. Produces an inclusion proof for one or more transactions; the companionverifytxoutproofvalidates it. - Various second-layer constructions. Sidechain pegs, drivechain proposals, BitVM, and similar designs use merkle inclusion proofs to commit one chain's state to another.
What inclusion proofs don't prove: that the transaction is valid (you'd need the block's full validation state), or that the chain itself is the canonical one (you'd need proof-of-work and ancestry). They prove only "this transaction is committed to in this block." That's a useful but limited primitive, and a building block in most light-client and cross-chain designs.
Key takeaways
- Links a transaction to the block's Merkle root using partial hashes
- Used by SPV clients for efficient verification
- Ensures no tampering occurred without downloading the full block