# 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.