ethereum.muir_glacier.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.

  1"""
  2State
  3^^^^^
  4
  5.. contents:: Table of Contents
  6    :backlinks: none
  7    :local:
  8
  9Introduction
 10------------
 11
 12The state contains all information that is preserved between transactions.
 13
 14It consists of a main account trie and storage tries for each contract.
 15
 16There is a distinction between an account that does not exist and
 17`EMPTY_ACCOUNT`.
 18"""
 19from dataclasses import dataclass, field
 20from typing import Callable, Dict, List, Optional, Set, Tuple
 21
 22from ethereum.base_types import U256, Bytes, Uint, modify
 23from ethereum.utils.ensure import ensure
 24
 25from .fork_types import EMPTY_ACCOUNT, Account, Address, Root
 26from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set
 27
 28
 29@dataclass
 30class State:
 31    """
 32    Contains all information that is preserved between transactions.
 33    """
 34
 35    _main_trie: Trie[Address, Optional[Account]] = field(
 36        default_factory=lambda: Trie(secured=True, default=None)
 37    )
 38    _storage_tries: Dict[Address, Trie[Bytes, U256]] = field(
 39        default_factory=dict
 40    )
 41    _snapshots: List[
 42        Tuple[
 43            Trie[Address, Optional[Account]], Dict[Address, Trie[Bytes, U256]]
 44        ]
 45    ] = field(default_factory=list)
 46    _created_accounts: Set[Address] = field(default_factory=set)
 47
 48
 49def 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
 57    del state._created_accounts
 58
 59
 60def 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    )
 78
 79
 80def 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()
 90    if not state._snapshots:
 91        state._created_accounts.clear()
 92
 93
 94def rollback_transaction(state: State) -> None:
 95    """
 96    Rollback a state transaction, resetting the state to the point when the
 97    corresponding `start_transaction()` call was made.
 98
 99    Parameters
100    ----------
101    state : State
102        The state.
103    """
104    state._main_trie, state._storage_tries = state._snapshots.pop()
105    if not state._snapshots:
106        state._created_accounts.clear()
107
108
109def get_account(state: State, address: Address) -> Account:
110    """
111    Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there
112    is no account at the address.
113
114    Use `get_account_optional()` if you care about the difference between a
115    non-existent account and `EMPTY_ACCOUNT`.
116
117    Parameters
118    ----------
119    state: `State`
120        The state
121    address : `Address`
122        Address to lookup.
123
124    Returns
125    -------
126    account : `Account`
127        Account at address.
128    """
129    account = get_account_optional(state, address)
130    if isinstance(account, Account):
131        return account
132    else:
133        return EMPTY_ACCOUNT
134
135
136def get_account_optional(state: State, address: Address) -> Optional[Account]:
137    """
138    Get the `Account` object at an address. Returns `None` (rather than
139    `EMPTY_ACCOUNT`) if there is no account at the address.
140
141    Parameters
142    ----------
143    state: `State`
144        The state
145    address : `Address`
146        Address to lookup.
147
148    Returns
149    -------
150    account : `Account`
151        Account at address.
152    """
153    account = trie_get(state._main_trie, address)
154    return account
155
156
157def set_account(
158    state: State, address: Address, account: Optional[Account]
159) -> None:
160    """
161    Set the `Account` object at an address. Setting to `None` deletes
162    the account (but not its storage, see `destroy_account()`).
163
164    Parameters
165    ----------
166    state: `State`
167        The state
168    address : `Address`
169        Address to set.
170    account : `Account`
171        Account to set at address.
172    """
173    trie_set(state._main_trie, address, account)
174
175
176def destroy_account(state: State, address: Address) -> None:
177    """
178    Completely remove the account at `address` and all of its storage.
179
180    This function is made available exclusively for the `SELFDESTRUCT`
181    opcode. It is expected that `SELFDESTRUCT` will be disabled in a future
182    hardfork and this function will be removed.
183
184    Parameters
185    ----------
186    state: `State`
187        The state
188    address : `Address`
189        Address of account to destroy.
190    """
191    destroy_storage(state, address)
192    set_account(state, address, None)
193
194
195def destroy_storage(state: State, address: Address) -> None:
196    """
197    Completely remove the storage at `address`.
198
199    Parameters
200    ----------
201    state: `State`
202        The state
203    address : `Address`
204        Address of account whose storage is to be deleted.
205    """
206    if address in state._storage_tries:
207        del state._storage_tries[address]
208
209
210def mark_account_created(state: State, address: Address) -> None:
211    """
212    Mark an account as having been created in the current transaction.
213    This information is used by `get_storage_original()` to handle an obscure
214    edgecase.
215
216    The marker is not removed even if the account creation reverts. Since the
217    account cannot have had code prior to its creation and can't call
218    `get_storage_original()`, this is harmless.
219
220    Parameters
221    ----------
222    state: `State`
223        The state
224    address : `Address`
225        Address of the account that has been created.
226    """
227    state._created_accounts.add(address)
228
229
230def get_storage(state: State, address: Address, key: Bytes) -> U256:
231    """
232    Get a value at a storage key on an account. Returns `U256(0)` if the
233    storage key has not been set previously.
234
235    Parameters
236    ----------
237    state: `State`
238        The state
239    address : `Address`
240        Address of the account.
241    key : `Bytes`
242        Key to lookup.
243
244    Returns
245    -------
246    value : `U256`
247        Value at the key.
248    """
249    trie = state._storage_tries.get(address)
250    if trie is None:
251        return U256(0)
252
253    value = trie_get(trie, key)
254
255    assert isinstance(value, U256)
256    return value
257
258
259def set_storage(
260    state: State, address: Address, key: Bytes, value: U256
261) -> None:
262    """
263    Set a value at a storage key on an account. Setting to `U256(0)` deletes
264    the key.
265
266    Parameters
267    ----------
268    state: `State`
269        The state
270    address : `Address`
271        Address of the account.
272    key : `Bytes`
273        Key to set.
274    value : `U256`
275        Value to set at the key.
276    """
277    assert trie_get(state._main_trie, address) is not None
278
279    trie = state._storage_tries.get(address)
280    if trie is None:
281        trie = Trie(secured=True, default=U256(0))
282        state._storage_tries[address] = trie
283    trie_set(trie, key, value)
284    if trie._data == {}:
285        del state._storage_tries[address]
286
287
288def storage_root(state: State, address: Address) -> Root:
289    """
290    Calculate the storage root of an account.
291
292    Parameters
293    ----------
294    state:
295        The state
296    address :
297        Address of the account.
298
299    Returns
300    -------
301    root : `Root`
302        Storage root of the account.
303    """
304    assert not state._snapshots
305    if address in state._storage_tries:
306        return root(state._storage_tries[address])
307    else:
308        return EMPTY_TRIE_ROOT
309
310
311def state_root(state: State) -> Root:
312    """
313    Calculate the state root.
314
315    Parameters
316    ----------
317    state:
318        The current state.
319
320    Returns
321    -------
322    root : `Root`
323        The state root.
324    """
325    assert not state._snapshots
326
327    def get_storage_root(address: Address) -> Root:
328        return storage_root(state, address)
329
330    return root(state._main_trie, get_storage_root=get_storage_root)
331
332
333def account_exists(state: State, address: Address) -> bool:
334    """
335    Checks if an account exists in the state trie
336
337    Parameters
338    ----------
339    state:
340        The state
341    address:
342        Address of the account that needs to be checked.
343
344    Returns
345    -------
346    account_exists : `bool`
347        True if account exists in the state trie, False otherwise
348    """
349    return get_account_optional(state, address) is not None
350
351
352def account_has_code_or_nonce(state: State, address: Address) -> bool:
353    """
354    Checks if an account has non zero nonce or non empty code
355
356    Parameters
357    ----------
358    state:
359        The state
360    address:
361        Address of the account that needs to be checked.
362
363    Returns
364    -------
365    has_code_or_nonce : `bool`
366        True if if an account has non zero nonce or non empty code,
367        False otherwise.
368    """
369    account = get_account(state, address)
370    return account.nonce != Uint(0) or account.code != b""
371
372
373def is_account_empty(state: State, address: Address) -> bool:
374    """
375    Checks if an account has zero nonce, empty code and zero balance.
376
377    Parameters
378    ----------
379    state:
380        The state
381    address:
382        Address of the account that needs to be checked.
383
384    Returns
385    -------
386    is_empty : `bool`
387        True if if an account has zero nonce, empty code and zero balance,
388        False otherwise.
389    """
390    account = get_account(state, address)
391    return (
392        account.nonce == Uint(0)
393        and account.code == b""
394        and account.balance == 0
395    )
396
397
398def account_exists_and_is_empty(state: State, address: Address) -> bool:
399    """
400    Checks if an account exists and has zero nonce, empty code and zero
401    balance.
402
403    Parameters
404    ----------
405    state:
406        The state
407    address:
408        Address of the account that needs to be checked.
409
410    Returns
411    -------
412    exists_and_is_empty : `bool`
413        True if an account exists and has zero nonce, empty code and zero
414        balance, False otherwise.
415    """
416    account = get_account_optional(state, address)
417    return (
418        account is not None
419        and account.nonce == Uint(0)
420        and account.code == b""
421        and account.balance == 0
422    )
423
424
425def is_account_alive(state: State, address: Address) -> bool:
426    """
427    Check whether is an account is both in the state and non empty.
428
429    Parameters
430    ----------
431    state:
432        The state
433    address:
434        Address of the account that needs to be checked.
435
436    Returns
437    -------
438    is_alive : `bool`
439        True if the account is alive.
440    """
441    account = get_account_optional(state, address)
442    if account is None:
443        return False
444    else:
445        return not (
446            account.nonce == Uint(0)
447            and account.code == b""
448            and account.balance == 0
449        )
450
451
452def modify_state(
453    state: State, address: Address, f: Callable[[Account], None]
454) -> None:
455    """
456    Modify an `Account` in the `State`.
457    """
458    set_account(state, address, modify(get_account(state, address), f))
459
460
461def move_ether(
462    state: State,
463    sender_address: Address,
464    recipient_address: Address,
465    amount: U256,
466) -> None:
467    """
468    Move funds between accounts.
469    """
470
471    def reduce_sender_balance(sender: Account) -> None:
472        ensure(sender.balance >= amount, AssertionError)
473        sender.balance -= amount
474
475    def increase_recipient_balance(recipient: Account) -> None:
476        recipient.balance += amount
477
478    modify_state(state, sender_address, reduce_sender_balance)
479    modify_state(state, recipient_address, increase_recipient_balance)
480
481
482def set_account_balance(state: State, address: Address, amount: U256) -> None:
483    """
484    Sets the balance of an account.
485
486    Parameters
487    ----------
488    state:
489        The current state.
490
491    address:
492        Address of the account whose nonce needs to be incremented.
493
494    amount:
495        The amount that needs to set in balance.
496    """
497
498    def set_balance(account: Account) -> None:
499        account.balance = amount
500
501    modify_state(state, address, set_balance)
502
503
504def touch_account(state: State, address: Address) -> None:
505    """
506    Initializes an account to state.
507
508    Parameters
509    ----------
510    state:
511        The current state.
512
513    address:
514        The address of the account that need to initialised.
515    """
516    if not account_exists(state, address):
517        set_account(state, address, EMPTY_ACCOUNT)
518
519
520def increment_nonce(state: State, address: Address) -> None:
521    """
522    Increments the nonce of an account.
523
524    Parameters
525    ----------
526    state:
527        The current state.
528
529    address:
530        Address of the account whose nonce needs to be incremented.
531    """
532
533    def increase_nonce(sender: Account) -> None:
534        sender.nonce += 1
535
536    modify_state(state, address, increase_nonce)
537
538
539def set_code(state: State, address: Address, code: Bytes) -> None:
540    """
541    Sets Account code.
542
543    Parameters
544    ----------
545    state:
546        The current state.
547
548    address:
549        Address of the account whose code needs to be update.
550
551    code:
552        The bytecode that needs to be set.
553    """
554
555    def write_code(sender: Account) -> None:
556        sender.code = code
557
558    modify_state(state, address, write_code)
559
560
561def create_ether(state: State, address: Address, amount: U256) -> None:
562    """
563    Add newly created ether to an account.
564
565    Parameters
566    ----------
567    state:
568        The current state.
569    address:
570        Address of the account to which ether is added.
571    amount:
572        The amount of ether to be added to the account of interest.
573    """
574
575    def increase_balance(account: Account) -> None:
576        account.balance += amount
577
578    modify_state(state, address, increase_balance)
579
580
581def get_storage_original(state: State, address: Address, key: Bytes) -> U256:
582    """
583    Get the original value in a storage slot i.e. the value before the current
584    transaction began. This function reads the value from the snapshots taken
585    before executing the transaction.
586
587    Parameters
588    ----------
589    state:
590        The current state.
591    address:
592        Address of the account to read the value from.
593    key:
594        Key of the storage slot.
595    """
596    # In the transaction where an account is created, its preexisting storage
597    # is ignored.
598    if address in state._created_accounts:
599        return U256(0)
600
601    _, original_trie = state._snapshots[0]
602    original_account_trie = original_trie.get(address)
603
604    if original_account_trie is None:
605        original_value = U256(0)
606    else:
607        original_value = trie_get(original_account_trie, key)
608
609    assert isinstance(original_value, U256)
610
611    return original_value
@dataclass
class State:
30@dataclass
31class State:
32    """
33    Contains all information that is preserved between transactions.
34    """
35
36    _main_trie: Trie[Address, Optional[Account]] = field(
37        default_factory=lambda: Trie(secured=True, default=None)
38    )
39    _storage_tries: Dict[Address, Trie[Bytes, U256]] = field(
40        default_factory=dict
41    )
42    _snapshots: List[
43        Tuple[
44            Trie[Address, Optional[Account]], Dict[Address, Trie[Bytes, U256]]
45        ]
46    ] = field(default_factory=list)
47    _created_accounts: Set[Address] = field(default_factory=set)

