ethereum.frontier.state

State ^^^^^

.. contents:: Table of Contents :backlinks: none :local:

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.

State

Contains all information that is preserved between transactions.

30
@dataclass
class State:

_main_trie

36
    _main_trie: Trie[Address, Optional[Account]] = field(
37
        default_factory=lambda: Trie(secured=True, default=None)
38
    )

_storage_tries

39
    _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field(
40
        default_factory=dict
41
    )

_snapshots

42
    _snapshots: List[
43
        Tuple[
44
            Trie[Address, Optional[Account]],
45
            Dict[Address, Trie[Bytes32, U256]],
46
        ]
47
    ] = field(default_factory=list)

close_state

Free resources held by the state. Used by optimized implementations to release file descriptors.

def close_state(state: State) -> None:
51
    """
52
    Free resources held by the state. Used by optimized implementations to
53
    release file descriptors.
54
    """
55
    del state._main_trie
56
    del state._storage_tries
57
    del state._snapshots

begin_transaction

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:
61
    """
62
    Start a state transaction.
63
64
    Transactions are entirely implicit and can be nested. It is not possible to
65
    calculate the state root during a transaction.
66
67
    Parameters
68
    ----------
69
    state : State
70
        The state.
71
    """
72
    state._snapshots.append(
73
        (
74
            copy_trie(state._main_trie),
75
            {k: copy_trie(t) for (k, t) in state._storage_tries.items()},
76
        )
77
    )

commit_transaction

Commit a state transaction.

Parameters

state : State The state.

def commit_transaction(state: State) -> None:
81
    """
82
    Commit a state transaction.
83
84
    Parameters
85
    ----------
86
    state : State
87
        The state.
88
    """
89
    state._snapshots.pop()

rollback_transaction

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:
93
    """
94
    Rollback a state transaction, resetting the state to the point when the
95
    corresponding `start_transaction()` call was made.
96
97
    Parameters
98
    ----------
99
    state : State
100
        The state.
101
    """
102
    state._main_trie, state._storage_tries = state._snapshots.pop()

get_account

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 Account at address.

def get_account(state: State, ​​address: Address) -> Account:
106
    """
107
    Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there
108
    is no account at the address.
109
110
    Use `get_account_optional()` if you care about the difference between a
111
    non-existent account and `EMPTY_ACCOUNT`.
112
113
    Parameters
114
    ----------
115
    state: `State`
116
        The state
117
    address : `Address`
118
        Address to lookup.
119
120
    Returns
121
    -------
122
    account : `Account`
123
        Account at address.
124
    """
125
    account = get_account_optional(state, address)
126
    if isinstance(account, Account):
127
        return account
128
    else:
129
        return EMPTY_ACCOUNT

get_account_optional

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 Account at address.

def get_account_optional(state: State, ​​address: Address) -> Optional[Account]:
133
    """
134
    Get the `Account` object at an address. Returns `None` (rather than
135
    `EMPTY_ACCOUNT`) if there is no account at the address.
136
137
    Parameters
138
    ----------
139
    state: `State`
140
        The state
141
    address : `Address`
142
        Address to lookup.
143
144
    Returns
145
    -------
146
    account : `Account`
147
        Account at address.
148
    """
149
    account = trie_get(state._main_trie, address)
150
    return account

set_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:
156
    """
157
    Set the `Account` object at an address. Setting to `None` deletes
158
    the account (but not its storage, see `destroy_account()`).
159
160
    Parameters
161
    ----------
162
    state: `State`
163
        The state
164
    address : `Address`
165
        Address to set.
166
    account : `Account`
167
        Account to set at address.
168
    """
169
    trie_set(state._main_trie, address, account)

destroy_account

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:
173
    """
174
    Completely remove the account at `address` and all of its storage.
175
176
    This function is made available exclusively for the `SELFDESTRUCT`
177
    opcode. It is expected that `SELFDESTRUCT` will be disabled in a future
178
    hardfork and this function will be removed.
179
180
    Parameters
181
    ----------
182
    state: `State`
183
        The state
184
    address : `Address`
185
        Address of account to destroy.
186
    """
