ethereum.homestead.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""

modify_state

Modify an Account in the State.

def modify_state(state: State, ​​address: Address, ​​f: Callable[[Account], None]) -> None:
349
    """
350
    Modify an `Account` in the `State`.
351
    """
352
    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:
361
    """
362
    Move funds between accounts.
363
    """
364
365
    def reduce_sender_balance(sender: Account) -> None:
366
        if sender.balance < amount:
367
            raise AssertionError
368
        sender.balance -= amount
369
370
    def increase_recipient_balance(recipient: Account) -> None:
371
        recipient.balance += amount
372
373
    modify_state(state, sender_address, reduce_sender_balance)
374
    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:
378
    """
379
    Sets the balance of an account.
380
381
    Parameters
382
    ----------
383
    state:
384
        The current state.
385
386
    address:
387
        Address of the account whose nonce needs to be incremented.
388
389
    amount:
390
        The amount that needs to set in balance.
391
    """
392
393
    def set_balance(account: Account) -> None:
394
        account.balance = amount
395
396
    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:
400
    """
401
    Initializes an account to state.
402
403
    Parameters
404
    ----------
405
    state:
406
        The current state.
407
408
    address:
409
        The address of the account that need to initialised.
410
    """
411
    if not account_exists(state, address):
412
        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:
416
    """
417
    Increments the nonce of an account.
418
419
    Parameters
420
    ----------
421
    state:
422
        The current state.
423
424
    address:
425
        Address of the account whose nonce needs to be incremented.
426
    """
427
428
    def increase_nonce(sender: Account) -> None:
429
        sender.nonce += 1
430
431
    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:
435
    """
436
    Sets Account code.
437
438
    Parameters
439
    ----------
440
    state:
441
        The current state.
442
443
    address:
444
        Address of the account whose code needs to be update.
445
446
    code:
447
        The bytecode that needs to be set.
448
    """
449
450
    def write_code(sender: Account) -> None:
451
        sender.code = code
452
453
    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:
457
    """
458
    Add newly created ether to an account.
459
460
    Parameters
461
    ----------
462
    state:
463
        The current state.
464
    address:
465
        Address of the account to which ether is added.
466
    amount:
467
        The amount of ether to be added to the account of interest.
468
    """
469
470
    def increase_balance(account: Account) -> None:
471
        account.balance += amount
472
473
    modify_state(state, address, increase_balance)