Contains all information that is preserved between transactions.

def close_state(state: State) -> None:
50def 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
58    del state._created_accounts

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

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

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 commit_transaction(state: State) -> None:
81def commit_transaction(state: State) -> None:
82    """
83    Commit a state transaction.
84
85    Parameters
86    ----------
87    state : State
88        The state.
89    """
90    state._snapshots.pop()
91    if not state._snapshots:
92        state._created_accounts.clear()

Commit a state transaction.

Parameters

state : State The state.

def rollback_transaction(state: State) -> None:
 95def rollback_transaction(state: State) -> None:
 96    """
 97    Rollback a state transaction, resetting the state to the point when the
 98    corresponding `start_transaction()` call was made.
 99
100    Parameters
101    ----------
102    state : State
103        The state.
104    """
105    state._main_trie, state._storage_tries = state._snapshots.pop()
106    if not state._snapshots:
107        state._created_accounts.clear()

Rollback a state transaction, resetting the state to the point when the corresponding start_transaction() call was made.

Parameters

state : State The state.

def get_account( state: State, address: ethereum.base_types.Bytes20) -> ethereum.muir_glacier.fork_types.Account:
110def get_account(state: State, address: Address) -> Account:
111    """
112    Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there
113    is no account at the address.
114
115    Use `get_account_optional()` if you care about the difference between a
116    non-existent account and `EMPTY_ACCOUNT`.
117
118    Parameters
119    ----------
120    state: `State`
121        The state
122    address : `Address`
123        Address to lookup.
124
125    Returns
126    -------
127    account : `Account`
128        Account at address.
129    """
130    account = get_account_optional(state, address)
131    if isinstance(account, Account):
132        return account
133    else:
134        return EMPTY_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_optional( state: State, address: ethereum.base_types.Bytes20) -> Optional[ethereum.muir_glacier.fork_types.Account]:
137def get_account_optional(state: State, address: Address) -> Optional[Account]:
138    """
139    Get the `Account` object at an address. Returns `None` (rather than
140    `EMPTY_ACCOUNT`) if there is no account at the address.
141
142    Parameters
143    ----------
144    state: `State`
145        The state
146    address : `Address`
147        Address to lookup.
148
149    Returns
150    -------
151    account : `Account`
152        Account at address.
153    """
154    account = trie_get(state._main_trie, address)
155    return account

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 set_account( state: State, address: ethereum.base_types.Bytes20, account: Optional[ethereum.muir_glacier.fork_types.Account]) -> None:
158def set_account(
159    state: State, address: Address, account: Optional[Account]
160) -> None:
161    """
162    Set the `Account` object at an address. Setting to `None` deletes
163    the account (but not its storage, see `destroy_account()`).
164
165    Parameters
166    ----------
167    state: `State`
168        The state
169    address : `Address`
170        Address to set.
171    account : `Account`
172        Account to set at address.
173    """
174    trie_set(state._main_trie, address, 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 destroy_account( state: State, address: ethereum.base_types.Bytes20) -> None:
177def destroy_account(state: State, address: Address) -> None:
178    """
179    Completely remove the account at `address` and all of its storage.
180
181    This function is made available exclusively for the `SELFDESTRUCT`
182    opcode. It is expected that `SELFDESTRUCT` will be disabled in a future
183    hardfork and this function will be removed.
184
185    Parameters
186    ----------
187    state: `State`
188        The state
189    address : `Address`
190        Address of account to destroy.
191    """
192    destroy_storage(state, address)
193    set_account(state, address, None)

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_storage( state: State, address: ethereum.base_types.Bytes20) -> None:
196def destroy_storage(state: State, address: Address) -> None:
197    """
198    Completely remove the storage at `address`.
199
200    Parameters
201    ----------
202    state: `State`
203        The state
204    address : `Address`
205        Address of account whose storage is to be deleted.
206    """
207    if address in state._storage_tries:
208        del state._storage_tries[address]

Completely remove the storage at address.

Parameters

state: State The state address : Address Address of account whose storage is to be deleted.

def mark_account_created( state: State, address: ethereum.base_types.Bytes20) -> None:
211def mark_account_created(state: State, address: Address) -> None:
212    """
213    Mark an account as having been created in the current transaction.
214    This information is used by `get_storage_original()` to handle an obscure
215    edgecase.
216
217    The marker is not removed even if the account creation reverts. Since the
218    account cannot have had code prior to its creation and can't call
219    `get_storage_original()`, this is harmless.
220
221    Parameters
222    ----------
223    state: `State`
224        The state
225    address : `Address`
226        Address of the account that has been created.
227    """
228    state._created_accounts.add(address)

Mark an account as having been created in the current transaction. This information is used by get_storage_original() to handle an obscure edgecase.

The marker is not removed even if the account creation reverts. Since the account cannot have had code prior to its creation and can't call get_storage_original(), this is harmless.

Parameters

state: State The state address : Address Address of the account that has been created.

def get_storage( state: State, address: ethereum.base_types.Bytes20, key: bytes) -> ethereum.base_types.U256:
231def get_storage(state: State, address: Address, key: Bytes) -> U256:
232    """
233    Get a value at a storage key on an account. Returns `U256(0)` if the
234    storage key has not been set previously.
235
236    Parameters
237    ----------
238    state: `State`
239        The state
240    address : `Address`
241        Address of the account.
242    key : `Bytes`
243        Key to lookup.
244
245    Returns
246    -------
247    value : `U256`
248        Value at the key.
249    """
250    trie = state._storage_tries.get(address)
251    if trie is None:
252        return U256(0)
253
254    value = trie_get(trie, key)
255
256    assert isinstance(value, U256)
257    return value

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 set_storage( state: State, address: ethereum.base_types.Bytes20, key: bytes, value: ethereum.base_types.U256) -> None:
260def set_storage(
261    state: State, address: Address, key: Bytes, value: U256
262) -> None:
263    """
264    Set a value at a storage key on an account. Setting to `U256(0)` deletes
265    the key.
266
267    Parameters
268    ----------
269    state: `State`
270        The state
271    address : `Address`
272        Address of the account.
273    key : `Bytes`
274        Key to set.
275    value : `U256`
276        Value to set at the key.
277    """
278    assert trie_get(state._main_trie, address) is not None
279
280    trie = state._storage_tries.get(address)
281    if trie is None:
282        trie = Trie(secured=True, default=U256(0))
283        state._storage_tries[address] = trie
284    trie_set(trie, key, value)
285    if trie._data == {}:
286        del state._storage_tries[address]

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 storage_root( state: State, address: ethereum.base_types.Bytes20) -> ethereum.base_types.Bytes32:
289def storage_root(state: State, address: Address) -> Root:
290    """
291    Calculate the storage root of an account.
292
293    Parameters
294    ----------
295    state:
296        The state
297    address :
298        Address of the account.
299
300    Returns
301    -------
302    root : `Root`
303        Storage root of the account.
304    """
305    assert not state._snapshots
306    if address in state._storage_tries:
307        return root(state._storage_tries[address])
308    else:
309        return EMPTY_TRIE_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 state_root(state: State) -> ethereum.base_types.Bytes32:
312def state_root(state: State) -> Root:
313    """
314    Calculate the state root.
315
316    Parameters
317    ----------
318    state:
319        The current state.
320
321    Returns
322    -------
323    root : `Root`
324        The state root.
325    """
326    assert not state._snapshots
327
328    def get_storage_root(address: Address) -> Root:
329        return storage_root(state, address)
330
331    return root(state._main_trie, get_storage_root=get_storage_root)

Calculate the state root.

Parameters

state: The current state.

Returns

root : Root The state root.

def account_exists( state: State, address: ethereum.base_types.Bytes20) -> bool:
334def account_exists(state: State, address: Address) -> bool:
335    """
336    Checks if an account exists in the state trie
337
338    Parameters
339    ----------
340    state:
341        The state
342    address:
343        Address of the account that needs to be checked.
344
345    Returns
346    -------
347    account_exists : `bool`
348        True if account exists in the state trie, False otherwise
349    """
350    return get_account_optional(state, address) is not None

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_has_code_or_nonce( state: State, address: ethereum.base_types.Bytes20) -> bool:
353def account_has_code_or_nonce(state: State, address: Address) -> bool:
354    """
355    Checks if an account has non zero nonce or non empty code
356
357    Parameters
358    ----------
359    state:
360        The state
361    address:
362        Address of the account that needs to be checked.
363
364    Returns
365    -------
366    has_code_or_nonce : `bool`
367        True if if an account has non zero nonce or non empty code,
368        False otherwise.
369    """
370    account = get_account(state, address)
371    return account.nonce != Uint(0) or account.code != b""

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 is_account_empty( state: State, address: ethereum.base_types.Bytes20) -> bool:
374def is_account_empty(state: State, address: Address) -> bool:
375    """
376    Checks if an account has zero nonce, empty code and zero 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    is_empty : `bool`
388        True if if an account has zero nonce, empty code and zero balance,
389        False otherwise.
390    """
391    account = get_account(state, address)
392    return (
393        account.nonce == Uint(0)
394        and account.code == b""
395        and account.balance == 0
396    )

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 account_exists_and_is_empty( state: State, address: ethereum.base_types.Bytes20) -> bool:
399def account_exists_and_is_empty(state: State, address: Address) -> bool:
400    """
401    Checks if an account exists and has zero nonce, empty code and zero
402    balance.
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    exists_and_is_empty : `bool`
414        True if an account exists and has zero nonce, empty code and zero
415        balance, False otherwise.
416    """
417    account = get_account_optional(state, address)
418    return (
419        account is not None
420        and account.nonce == Uint(0)
421        and account.code == b""
422        and account.balance == 0
423    )

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

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 modify_state( state: State, address: ethereum.base_types.Bytes20, f: Callable[[ethereum.muir_glacier.fork_types.Account], NoneType]) -> None:
453def modify_state(
454    state: State, address: Address, f: Callable[[Account], None]
455) -> None:
456    """
457    Modify an `Account` in the `State`.
458    """
459    set_account(state, address, modify(get_account(state, address), f))

Modify an Account in the State.

def move_ether( state: State, sender_address: ethereum.base_types.Bytes20, recipient_address: ethereum.base_types.Bytes20, amount: ethereum.base_types.U256) -> None:
462def move_ether(
463    state: State,
464    sender_address: Address,
465    recipient_address: Address,
466    amount: U256,
467) -> None:
468    """
469    Move funds between accounts.
470    """
471
472    def reduce_sender_balance(sender: Account) -> None:
473        ensure(sender.balance >= amount, AssertionError)
474        sender.balance -= amount
475
476    def increase_recipient_balance(recipient: Account) -> None:
477        recipient.balance += amount
478
479    modify_state(state, sender_address, reduce_sender_balance)
480    modify_state(state, recipient_address, increase_recipient_balance)

Move funds between accounts.

def set_account_balance( state: State, address: ethereum.base_types.Bytes20, amount: ethereum.base_types.U256) -> None:
483def set_account_balance(state: State, address: Address, amount: U256) -> None:
484    """
485    Sets the balance of an account.
486
487    Parameters
488    ----------
489    state:
490        The current state.
491
492    address:
493        Address of the account whose nonce needs to be incremented.
494
495    amount:
496        The amount that needs to set in balance.
497    """
498
499    def set_balance(account: Account) -> None:
500        account.balance = amount
501
502    modify_state(state, address, set_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 touch_account( state: State, address: ethereum.base_types.Bytes20) -> None:
505def touch_account(state: State, address: Address) -> None:
506    """
507    Initializes an account to state.
508
509    Parameters
510    ----------
511    state:
512        The current state.
513
514    address:
515        The address of the account that need to initialised.
516    """
517    if not account_exists(state, address):
518        set_account(state, address, EMPTY_ACCOUNT)

Initializes an account to state.

Parameters

state: The current state.

address: The address of the account that need to initialised.

def increment_nonce( state: State, address: ethereum.base_types.Bytes20) -> None:
521def increment_nonce(state: State, address: Address) -> None:
522    """
523    Increments the nonce of an account.
524
525    Parameters
526    ----------
527    state:
528        The current state.
529
530    address:
531        Address of the account whose nonce needs to be incremented.
532    """
533
534    def increase_nonce(sender: Account) -> None:
535        sender.nonce += 1
536
537    modify_state(state, address, increase_nonce)

Increments the nonce of an account.

Parameters

state: The current state.

address: Address of the account whose nonce needs to be incremented.

def set_code( state: State, address: ethereum.base_types.Bytes20, code: bytes) -> None:
540def set_code(state: State, address: Address, code: Bytes) -> None:
541    """
542    Sets Account code.
543
544    Parameters
545    ----------
546    state:
547        The current state.
548
549    address:
550        Address of the account whose code needs to be update.
551
552    code:
553        The bytecode that needs to be set.
554    """
555
556    def write_code(sender: Account) -> None:
557        sender.code = code
558
559    modify_state(state, address, write_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 create_ether( state: State, address: ethereum.base_types.Bytes20, amount: ethereum.base_types.U256) -> None:
562def create_ether(state: State, address: Address, amount: U256) -> None:
563    """
564    Add newly created ether to an account.
565
566    Parameters
567    ----------
568    state:
569        The current state.
570    address:
571        Address of the account to which ether is added.
572    amount:
573        The amount of ether to be added to the account of interest.
574    """
575
576    def increase_balance(account: Account) -> None:
577        account.balance += amount
578
579    modify_state(state, address, increase_balance)

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 get_storage_original( state: State, address: ethereum.base_types.Bytes20, key: bytes) -> ethereum.base_types.U256:
582def get_storage_original(state: State, address: Address, key: Bytes) -> U256:
583    """
584    Get the original value in a storage slot i.e. the value before the current
585    transaction began. This function reads the value from the snapshots taken
586    before executing the transaction.
587
588    Parameters
589    ----------
590    state:
591        The current state.
592    address:
593        Address of the account to read the value from.
594    key:
595        Key of the storage slot.
596    """
597    # In the transaction where an account is created, its preexisting storage
598    # is ignored.
599    if address in state._created_accounts:
600        return U256(0)
601
602    _, original_trie = state._snapshots[0]
603    original_account_trie = original_trie.get(address)
604
605    if original_account_trie is None:
606        original_value = U256(0)
607    else:
608        original_value = trie_get(original_account_trie, key)
609
610    assert isinstance(original_value, U256)
611
612    return original_value

Get the original value in a storage slot i.e. the value before the current transaction began. This function reads the value from the snapshots taken before executing the transaction.

Parameters

state: The current state. address: Address of the account to read the value from. key: Key of the storage slot.