ethereum.state

Shared state model and the PreState protocol used by the state transition function.

The PreState protocol specifies the operations that any pre-execution state provider must support, allowing multiple backing implementations (in-memory dict, on-disk database, witness, etc.). This module is commitment-agnostic: it defines what state is, not how it is committed to. The Merkle-Patricia-Trie-backed in-memory implementation lives in ethereum.state_mpt.

There is a distinction between an account that does not exist and EMPTY_ACCOUNT.

Address

33
Address = Bytes20

Root

34
Root = Hash32

EMPTY_CODE_HASH

36
EMPTY_CODE_HASH = keccak256(b"")

Account

State associated with an address.

39
@final
40
@slotted_freezable
41
@dataclass
class Account:

nonce

47
    nonce: Uint

balance

48
    balance: U256

code_hash

49
    code_hash: Hash32

EMPTY_ACCOUNT

52
EMPTY_ACCOUNT = Account(
53
    nonce=Uint(0),
54
    balance=U256(0),
55
    code_hash=EMPTY_CODE_HASH,
56
)

BlockDiff

State changes produced by executing a block.

59
@final
60
@dataclass
class BlockDiff:

account_changes

Per-address account diffs produced by execution.

66
    account_changes: Dict[Address, Optional[Account]] = field(
67
        default_factory=dict
68
    )

storage_changes

Per-address storage diffs produced by execution.

71
    storage_changes: Dict[Address, Dict[Bytes32, U256]] = field(
72
        default_factory=dict
73
    )

code_changes

New bytecodes (keyed by code hash) introduced by execution.

76
    code_changes: Dict[Hash32, Bytes] = field(default_factory=dict)

storage_clears

Addresses whose pre-existing storage was wiped during block execution (via a pre-EIP-6780 SELFDESTRUCT). Their storage tries are dropped before storage_changes is applied, so any post-wipe writes begin from empty storage.

79
    storage_clears: Set[Address] = field(default_factory=set)

PreState

Protocol for providing pre-execution state.

Specify the operations that any pre-state provider (dict, database, witness, etc.) must support for the EELS state transition.

class PreState:

get_account_optional

Get the account at an address.

Return None if there is no account at the address.

def get_account_optional(self, ​​address: Address) -> Optional[Account]:
99
        <snip>
104
        ...

get_storage

Get a storage value.

Return U256(0) if the key has not been set.

def get_storage(self, ​​address: Address, ​​key: Bytes32) -> U256:
107
        <snip>
112
        ...

get_code

Get the bytecode for a given code hash.

Return b"" for EMPTY_CODE_HASH.

def get_code(self, ​​code_hash: Hash32) -> Bytes:
115
        <snip>
120
        ...

account_has_storage

Check whether an account has any storage.

Only needed for EIP-7610.

def account_has_storage(self, ​​address: Address) -> bool:
123
        <snip>
128
        ...

compute_state_root

Compute the state root after applying block_diff to the pre-state. The pre-state itself is not modified.

The diff carries bytecode deployed during the block in code_changes, keyed by code hash. Commitments over code hashes alone can ignore it; a commitment over code contents resolves each account's bytecode through its code_hash, joining account_changes to code_changes, because the new bytecode is not yet in the provider's code store when the root is computed.

Return the new state root.

def compute_state_root(self, ​​block_diff: BlockDiff) -> Root:
131
        <snip>
145
        ...