Skip to main content

Inclusion Proofs

In general, Merkle proofs are used to prove that a piece of data is part of a larger set without having to provide the entire set. In Bolt, we use Merkle inclusion proofs because they are a fast and efficient way to prove that a transaction is included in a block.

In the context of Ethereum, almost all data in block headers is hashed and stored in a Merkle tree of some sort. In particular, post-merge Ethereum uses Merkle-Patricia-Tries (MPTs) to store account and storage data, and SimpleSerialize Merkleized containers to store commitments to other data, such as transactions and withdrawals. Inclusion proofs can be produced for both MPT and SSZ types, and the same principles apply to both.


Transaction Inclusion Proofs

Since each ExecutionPayloadHeader contains the TransactionsRoot SSZ Container, we can generate SSZ Merkle inclusion proofs for transactions to prove that they are in fact included in a block without having to unblind the entire block.

This way, proposers know that they are about to sign a block that fulfills all the constraints they have committed to!

As a bonus, we can even prove the index at which a specific transaction was included, because in the proof we need to provide the GeneralizedIndex corresponding to the HashTreeRoot of the transaction, which is a direct commitment to it.