ethereum.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[Bytes, U256]] = field(
40
        default_factory=dict
41
    )

_snapshots

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

commit_transaction

Commit a state transaction.

Parameters

state : State The state.

def commit_transaction(state: State) -> None:
80
    """
81
    Commit a state transaction.
82
83
    Parameters
84
    ----------
85
    state : State
86
        The state.
87
    """
88
    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:
92
    """
93
    Rollback a state transaction, resetting the state to the point when the
94
    corresponding `start_transaction()` call was made.
95
96
    Parameters
97
    ----------
98
    state : State
99
        The state.
100
    """
101
    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:
105
    """
106
    Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there
107
    is no account at the address.
108
109
    Use `get_account_optional()` if you care about the difference between a
110
    non-existent account and `EMPTY_ACCOUNT`.
111
112
    Parameters
113
    ----------
114
    state: `State`
115
        The state
116
    address : `Address`
117
        Address to lookup.
118
119
    Returns
120
    -------
121
    account : `Account`
122
        Account at address.
123
    """
124
    account = get_account_optional(state, address)
125
    if isinstance(account, Account):
126
        return account
127
    else:
128
        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]:
132
    """
133
    Get the `Account` object at an address. Returns `None` (rather than
134
    `EMPTY_ACCOUNT`) if there is no account at the address.
135
136
    Parameters
137
    ----------
138
    state: `State`
139
        The state
140
    address : `Address`
141
        Address to lookup.
142
143
    Returns
144
    -------
145
    account : `Account`
146
        Account at address.
147
    """
148
    account = trie_get(state._main_trie, address)
149
    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:
155
    """
156
    Set the `Account` object at an address. Setting to `None` deletes
157
    the account (but not its storage, see `destroy_account()`).
158
159
    Parameters
160
    ----------
161
    state: `State`
162
        The state
163
    address : `Address`
164
        Address to set.
165
    account : `Account`
166
        Account to set at address.
167
    """
168
    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:
172
    """
173
    Completely remove the account at `address` and all of its storage.
174
175
    This function is made available exclusively for the `SELFDESTRUCT`
176
    opcode. It is expected that `SELFDESTRUCT` will be disabled in a future
177
    hardfork and this function will be removed.
178
179
    Parameters
180
    ----------
181
    state: `State`
182
        The state
183
    address : `Address`
184
        Address of account to destroy.
185
    """
186
    destroy_storage(state, address)
187
    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:
191
    """
192
    Completely remove the storage at `address`.
193
194
    Parameters
195
    ----------
196
    state: `State`
197
        The state
198
    address : `Address`
199
        Address of account whose storage is to be deleted.
200
    """
201
    if address in state._storage_tries:
202
        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:
206
    """
207
    Get a value at a storage key on an account. Returns `U256(0)` if the
208
    storage key has not been set previously.
209
210
    Parameters
211
    ----------
212
    state: `State`
213
        The state
214
    address : `Address`
215
        Address of the account.
216
    key : `Bytes`
217
        Key to lookup.
218
219
    Returns
220
    -------
221
    value : `U256`
222
        Value at the key.
223
    """
224
    trie = state._storage_tries.get(address)
225
    if trie is None:
226
        return U256(0)
227
228
    value = trie_get(trie, key)
229
230
    assert isinstance(value, U256)
231
    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:
237
    """
238
    Set a value at a storage key on an account. Setting to `U256(0)` deletes
239
    the key.
240
241
    Parameters
242
    ----------
243
    state: `State`
244
        The state
245
    address : `Address`
246
        Address of the account.
247
    key : `Bytes`
248
        Key to set.
249
    value : `U256`
250
        Value to set at the key.
251
    """
252
    assert trie_get(state._main_trie, address) is not None
253
254
    trie = state._storage_tries.get(address)
255
    if trie is None:
256
        trie = Trie(secured=True, default=U256(0))
257
        state._storage_tries[address] = trie
258
    trie_set(trie, key, value)
259
    if trie._data == {}:
260
        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:
264
    """
265
    Calculate the storage root of an account.
266
267
    Parameters
268
    ----------
269
    state:
270
        The state
271
    address :
272
        Address of the account.
273
274
    Returns
275
    -------
276
    root : `Root`
277
        Storage root of the account.
278
    """
279
    assert not state._snapshots
280
    if address in state._storage_tries:
281
        return root(state._storage_tries[address])
282
    else:
283
        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:
287
    """
288
    Calculate the state root.
289
290
    Parameters
291
    ----------
292
    state:
293
        The current state.
294
295
    Returns
296
    -------
297
    root : `Root`
298
        The state root.
299
    """
300
    assert not state._snapshots
301
302
    def get_storage_root(address: Address) -> Root:
303
        return storage_root(state, address)
304
305
    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:
309
    """
310
    Checks if an account exists in the state trie
311
312
    Parameters
313
    ----------
314
    state:
315
        The state
316
    address:
317
        Address of the account that needs to be checked.
318
319
    Returns
320
    -------
321
    account_exists : `bool`
322
        True if account exists in the state trie, False otherwise
323
    """
324
    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:
328
    """
329
    Checks if an account has non zero nonce or non empty code
330
331
    Parameters
332
    ----------
333
    state:
334
        The state
335
    address:
336
        Address of the account that needs to be checked.
337
338
    Returns
339
    -------
340
    has_code_or_nonce : `bool`
341
        True if if an account has non zero nonce or non empty code,
342
        False otherwise.
343
    """
344
    account = get_account(state, address)
345
    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:
349
    """
350
    Checks if an account has zero nonce, empty code and zero balance.
351
352
    Parameters
353
    ----------
354
    state:
355
        The state
356
    address:
357
        Address of the account that needs to be checked.
358
359
    Returns
360
    -------
361
    is_empty : `bool`
362
        True if if an account has zero nonce, empty code and zero balance,
363
        False otherwise.
364
    """
365
    account = get_account(state, address)
366
    return (
367
        account.nonce == Uint(0)
368
        and account.code == b""
369
        and account.balance == 0
370
    )

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

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

modify_state

Modify an Account in the State.

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