Genesis setup for the system contracts that blocks call from Cancun on.
| EIP | From | Address | Called |
|---|---|---|---|
| EIP-4788 beacon roots | Cancun | 0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02 | block start |
| EIP-2935 block hashes | Prague | 0x0000F90827F1C53a10cb7A02335B175320002935 | block start |
| EIP-7002 withdrawal requests | Prague | 0x00000961Ef480Eb55e80D19ad83579A64c007002 | block end |
| EIP-7251 consolidation requests | Prague | 0x0000BBdDc7CE488642fb579F8B00f3a590007251 | block end |
On mainnet each contract was deployed by an ordinary transaction before its
fork activated. A chain started from scratch, such as a devnet or a test,
has no such history, so genesis_accounts/1 returns the contracts a fork
calls as genesis accounts, and install/2 writes them into a database.
Block execution never installs them itself: a Prague block whose state
lacks the EIP-7002 or EIP-7251 contract fails with :system_contract_empty,
as those EIPs require. A missing EIP-4788 or EIP-2935 contract makes its
block-start call a no-op. EEVM.SystemContracts.BeaconRoots and
EEVM.SystemContracts.BlockHashes drive and read those two contracts.
Summary
Functions
Returns the system contracts that blocks of fork call, as genesis accounts
in the shape EEVM.Database.InMemory.new/1 takes:
%{address => %{balance: 0, nonce: 1, code: code}}.
Writes the accounts genesis_accounts/1 returns for fork into db,
replacing any accounts at those addresses but keeping their storage.
Functions
@spec genesis_accounts(EEVM.Config.t() | EEVM.HardforkConfig.spec_id()) :: %{ required(non_neg_integer()) => %{balance: 0, nonce: 1, code: binary()} }
Returns the system contracts that blocks of fork call, as genesis accounts
in the shape EEVM.Database.InMemory.new/1 takes:
%{address => %{balance: 0, nonce: 1, code: code}}.
fork is an EEVM.Config or a hardfork name. Each contract is included
from the fork that activates its EIP, with its canonical deployed code and
the nonce of 1 that its deployment left on mainnet, so state roots match
other clients'. Forks before Cancun need none.
Examples
iex> EEVM.SystemContracts.genesis_accounts(:prague) |> Map.keys() |> Enum.sort()
[
0x00000961EF480EB55E80D19AD83579A64C007002,
0x0000BBDDC7CE488642FB579F8B00F3A590007251,
0x0000F90827F1C53A10CB7A02335B175320002935,
0x000F3DF6D732807EF1319FB7B8BB8522D0BEAC02
]
iex> EEVM.SystemContracts.genesis_accounts(EEVM.Config.new(:cancun))
%{0x000F3DF6D732807EF1319FB7B8BB8522D0BEAC02 => %{balance: 0, nonce: 1,
code: EEVM.SystemContracts.BeaconRoots.deployed_bytecode()}}
iex> EEVM.SystemContracts.genesis_accounts(:shanghai)
%{}
@spec install(EEVM.Database.t(), EEVM.Config.t() | EEVM.HardforkConfig.spec_id()) :: EEVM.Database.t()
Writes the accounts genesis_accounts/1 returns for fork into db,
replacing any accounts at those addresses but keeping their storage.
Example
iex> db = EEVM.SystemContracts.install(EEVM.Database.InMemory.new(), :prague)
iex> EEVM.Database.get_nonce(db, 0x00000961EF480EB55E80D19AD83579A64C007002)
1