187
    destroy_storage(state, address)
188
    set_account(state, address, None)

destroy_storage

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:
192
    """
193
    Completely remove the storage at `address`.
194
195
    Parameters
196
    ----------
197
    state: `State`
198
        The state
199
    address : `Address`
200
        Address of account whose storage is to be deleted.
201
    """
202
    if address in state._storage_tries:
203
        del state._storage_tries[address]

get_storage

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 : U256 Value at the key.

def get_storage(state: State, ​​address: Address, ​​key: Bytes32) -> U256:
207
    """
208
    Get a value at a storage key on an account. Returns `U256(0)` if the
209
    storage key has not been set previously.
210
211
    Parameters
212
    ----------
213
    state: `State`
214
        The state
215
    address : `Address`
216
        Address of the account.
217
    key : `Bytes`
218
        Key to lookup.
219
220
    Returns
221
    -------
222
    value : `U256`
223
        Value at the key.
224
    """
225
    trie = state._storage_tries.get(address)
226
    if trie is None:
227
        return U256(0)
228
229
    value = trie_get(trie, key)
230
231
    assert isinstance(value, U256)
232
    return value

set_storage

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: Bytes32, ​​value: U256) -> None:
238
    """
239
    Set a value at a storage key on an account. Setting to `U256(0)` deletes
240
    the key.
241
242
    Parameters
243
    ----------
244
    state: `State`
245
        The state
246
    address : `Address`
247
        Address of the account.
248
    key : `Bytes`
249
        Key to set.
250
    value : `U256`
251
        Value to set at the key.
252
    """
253
    assert trie_get(state._main_trie, address) is not None
254
255
    trie = state._storage_tries.get(address)
256
    if trie is None:
257
        trie = Trie(secured=True, default=U256(0))
258
        state._storage_tries[address] = trie
259
    trie_set(trie, key, value)
260
    if trie._data == {}:
261
        del state._storage_tries[address]

storage_root

Calculate the storage root of an account.

Parameters

state: The state address : Address of the account.

Returns

root : Root Storage root of the account.

def storage_root(state: State, ​​address: Address) -> Root:
265
    """
266
    Calculate the storage root of an account.
267
268
    Parameters
269
    ----------
270
    state:
271
        The state
272
    address :
273
        Address of the account.
274
275
    Returns
276
    -------
277
    root : `Root`
278
        Storage root of the account.
279
    """
280
    assert not state._snapshots
281
    if address in state._storage_tries:
282
        return root(state._storage_tries[address])
283
    else:
284
        return EMPTY_TRIE_ROOT

state_root

Calculate the state root.

Parameters

state: The current state.

Returns

root : Root The state root.

def state_root(state: State) -> Root:
288
    """
289
    Calculate the state root.
290
291
    Parameters
292
    ----------
293
    state:
294
        The current state.
295
296
    Returns
297
    -------
298
    root : `Root`
299
        The state root.
300
    """
301
    assert not state._snapshots
302
303
    def get_storage_root(address: Address) -> Root:
304
        return storage_root(state, address)
305
306
    return root(state._main_trie, get_storage_root=get_storage_root)

account_exists

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 : bool True if account exists in the state trie, False otherwise

def account_exists(state: State, ​​address: Address) -> bool:
310
    """
311
    Checks if an account exists in the state trie
312
313
    Parameters
314
    ----------
315
    state:
316
        The state
317
    address:
318
        Address of the account that needs to be checked.
319
320
    Returns
321
    -------
322
    account_exists : `bool`
323
        True if account exists in the state trie, False otherwise
324
    """
325
    return get_account_optional(state, address) is not None

account_has_code_or_nonce

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 : bool True if the account has non zero nonce or non empty code, False otherwise.

