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

28
@dataclass
class State:

_main_trie

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

_storage_tries

37
    _storage_tries: Dict[Address, Trie[Bytes, U256]] = field(
38
        default_factory=dict
39
    )

_snapshots

40
    _snapshots: List[
41
        Tuple[
42
            Trie[Address, Optional[Account]], Dict[Address, Trie[Bytes, U256]]
43
        ]
44
    ] = 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:
48
    """
49
    Free resources held by the state. Used by optimized implementations to
50
    release file descriptors.
51
    """
52
    del state._main_trie
53
    del state._storage_tries
54
    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:
58
    """
59
    Start a state transaction.
60
61
    Transactions are entirely implicit and can be nested. It is not possible to
62
    calculate the state root during a transaction.
63
64
    Parameters
65
    ----------
66
    state : State
67
        The state.
68
    """
69
    state._snapshots.append(
70
        (
71
            copy_trie(state._main_trie),
72
            {k: copy_trie(t) for (k, t) in state._storage_tries.items()},
73
        )
74
    )

commit_transaction

Commit a state transaction.

Parameters

state : State The state.

def commit_transaction(state: State) -> None:
78
    """
79
    Commit a state transaction.
80
81
    Parameters
82
    ----------
83
    state : State
84
        The state.
85
    """
86
    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:
90
    """
91
    Rollback a state transaction, resetting the state to the point when the
92
    corresponding `start_transaction()` call was made.
93
94
    Parameters
95
    ----------
96
    state : State
97
        The state.
98
    """
99
    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:
103
    """
104
    Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there
105
    is no account at the address.
106
107
    Use `get_account_optional()` if you care about the difference between a
108
    non-existent account and `EMPTY_ACCOUNT`.
109
110
    Parameters
111
    ----------
112
    state: `State`
113
        The state
114
    address : `Address`
115
        Address to lookup.
116
117
    Returns
118
    -------
119
    account : `Account`
120
        Account at address.
121
    """
122
    account = get_account_optional(state, address)
123
    if isinstance(account, Account):
124
        return account
125
    else:
126
        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]:
130
    """
131
    Get the `Account` object at an address. Returns `None` (rather than
132
    `EMPTY_ACCOUNT`) if there is no account at the address.
133
134
    Parameters
135
    ----------
136
    state: `State`
137
        The state
138
    address : `Address`
139
        Address to lookup.
140
141
    Returns
142
    -------
143
    account : `Account`
144
        Account at address.
145
    """
146
    account = trie_get(state._main_trie, address)
147
    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:
153
    """
154
    Set the `Account` object at an address. Setting to `None` deletes
155
    the account (but not its storage, see `destroy_account()`).
156
157
    Parameters
158
    ----------
159
    state: `State`
160
        The state
161
    address : `Address`
162
        Address to set.
163
    account : `Account`
164
        Account to set at address.
165
    """
166
    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:
170
    """
171
    Completely remove the account at `address` and all of its storage.
172
173
    This function is made available exclusively for the `SELFDESTRUCT`
174
    opcode. It is expected that `SELFDESTRUCT` will be disabled in a future
175
    hardfork and this function will be removed.
176
177
    Parameters
178
    ----------
179
    state: `State`
180
        The state
181
    address : `Address`
182
        Address of account to destroy.
183
    """
184
    destroy_storage(state, address)
185
    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:
189
    """
190
    Completely remove the storage at `address`.
191
192
    Parameters
193
    ----------
194
    state: `State`
195
        The state
196
    address : `Address`
197
        Address of account whose storage is to be deleted.
198
    """
199
    if address in state._storage_tries:
200
        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: Bytes) -> U256:
204
    """
205
    Get a value at a storage key on an account. Returns `U256(0)` if the
206
    storage key has not been set previously.
207
208
    Parameters
209
    ----------
210
    state: `State`
211
        The state
212
    address : `Address`
213
        Address of the account.
214
    key : `Bytes`
215
        Key to lookup.
216
217
    Returns
218
    -------
219
    value : `U256`
220
        Value at the key.
221
    """
222
    trie = state._storage_tries.get(address)
223
    if trie is None:
224
        return U256(0)
225
226
    value = trie_get(trie, key)
227
228
    assert isinstance(value, U256)
229
    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: Bytes, ​​value: U256) -> None:
235
    """
236
    Set a value at a storage key on an account. Setting to `U256(0)` deletes
237
    the key.
238
239
    Parameters
240
    ----------
241
    state: `State`
242
        The state
243
    address : `Address`
244
        Address of the account.
245
    key : `Bytes`
246
        Key to set.
247
    value : `U256`
248
        Value to set at the key.
249
    """
250
    assert trie_get(state._main_trie, address) is not None
251
252
    trie = state._storage_tries.get(address)
253
    if trie is None:
