ethereum.byzantium.stateethereum.constantinople.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

account_exists_and_is_empty

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 : bool True if an account exists and has zero nonce, empty code and zero balance, False otherwise.

def account_exists_and_is_empty(state: State, ​​address: Address) -> bool:
369
    """
370
    Checks if an account exists and has zero nonce, empty code and zero
371
    balance.
372
373
    Parameters
374
    ----------
375
    state:
376
        The state
377
    address:
378
        Address of the account that needs to be checked.
379
380
    Returns
381
    -------
382
    exists_and_is_empty : `bool`
383
        True if an account exists and has zero nonce, empty code and zero
384
        balance, False otherwise.
385
    """
386
    account = get_account_optional(state, address)
387
    return (
388
        account is not None
389
        and account.nonce == Uint(0)
390
        and account.code == b""
391
        and account.balance == 0
392
    )

is_account_alive

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 : bool True if the account is alive.

def is_account_alive(state: State, ​​address: Address) -> bool:
396
    """
397
    Check whether is an account is both in the state and non empty.
398
399
    Parameters
400
    ----------
401
    state:
402
        The state
403
    address:
404
        Address of the account that needs to be checked.
405
406
    Returns
407
    -------
408
    is_alive : `bool`
409
        True if the account is alive.
410
    """
411
    account = get_account_optional(state, address)
412
    return account is not None and account != EMPTY_ACCOUNT

modify_state

Modify an Account in the State.

def modify_state(state: State, ​​address: Address, ​​f: Callable[[Account], None]) -> None:
418
    """
419
    Modify an `Account` in the `State`.
420
    """
421
    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:
430
    """
431
    Move funds between accounts.
432
    """
433
434
    def reduce_sender_balance(sender: Account) -> None:
435
        if sender.balance < amount:
436
            raise AssertionError
437
        sender.balance -= amount
438
439
    def increase_recipient_balance(recipient: Account) -> None:
440
        recipient.balance += amount
441
442
    modify_state(state, sender_address, reduce_sender_balance)
443
    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:
447
    """
448
    Sets the balance of an account.
449
450
    Parameters
451
    ----------
452
    state:
453
        The current state.
454
455
    address:
456
        Address of the account whose nonce needs to be incremented.
457
458
    amount:
459
        The amount that needs to set in balance.
460
    """
461
462
    def set_balance(account: Account) -> None:
463
        account.balance = amount
464
465
    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:
469
    """
470
    Initializes an account to state.
471
472
    Parameters
473
    ----------
474
    state:
475
        The current state.
476
477
    address:
478
        The address of the account that need to initialised.
479
    """
480
    if not account_exists(state, address):
481
        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:
485
    """
486
    Increments the nonce of an account.
487
488
    Parameters
489
    ----------
490
    state:
491
        The current state.
492
493
    address:
494
        Address of the account whose nonce needs to be incremented.
495
    """
496
497
    def increase_nonce(sender: Account) -> None:
498
        sender.nonce += Uint(1)
499
500
    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:
504
    """
505
    Sets Account code.
506
507
    Parameters
508
    ----------
509
    state:
510
        The current state.
511
512
    address:
513
        Address of the account whose code needs to be update.
514
515
    code:
516
        The bytecode that needs to be set.
517
    """
518
519
    def write_code(sender: Account) -> None:
520
        sender.code = code
521
522
    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:
526
    """
527
    Add newly created ether to an account.
528
529
    Parameters
530
    ----------
531
    state:
532
        The current state.
533
    address:
534
        Address of the account to which ether is added.
535
    amount:
536
        The amount of ether to be added to the account of interest.
537
    """
538
539
    def increase_balance(account: Account) -> None:
540
        account.balance += amount
541
542
    modify_state(state, address, increase_balance)

destroy_touched_empty_accounts

Destroy all touched accounts that are empty. Parameters

state: State The current state. touched_accounts: Iterable[Address] All the accounts that have been touched in the current transaction.

def destroy_touched_empty_accounts(state: State, ​​touched_accounts: Iterable[Address]) -> None:
548
    """
549
    Destroy all touched accounts that are empty.
550
    Parameters
551
    ----------
552
    state: `State`
553
        The current state.
554
    touched_accounts: `Iterable[Address]`
555
        All the accounts that have been touched in the current transaction.
556
    """
557
    for address in touched_accounts:
558
        if account_exists_and_is_empty(state, address):
559
            destroy_account(state, address)