def account_has_code_or_nonce(state: State, ​​address: Address) -> bool:
329
    """
330
    Checks if an account has non zero nonce or non empty code
331
332
    Parameters
333
    ----------
334
    state:
335
        The state
336
    address:
337
        Address of the account that needs to be checked.
338
339
    Returns
340
    -------
341
    has_code_or_nonce : `bool`
342
        True if the account has non zero nonce or non empty code,
343
        False otherwise.
344
    """
345
    account = get_account(state, address)
346
    return account.nonce != Uint(0) or account.code != b""

account_has_storage

Checks if an account has storage.

Parameters

state: The state address: Address of the account that needs to be checked.

Returns

has_storage : bool True if the account has storage, False otherwise.

def account_has_storage(state: State, ​​address: Address) -> bool:
350
    """
351
    Checks if an account has storage.
352
353
    Parameters
354
    ----------
355
    state:
356
        The state
357
    address:
358
        Address of the account that needs to be checked.
359
360
    Returns
361
    -------
362
    has_storage : `bool`
363
        True if the account has storage, False otherwise.
364
    """
365
    return address in state._storage_tries

modify_state

Modify an Account in the State.

def modify_state(state: State, ​​address: Address, ​​f: Callable[[Account], None]) -> None:
371
    """
372
    Modify an `Account` in the `State`.
373
    """
374
    set_account(state, address, modify(get_account(state, address), f))

move_ether

Move funds between accounts.

def move_ether(state: State, ​​sender_address: Address, ​​recipient_address: Address, ​​amount: U256) -> None:
383
    """
384
    Move funds between accounts.
385
    """
386
387
    def reduce_sender_balance(sender: Account) -> None:
388
        if sender.balance < amount:
389
            raise AssertionError
390
        sender.balance -= amount
391
392
    def increase_recipient_balance(recipient: Account) -> None:
393
        recipient.balance += amount
394
395
    modify_state(state, sender_address, reduce_sender_balance)
396
    modify_state(state, recipient_address, increase_recipient_balance)

set_account_balance

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:
400
    """
401
    Sets the balance of an account.
402
403
    Parameters
404
    ----------
405
    state:
406
        The current state.
407
408
    address:
409
        Address of the account whose nonce needs to be incremented.
410
411
    amount:
412
        The amount that needs to set in balance.
413
    """
414
415
    def set_balance(account: Account) -> None:
416
        account.balance = amount
417
418
    modify_state(state, address, set_balance)

touch_account

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:
422
    """
423
    Initializes an account to state.
424
425
    Parameters
426
    ----------
427
    state:
428
        The current state.
429
430
    address:
431
        The address of the account that need to initialised.
432
    """
433
    if not account_exists(state, address):
434
        set_account(state, address, EMPTY_ACCOUNT)

increment_nonce

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:
438
    """
439
    Increments the nonce of an account.
440
441
    Parameters
442
    ----------
443
    state:
444
        The current state.
445
446
    address:
447
        Address of the account whose nonce needs to be incremented.
448
    """
449
450
    def increase_nonce(sender: Account) -> None:
451
        sender.nonce += Uint(1)
452
453
    modify_state(state, address, increase_nonce)

set_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:
457
    """
458
    Sets Account code.
459
460
    Parameters
461
    ----------
462
    state:
463
        The current state.
464
465
    address:
466
        Address of the account whose code needs to be update.
467
468
    code:
469
        The bytecode that needs to be set.
470
    """
471
472
    def write_code(sender: Account) -> None:
473
        sender.code = code
474
475
    modify_state(state, address, write_code)

create_ether

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:
479
    """
480
    Add newly created ether to an account.
481
482
    Parameters
483
    ----------
484
    state:
485
        The current state.
486
    address:
487
        Address of the account to which ether is added.
488
    amount:
489
        The amount of ether to be added to the account of interest.
490
    """
491
492
    def increase_balance(account: Account) -> None:
493
        account.balance += amount
494
495
    modify_state(state, address, increase_balance)