State
Table of Contents
Introduction
The state contains all information that is preserved between transactions.
It consists of a main account trie and storage tries for each contract.
There is a distinction between an account that does not exist and EMPTY_ACCOUNT.
Module Contents
Classes
Contains all information that is preserved between transactions. |
Functions
Free resources held by the state. Used by optimized implementations to |
|
Start a state transaction. |
|
Commit a state transaction. |
|
Rollback a state transaction, resetting the state to the point when the |
|
Get the Account object at an address. Returns EMPTY_ACCOUNT if there |
|
Get the Account object at an address. Returns None (rather than |
|
Set the Account object at an address. Setting to None deletes |
|
Completely remove the account at address and all of its storage. |
|
Completely remove the storage at address. |
|
Get a value at a storage key on an account. Returns U256(0) if the |
|
Set a value at a storage key on an account. Setting to U256(0) deletes |
|
Calculate the storage root of an account. |
|
Calculate the state root. |
|
Checks if an account exists in the state trie |
|
Checks if an account has non zero nonce or non empty code |
|
Checks if an account has zero nonce, empty code and zero balance. |
|
Checks if an account exists and has zero nonce, empty code and zero |
|
Check whether is an account is both in the state and non empty. |
|
Modify an Account in the State. |
|
Move funds between accounts. |
|
Sets the balance of an account. |
|
Initializes an account to state. |
|
Increments the nonce of an account. |
|
Sets Account code. |
|
Add newly created ether to an account. |
|
Get the original value in a storage slot i.e. the value before the current |
Module Details
State
Contains all information that is preserved between transactions.
- class State
- _main_trie :ethereum.constantinople.trie.Trie[ethereum.constantinople.fork_types.Address, Optional[ethereum.constantinople.fork_types.Account]]:ethereum.istanbul.trie.Trie[ethereum.istanbul.fork_types.Address, Optional[ethereum.istanbul.fork_types.Account]]
- _storage_tries :Dict[ethereum.constantinople.fork_types.Address, ethereum.constantinople.trie.Trie[ethereum.base_types.Bytes,:Dict[ethereum.istanbul.fork_types.Address, ethereum.istanbul.trie.Trie[ethereum.base_types.Bytes, ethereum.base_types.U256]]
- _snapshots :List[Tuple[ethereum.constantinople.trie.Trie[ethereum.constantinople.fork_types.Address, Optional[ethereum.constantinople.fork_types.Account]], Dict[ethereum.constantinople.fork_types.Address, ethereum.constantinople.trie.Trie[ethereum.base_types.Bytes,:List[Tuple[ethereum.istanbul.trie.Trie[ethereum.istanbul.fork_types.Address, Optional[ethereum.istanbul.fork_types.Account]], Dict[ethereum.istanbul.fork_types.Address, ethereum.istanbul.trie.Trie[ethereum.base_types.Bytes, ethereum.base_types.U256]]]]
close_state
- close_state(state)
Free resources held by the state. Used by optimized implementations to release file descriptors.
def close_state(state: State) -> None:
del state._main_trie
del state._storage_tries
del state._snapshots
begin_transaction
- begin_transaction(state)
Start a state transaction.
Transactions are entirely implicit and can be nested. It is not possible to calculate the state root during a transaction.
- Parameters
state (State) – The state.
def begin_transaction(state: State) -> None:
state._snapshots.append(
(
copy_trie(state._main_trie),
{k: copy_trie(t) for (k, t) in state._storage_tries.items()},
)
)
commit_transaction
def commit_transaction(state: State) -> None:
state._snapshots.pop()
rollback_transaction
- rollback_transaction(state)
Rollback a state transaction, resetting the state to the point when the corresponding start_transaction() call was made.
- Parameters
state (State) – The state.
def rollback_transaction(state: State) -> None:
state._main_trie, state._storage_tries = state._snapshots.pop()
get_account
- get_account(state, address)
Get the Account object at an address. Returns EMPTY_ACCOUNT if there is no account at the address.
Use get_account_optional() if you care about the difference between a non-existent account and EMPTY_ACCOUNT.
- Parameters
state (State) – The state
address (Address) – Address to lookup.
- Returns
account – Account at address.
- Return type
Account
def get_account(state: State, address: Address) -> Account:
account = get_account_optional(state, address)
if isinstance(account, Account):
return account
else:
return EMPTY_ACCOUNT
get_account_optional
- get_account_optional(state, address)
Get the Account object at an address. Returns None (rather than EMPTY_ACCOUNT) if there is no account at the address.
- Parameters
state (State) – The state
address (Address) – Address to lookup.
- Returns
account – Account at address.
- Return type
Account
def get_account_optional(state: State, address: Address) -> Optional[Account]:
account = trie_get(state._main_trie, address)
return account
set_account
- set_account(state, address, account)
Set the Account object at an address. Setting to None deletes the account (but not its storage, see destroy_account()).
- Parameters
state (State) – The state
address (Address) – Address to set.
account (Account) – Account to set at address.
def set_account(
state: State, address: Address, account: Optional[Account]
) -> None:
trie_set(state._main_trie, address, account)
destroy_account
- destroy_account(state, address)
Completely remove the account at address and all of its storage.
This function is made available exclusively for the SELFDESTRUCT opcode. It is expected that SELFDESTRUCT will be disabled in a future hardfork and this function will be removed.
- Parameters
state (State) – The state
address (Address) – Address of account to destroy.
def destroy_account(state: State, address: Address) -> None:
destroy_storage(state, address)
set_account(state, address, None)
destroy_storage
- destroy_storage(state, address)
Completely remove the storage at address.
- Parameters
state (State) – The state
address (Address) – Address of account whose storage is to be deleted.
def destroy_storage(state: State, address: Address) -> None:
if address in state._storage_tries:
del state._storage_tries[address]
get_storage
- get_storage(state, address, key)
Get a value at a storage key on an account. Returns U256(0) if the storage key has not been set previously.
- Parameters
state (State) – The state
address (Address) – Address of the account.
key (Bytes) – Key to lookup.
- Returns
value – Value at the key.
- Return type
U256
def get_storage(state: State, address: Address, key: Bytes) -> U256:
trie = state._storage_tries.get(address)
if trie is None:
return U256(0)
value = trie_get(trie, key)
assert isinstance(value, U256)
return value
set_storage
- set_storage(state, address, key, value)
Set a value at a storage key on an account. Setting to U256(0) deletes the key.
- Parameters
state (State) – The state
address (Address) – Address of the account.
key (Bytes) – Key to set.
value (U256) – Value to set at the key.
def set_storage(
state: State, address: Address, key: Bytes, value: U256
) -> None:
assert trie_get(state._main_trie, address) is not None
trie = state._storage_tries.get(address)
if trie is None:
trie = Trie(secured=True, default=U256(0))
state._storage_tries[address] = trie
trie_set(trie, key, value)
if trie._data == {}:
del state._storage_tries[address]
storage_root
- storage_root(state, address)
Calculate the storage root of an account.
- Parameters
state – The state
address – Address of the account.
- Returns
root – Storage root of the account.
- Return type
Root
def storage_root(state: State, address: Address) -> Root:
assert state._snapshots == []
if address in state._storage_tries:
return root(state._storage_tries[address])
else:
return EMPTY_TRIE_ROOT
state_root
- state_root(state)
Calculate the state root.
- Parameters
state – The current state.
- Returns
root – The state root.
- Return type
Root
def state_root(state: State) -> Root:
assert state._snapshots == []
def get_storage_root(address: Address) -> Root:
return storage_root(state, address)
return root(state._main_trie, get_storage_root=get_storage_root)
account_exists
- account_exists(state, address)
Checks if an account exists in the state trie
- Parameters
state – The state
address – Address of the account that needs to be checked.
- Returns
account_exists – True if account exists in the state trie, False otherwise
- Return type
bool
def account_exists(state: State, address: Address) -> bool:
return get_account_optional(state, address) is not None
account_has_code_or_nonce
- account_has_code_or_nonce(state, address)
Checks if an account has non zero nonce or non empty code
- Parameters
state – The state
address – Address of the account that needs to be checked.
- Returns
has_code_or_nonce – True if if an account has non zero nonce or non empty code, False otherwise.
- Return type
bool
def account_has_code_or_nonce(state: State, address: Address) -> bool:
account = get_account(state, address)
return account.nonce != Uint(0) or account.code != b""
is_account_empty
- is_account_empty(state, address)
Checks if an account has zero nonce, empty code and zero balance.
- Parameters
state – The state
address – Address of the account that needs to be checked.
- Returns
is_empty – True if if an account has zero nonce, empty code and zero balance, False otherwise.
- Return type
bool
def is_account_empty(state: State, address: Address) -> bool:
account = get_account(state, address)
return (
account.nonce == Uint(0)
and account.code == b""
and account.balance == 0
)
account_exists_and_is_empty
- account_exists_and_is_empty(state, address)
Checks if an account exists and has zero nonce, empty code and zero balance.
- Parameters
state – The state
address – Address of the account that needs to be checked.
- Returns
exists_and_is_empty – True if an account exists and has zero nonce, empty code and zero balance, False otherwise.
- Return type
bool
def account_exists_and_is_empty(state: State, address: Address) -> bool:
account = get_account_optional(state, address)
return (
account is not None
and account.nonce == Uint(0)
and account.code == b""
and account.balance == 0
)
is_account_alive
- is_account_alive(state, address)
Check whether is an account is both in the state and non empty.
- Parameters
state – The state
address – Address of the account that needs to be checked.
- Returns
is_alive – True if the account is alive.
- Return type
bool
def is_account_alive(state: State, address: Address) -> bool:
account = get_account_optional(state, address)
if account is None:
return False
else:
return not (
account.nonce == Uint(0)
and account.code == b""
and account.balance == 0
)
modify_state
- modify_state(state, address, f)
Modify an Account in the State.
def modify_state(
state: State, address: Address, f: Callable[[Account], None]
) -> None:
set_account(state, address, modify(get_account(state, address), f))
move_ether
- move_ether(state, sender_address, recipient_address, amount)
Move funds between accounts.
def move_ether(
state: State,
sender_address: Address,
recipient_address: Address,
amount: U256,
) -> None:
def reduce_sender_balance(sender: Account) -> None:
ensure(sender.balance >= amount, AssertionError)
sender.balance -= amount
def increase_recipient_balance(recipient: Account) -> None:
recipient.balance += amount
modify_state(state, sender_address, reduce_sender_balance)
modify_state(state, recipient_address, increase_recipient_balance)
set_account_balance
- set_account_balance(state, address, amount)
Sets the balance of an account.
- Parameters
state – The current state.
address – Address of the account whose nonce needs to be incremented.
amount – The amount that needs to set in balance.
def set_account_balance(state: State, address: Address, amount: U256) -> None:
def set_balance(account: Account) -> None:
account.balance = amount
modify_state(state, address, set_balance)
touch_account
- touch_account(state, address)
Initializes an account to state.
- Parameters
state – The current state.
address – The address of the account that need to initialised.
def touch_account(state: State, address: Address) -> None:
if not account_exists(state, address):
set_account(state, address, EMPTY_ACCOUNT)
increment_nonce
- increment_nonce(state, address)
Increments the nonce of an account.
- Parameters
state – The current state.
address – Address of the account whose nonce needs to be incremented.
def increment_nonce(state: State, address: Address) -> None:
def increase_nonce(sender: Account) -> None:
sender.nonce += 1
modify_state(state, address, increase_nonce)
set_code
- set_code(state, address, code)
Sets Account code.
- Parameters
state – The current state.
address – Address of the account whose code needs to be update.
code – The bytecode that needs to be set.
def set_code(state: State, address: Address, code: Bytes) -> None:
def write_code(sender: Account) -> None:
sender.code = code
modify_state(state, address, write_code)
create_ether
- create_ether(state, address, amount)
Add newly created ether to an account.
- Parameters
state – The current state.
address – Address of the account to which ether is added.
amount – The amount of ether to be added to the account of interest.
def create_ether(state: State, address: Address, amount: U256) -> None:
def increase_balance(account: Account) -> None:
account.balance += amount
modify_state(state, address, increase_balance)
get_storage_original
- get_storage_original(state, address, key)
Get the original value in a storage slot i.e. the value before the current transaction began. This function reads the value from the snapshots taken before executing the transaction.
- Parameters
state – The current state.
address – Address of the account to read the value from.
key – Key of the storage slot.
def get_storage_original(state: State, address: Address, key: Bytes) -> U256:
_, original_trie = state._snapshots[0]
original_account_trie = original_trie.get(address)
if original_account_trie is None:
original_value = U256(0)
else:
original_value = trie_get(original_account_trie, key)
assert isinstance(original_value, U256)
return original_value