Skip to main content
Steel retrieves state for a view call at a specific block, therefore it commits the relevant block data to the journal for validation onchain; this data is known as a Steel commitment. Concretely, a Steel commitment consists of a block identifier, and the block hash. To validate this block commitment onchain, the block hash in the commitment is compared with the block hash available onchain. If there is a discrepancy, there is no guarantee that the proof accurately reflects the correct blockchain state at the specified block.

Steel’s Trust Anchor: The Blockhash

Steel uses revm to generate an EVM execution environment, EvmEnv within the guest. When you create the EvmEnv, you can specify a block (the default is the latest block).
This block is used for RPC queries (i.e. getStorageAt) during the preflight call. Once the preflighting is done, into_input is called:
During this into_input step, the preflight data is packed into a form that can be read and validated in the guest. Crucially, during the step, Steel will use the RPC call eth_getProof for all accounts accessed during the preflight and the return data is combined into a sparse Merkle trie. Within the guest, calling into_env checks that all Merkle tries are consistent, have the correct root and computes the corresponding block hash. This blockhash is Steel’s trust anchor; it needs to be recomputed within the guest to validate the integrity of the RPC data.
For the Steel commitment, it is this block hash, computed within the guest, that is committed to the journal:
This block hash has to be compared onchain, alongside the verification of the proof, to validate that the Steel proof is correct and to verify the integrity of RPC data.

What is a Steel Commitment?

A commitment consists of two values: the block ID and the block digest. The block ID encodes two values, the Steel version number and a block identifier (e.g. a block number).
In the increment function in the Counter contract, we saw this require statement:
The Steel library contains the function validateCommitment :

Validation of Steel Commitments

Steel supports two methods of commitment validation (see validateCommitment in Steel.sol); This validation onchain is essential to ensure that the proof accurately reflects the correct blockchain state.
  1. Block hash commitment
This method uses the blockhash opcode to commit to a block hash that is no more than 256 blocks old. With Ethereum’s 12-second block time, this provides a window of about 50 minutes to generate the proof and ensure that the validating transaction is contained in a block. This approach will work for most scenarios, including complex computations, as it typically provides sufficient time to generate the proof.
  1. Beacon Block Root Commitment
The second method allows validation using the EIP-4788 beacon roots contract. This technique extends the time window in which the proof can be validated onchain to just over a day. It requires access to a beacon API endpoint and can be enabled by calling EvmEnv::builder().beacon_api(). However, this approach is specific to Ethereum (L1) Steel proofs and depends on the implementation of EIP-4788. Note that EIP-4788 only provides access to the parent beacon root, requiring iterative queries in Solidity to retrieve the target beacon root for validation. This iterative process can result in slightly higher gas costs compared to using the blockhash opcode. Overall, it is suitable for environments where longer proof generation times are required.