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

is_account_empty

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

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

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:
394
    """
395
    Checks if an account exists and has zero nonce, empty code and zero
396
    balance.
397
398
    Parameters
399
    ----------
400
    state:
401
        The state
402
    address:
403
        Address of the account that needs to be checked.
404
405
    Returns
406
    -------
407
    exists_and_is_empty : `bool`
408
        True if an account exists and has zero nonce, empty code and zero
409
        balance, False otherwise.
410
    """
411
    account = get_account_optional(state, address)
412
    return (
413
        account is not None
414
        and account.nonce == Uint(0)
415
        and account.code == b""
416
        and account.balance == 0
417
    )

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:
421
    """
422
    Check whether is an account is both in the state and non empty.
423
424
    Parameters
425
    ----------
426
    state:
427
        The state
428
    address:
429
        Address of the account that needs to be checked.
430
431
    Returns
432
    -------
433
    is_alive : `bool`
434
        True if the account is alive.
435
    """
436
    account = get_account_optional(state, address)
437
    if account is None:
438
        return False
439
    else:
440
        return not (
441
            account.nonce == Uint(0)
442
            and account.code == b""
443
            and account.balance == 0
444
        )

modify_state

Modify an Account in the State.

def modify_state(state: State, ​​address: Address, ​​f: Callable[[Account], None]) -> None:
450
    """
451
    Modify an `Account` in the `State`.
452
    """
453
    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:
462
    """
463
    Move funds between accounts.
464
    """
465
466
    def reduce_sender_balance(sender: Account) -> None:
467
        if sender.balance < amount:
468
            raise AssertionError
469
        sender.balance -= amount
470
471
    def increase_recipient_balance(recipient: Account) -> None:
472
        recipient.balance += amount
473
474
    modify_state(state, sender_address, reduce_sender_balance)
475
    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:
479
    """
480
    Sets the balance of an account.
481
482
    Parameters
483
    ----------
484
    state:
485
        The current state.
486
487
    address:
488
        Address of the account whose nonce needs to be incremented.
489
490
    amount:
491
        The amount that needs to set in balance.
492
    """
493
494
    def set_balance(account: Account) -> None:
495
        account.balance = amount
496
497
    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:
501
    """
502
    Initializes an account to state.
503
504
    Parameters
505
    ----------
506
    state:
507
        The current state.
508
509
    address:
510
        The address of the account that need to initialised.
511
    """
512
    if not account_exists(state, address):
513
        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:
517
    """
518
    Increments the nonce of an account.
519
520
    Parameters
521
    ----------
522
    state:
523
        The current state.
524
525
    address:
526
        Address of the account whose nonce needs to be incremented.
527
    """
528
529
    def increase_nonce(sender: Account) -> None:
530
        sender.nonce += Uint(1)
531
532
    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:
536
    """
537
    Sets Account code.
538
539
    Parameters
540
    ----------
541
    state:
542
        The current state.
543
544
    address:
545
        Address of the account whose code needs to be update.
546
547
    code:
548
        The bytecode that needs to be set.
549
    """
550
551
    def write_code(sender: Account) -> None:
552
        sender.code = code
553
554
    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:
558
    """
559
    Add newly created ether to an account.
560
561
    Parameters
562
    ----------
563
    state:
564
        The current state.
565
    address:
566
        Address of the account to which ether is added.
567
    amount:
568
        The amount of ether to be added to the account of interest.
569
    """
570
571
    def increase_balance(account: Account) -> None:
572
        account.balance += amount
573
574
    modify_state(state, address, increase_balance)