diff --git a/contracts/utils/Blockhash.sol b/contracts/utils/Blockhash.sol index db8eaac2a..cb16cd634 100644 --- a/contracts/utils/Blockhash.sol +++ b/contracts/utils/Blockhash.sol @@ -14,6 +14,7 @@ pragma solidity ^0.8.20; * Before that, only block hashes since the fork block will be available. */ library Blockhash { + /// @dev Address of the EIP-2935 history storage contract. address internal constant HISTORY_STORAGE_ADDRESS = 0x0000F90827F1C53a10cb7A02335B175320002935; /** diff --git a/contracts/utils/README.adoc b/contracts/utils/README.adoc index 5151b4616..74b26b236 100644 --- a/contracts/utils/README.adoc +++ b/contracts/utils/README.adoc @@ -45,6 +45,7 @@ Miscellaneous contracts and libraries containing utility functions you can use t * {Panic}: A library to revert with https://docs.soliditylang.org/en/v0.8.20/control-structures.html#panic-via-assert-and-error-via-require[Solidity panic codes]. * {Comparators}: A library that contains comparator functions to use with the {Heap} library. * {CAIP2}, {CAIP10}: Libraries for formatting and parsing CAIP-2 and CAIP-10 identifiers. + * {Blockhash}: A library for accessing historical block hashes beyond the standard 256 block limit utilizing EIP-2935's historical blockhash functionality. [NOTE] ==== @@ -156,3 +157,5 @@ Ethereum contracts have no native concept of an interface, so applications must {{CAIP2}} {{CAIP10}} + +{{Blockhash}} diff --git a/docs/modules/ROOT/pages/utilities.adoc b/docs/modules/ROOT/pages/utilities.adoc index f6b22b025..04cb2ee43 100644 --- a/docs/modules/ROOT/pages/utilities.adoc +++ b/docs/modules/ROOT/pages/utilities.adoc @@ -386,3 +386,22 @@ await instance.multicall([ instance.interface.encodeFunctionData("bar") ]); ---- + +=== Historical Block Hashes + +xref:api:utils.adoc#Blockhash[`Blockhash`] provides L2 protocol developers with extended access to historical block hashes beyond Ethereum's native 256-block limit. By leveraging https://eips.ethereum.org/EIPS/eip-2935[EIP-2935]'s history storage contract, the library enables access to block hashes up to 8,191 blocks in the past, making it invaluable for L2 fraud proofs and state verification systems. + +The library seamlessly combines native `BLOCKHASH` opcode access for recent blocks (≤256) with EIP-2935 history storage queries for older blocks (257-8,191). It handles edge cases gracefully by returning zero for future blocks or those beyond the history window, matching the EVM's behavior. The implementation uses gas-efficient assembly for static calls to the history storage contract. + +[source,solidity] +---- +contract L1Inbox { + using Blockhash for uint256; + + function verifyBlockHash(uint256 blockNumber, bytes32 expectedHash) public view returns (bool) { + return blockNumber.blockHash() == expectedHash; + } +} +---- + +IMPORTANT: After EIP-2935 activation, it takes 8,191 blocks to completely fill the history storage. Before that, only block hashes since the fork block will be available.