254
        trie = Trie(secured=True, default=U256(0))
255
        state._storage_tries[address] = trie
256
    trie_set(trie, key, value)
257
    if trie._data == {}:
258
        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:
262
    """
263
    Calculate the storage root of an account.
264
265
    Parameters
266
    ----------
267
    state:
268
        The state
269
    address :
270
        Address of the account.
271
272
    Returns
273
    -------
274
    root : `Root`
275
        Storage root of the account.
276
    """
277
    assert not state._snapshots
278
    if address in state._storage_tries:
279
        return root(state._storage_tries[address])
280
    else:
281
        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:
285
    """
286
    Calculate the state root.
287
288
    Parameters
289
    ----------
290
    state:
291
        The current state.
292
293
    Returns
294
    -------
295
    root : `Root`
296
        The state root.
297
    """
298
    assert not state._snapshots
299
300
    def get_storage_root(address: Address) -> Root:
301
        return storage_root(state, address)
302
303
    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:
307
    """
308
    Checks if an account exists in the state trie
309
310
    Parameters
311
    ----------
312
    state:
313
        The state
314
    address:
315
        Address of the account that needs to be checked.
316
317
    Returns
318
    -------
319
    account_exists : `bool`
320
        True if account exists in the state trie, False otherwise
321
    """
322
    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 if an account has non zero nonce or non empty code, False otherwise.

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

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:
347
    """
348
    Checks if an account has zero nonce, empty code and zero balance.
349
350
    Parameters
351
    ----------
352
    state:
353
        The state
354
    address:
355
        Address of the account that needs to be checked.
356
357
    Returns
358
    -------
359
    is_empty : `bool`
360
        True if if an account has zero nonce, empty code and zero balance,
361
        False otherwise.
362
    """
363
    account = get_account(state, address)
364
    return (
365
        account.nonce == Uint(0)
366
        and account.code == b""
367
        and account.balance == 0
368
    )

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

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:
399
    """
400
    Check whether is an account is both in the state and non empty.
401
402
    Parameters
403
    ----------
404
    state:
405
        The state
406
    address:
407
        Address of the account that needs to be checked.
408
409
    Returns
410
    -------
411
    is_alive : `bool`
412
        True if the account is alive.
413
    """
414
    account = get_account_optional(state, address)
415
    if account is None:
416
        return False
417
    else:
418
        return not (
419
            account.nonce == Uint(0)
420
            and account.code == b""
421
            and account.balance == 0
422
        )

modify_state

Modify an Account in the State.

def modify_state(state: State, ​​address: Address, ​​f: Callable[[Account], None]) -> None:
428
    """
429
    Modify an `Account` in the `State`.
430
    """
431
    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:
440
    """
441
    Move funds between accounts.
442
    """
443
444
    def reduce_sender_balance(sender: Account) -> None:
445
        if sender.balance < amount:
446
            raise AssertionError
447
        sender.balance -= amount
448
449
    def increase_recipient_balance(recipient: Account) -> None:
450
        recipient.balance += amount
451
452
    modify_state(state, sender_address, reduce_sender_balance)
453
    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:
457
    """
458
    Sets the balance of an account.
459
460
    Parameters
461
    ----------
462
    state:
463
        The current state.
464
465
    address:
466
        Address of the account whose nonce needs to be incremented.
467
468
    amount:
469
        The amount that needs to set in balance.
470
    """
471
472
    def set_balance(account: Account) -> None:
473
        account.balance = amount
474
475
    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:
479
    """
480
    Initializes an account to state.
481
482
    Parameters
483
    ----------
484
    state:
485
        The current state.
486
487
    address:
488
        The address of the account that need to initialised.
489
    """
490
    if not account_exists(state, address):
491
        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:
495
    """
496
    Increments the nonce of an account.
497
498
    Parameters
499
    ----------
500
    state:
501
        The current state.
502
503
    address:
504
        Address of the account whose nonce needs to be incremented.
505
    """
506
507
    def increase_nonce(sender: Account) -> None:
508
        sender.nonce += 1
509
510
    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:
514
    """
515
    Sets Account code.
516
517
    Parameters
518
    ----------
519
    state:
520
        The current state.
521
522
    address:
523
        Address of the account whose code needs to be update.
524
525
    code:
526
        The bytecode that needs to be set.
527
    """
528
529
    def write_code(sender: Account) -> None:
530
        sender.code = code
531
532
    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:
536
    """
537
    Add newly created ether to an account.
538
539
    Parameters
540
    ----------
541
    state:
542
        The current state.
543
    address:
544
        Address of the account to which ether is added.
545
    amount:
546
        The amount of ether to be added to the account of interest.
547
    """
548
549
    def increase_balance(account: Account) -> None:
550
        account.balance += amount
551
552
    modify_state(state, address, increase_balance)