Last active
May 8, 2025 15:53
-
-
Save pcaversaccio/64c7829e0c7ed4eeb1e5a07e2177836c to your computer and use it in GitHub Desktop.
Historical block hashes oracle Vyper contract.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# pragma version ~=0.4.1 | |
""" | |
@title Historical Block Hashes Oracle | |
@custom:contract-name block_hash_oracle | |
@license GNU Affero General Public License v3.0 only | |
@author pcaversaccio | |
@notice The contract function `block_hash` can be used to access the | |
historical block hashes beyond the default 256-block limit. | |
We use the EIP-2935 (https://eips.ethereum.org/EIPS/eip-2935) | |
history contract, which maintains a ring buffer of the last | |
8,191 block hashes stored in state: | |
- For blocks within the last 256 blocks, the function `block_hash` | |
uses the native `BLOCKHASH` opcode. | |
- For blocks between 257 and 8,191 blocks ago, the function | |
`block_hash` queries the EIP-2935 history contract using the | |
specified `get` method: https://eips.ethereum.org/EIPS/eip-2935#get. | |
- For blocks older than 8,191 blocks or future blocks (including the | |
current one), it returns zero, matching the `BLOCKHASH` behavior. | |
Please note that after EIP-2935 is activated, it takes 8,191 | |
blocks to fully populate the history. Before that, only block | |
hashes from the fork block onward are available. | |
""" | |
from snekmate.utils import block_hash as bh | |
@external | |
@view | |
def block_hash(block_number: uint256) -> bytes32: | |
""" | |
@dev Returns the block hash for block number `block_number`. | |
@notice For blocks older than 8,191 or future blocks (including | |
the current one), returns zero, matching the `BLOCKHASH` | |
behaviour. Furthermore, this function does verify if the | |
history contract is deployed. If the history contract is | |
undeployed, the function will fallback to the `BLOCKHASH` | |
behaviour. | |
@param block_number The 32-byte block number. | |
@return bytes32 The 32-byte block hash for block number `block_number`. | |
""" | |
return bh._block_hash(block_number) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Compilation Versions
Use Vyper version
0.4.1
and π snekmate commit96b0845
:After, save the gist code to a file called
block_hash_oracle.vy
and run:vyper block_hash_oracle.vy
Contract Creation Code
0x61015961001161000039610159610000f35f3560e01c63b509f4ef81186100315760243610341761015557602060043560e05261002c61014061009a565b610140f35b5f5ffd5b5a6040516080526020606052606050602060c0606051608071f90827f1c53a10cb7a02335b17532000293585fa9050610070573d5f5f3e3d5ffd5b3d602081183d602010021860a05260a0805160200360031b6020820151811c811b90509050815250565b4360e051106100ac575f815250610153565b60e0514303610100526101006101005111156101385761200061010051101561010b577f6e49e66782037c0555897870e29fa5e552daf4719552131a0abce779daec0a5d71f90827f1c53a10cb7a02335b1753200029353f141561010e565b60015b61012f5760e051604052610123610120610035565b61012051815250610153565b5f815250610153565b60e05161010043038112610155574381101561015557408152505b565b5f80fd8558205faae5cedd8d4098fc2e7250264ec7db93b093963b3583c968a0353969b14b2d1901598000a1657679706572830004010035
Standard
JSON
InputThe standard
JSON
input file can be retrieved via:vyper -f solc_json block_hash_oracle.vy > block_hash_oracle.json
Deployment via
CreateX
Call
deployCreate2(bytes32,bytes)
with the arguments:Deployments
0x0e04bDF212088405D1EF8abE507F644a87c17a84
0x0e04bDF212088405D1EF8abE507F644a87c17a84
Testing
You can test it on e.g. Sepolia by running: