ethereum.forks.bpo5.vmethereum.forks.amsterdam.vm

Ethereum Virtual Machine (EVM).

.. contents:: Table of Contents :backlinks: none :local:

Introduction

The abstract computer which runs the code stored in an .fork_types.Account.

__all__

33
__all__ = ("Environment", "Evm", "Message")

TRANSFER_TOPIC

34
TRANSFER_TOPIC = keccak256(b"Transfer(address,address,uint256)")

BURN_TOPIC

35
BURN_TOPIC = keccak256(b"Burn(address,uint256)")

SYSTEM_ADDRESS

36
SYSTEM_ADDRESS = Address(
37
    bytes.fromhex("fffffffffffffffffffffffffffffffffffffffe")
38
)

CALL_SUCCESS

39
CALL_SUCCESS = U256(1)

BlockEnvironment

Items external to the virtual machine itself, provided by the environment.

42
@final
43
@dataclass
class BlockEnvironment:

chain_id

49
    chain_id: U64

state

50
    state: BlockState

block_gas_limit

51
    block_gas_limit: Uint

block_hashes

52
    block_hashes: List[Hash32]

coinbase

53
    coinbase: Address

number

54
    number: Uint

base_fee_per_gas

55
    base_fee_per_gas: Uint

time

56
    time: U256

prev_randao

57
    prev_randao: Bytes32

excess_blob_gas

58
    excess_blob_gas: U64

parent_beacon_block_root

59
    parent_beacon_block_root: Hash32

block_access_list_builder

60
    block_access_list_builder: BlockAccessListBuilder

slot_number

61
    slot_number: U64

BlockOutput

Output from applying the block body to the present state.

Contains the following:

block_gas_used : ethereum.base_types.Uint Gas used for executing all transactions. block_state_gas_used : ethereum.base_types.Uint State gas used for executing all transactions. cumulative_gas_used : ethereum.base_types.Uint Cumulative gas paid by users (post-refund, post-floor). transactions_trie : ethereum.fork_types.Root Trie of all the transactions in the block. receipts_trie : ethereum.fork_types.Root Trie root of all the receipts in the block. receipt_keys : Keys of all the receipts in the block. block_logs : Bloom Logs bloom of all the logs included in all the transactions of the block. withdrawals_trie : ethereum.fork_types.Root Trie root of all the withdrawals in the block. blob_gas_used : ethereum.base_types.U64 Total blob gas used in the block. requests : Bytes Hash of all the requests in the block. block_access_list: BlockAccessList The block access list for the block.

64
@final
65
@dataclass
class BlockOutput:

block_gas_used

97
    block_gas_used: Uint = Uint(0)

block_state_gas_used

98
    block_state_gas_used: Uint = Uint(0)

cumulative_gas_used

99
    cumulative_gas_used: Uint = Uint(0)

transactions_trie

100
    transactions_trie: Trie[Bytes, Optional[Bytes | LegacyTransaction]] = (
101
        field(default_factory=lambda: Trie(secured=False, default=None))
102
    )

receipts_trie

103
    receipts_trie: Trie[Bytes, Optional[Bytes | Receipt]] = field(
104
        default_factory=lambda: Trie(secured=False, default=None)
105
    )

receipt_keys

106
    receipt_keys: Tuple[Bytes, ...] = field(default_factory=tuple)

block_logs

107
    block_logs: Tuple[Log, ...] = field(default_factory=tuple)

withdrawals_trie

108
    withdrawals_trie: Trie[Bytes, Optional[Bytes | Withdrawal]] = field(
109
        default_factory=lambda: Trie(secured=False, default=None)
110
    )

blob_gas_used

111
    blob_gas_used: U64 = U64(0)

requests

112
    requests: List[Bytes] = field(default_factory=list)

block_access_list

113
    block_access_list: BlockAccessList = field(default_factory=list)

TransactionEnvironment

Items that are used while processing a transaction.

116
@final
117
@dataclass
class TransactionEnvironment:

origin

123
    origin: Address

gas_price

124
    gas_price: Uint

gas

125
    gas: Uint

state_gas_reservoir

126
    state_gas_reservoir: Uint

access_list_addresses

127
    access_list_addresses: Set[Address]

access_list_storage_keys

128
    access_list_storage_keys: Set[Tuple[Address, Bytes32]]

state

129
    state: TransactionState

blob_versioned_hashes

130
    blob_versioned_hashes: Tuple[VersionedHash, ...]

authorizations

131
    authorizations: Tuple[Authorization, ...]

index_in_block

132
    index_in_block: Optional[Uint]

tx_hash

133
    tx_hash: Optional[Hash32]

intrinsic_regular_gas

134
    intrinsic_regular_gas: Uint

intrinsic_state_gas

135
    intrinsic_state_gas: Uint

Message

Items that are used by contract creation or message call.

138
@final
139
@dataclass
class Message:

block_env

145
    block_env: BlockEnvironment

tx_env

146
    tx_env: TransactionEnvironment

caller

147
    caller: Address

target

148
    target: Bytes0 | Address

current_target

149
    current_target: Address

gas

150
    gas: Uint

state_gas_reservoir

151
    state_gas_reservoir: Uint

value

152
    value: U256

data

153
    data: Bytes

code_address

154
    code_address: Optional[Address]

code

155
    code: Bytes

depth

156
    depth: Uint

should_transfer_value

157
    should_transfer_value: bool

is_static

158
    is_static: bool

accessed_addresses

159
    accessed_addresses: Set[Address]

accessed_storage_keys

160
    accessed_storage_keys: Set[Tuple[Address, Bytes32]]

disable_precompiles

161
    disable_precompiles: bool

parent_evm

162
    parent_evm: Optional["Evm"]

Evm

The internal state of the virtual machine.

165
@final
166
@dataclass
class Evm:

pc

170
    pc: Uint

stack

171
    stack: List[U256]

memory

172
    memory: bytearray

code

173
    code: Bytes

gas_left

174
    gas_left: Uint

state_gas_left

175
    state_gas_left: Uint

valid_jump_destinations

176
    valid_jump_destinations: Set[Uint]

logs

177
    logs: Tuple[Log, ...]

refund_counter

178
    refund_counter: int

running

179
    running: bool

message

180
    message: Message

output

181
    output: Bytes

accounts_to_delete

182
    accounts_to_delete: Set[Address]

return_data

183
    return_data: Bytes

error

184
    error: Optional[EthereumException]

accessed_addresses

185
    accessed_addresses: Set[Address]

accessed_storage_keys

186
    accessed_storage_keys: Set[Tuple[Address, Bytes32]]

regular_gas_used

187
    regular_gas_used: Uint = Uint(0)

state_gas_used

188
    state_gas_used: int = 0

state_gas_spilled

189
    state_gas_spilled: Uint = Uint(0)

credit_state_gas_refund

Credit a state gas refund to the local frame, in LIFO order.

State-gas charges draw from the reservoir first and from gas_left last, so refills credit the pool charged last first: gas_left up to state_gas_spilled, then the reservoir. This restores the exact pools the charge drew from, so the two never drift.

Parameters

evm : The frame crediting the refund. amount : The refund amount to credit.

def credit_state_gas_refund(evm: Evm, ​​amount: Uint) -> None:
193
    <snip>
209
    from_gas_left = min(amount, evm.state_gas_spilled)
210
    evm.gas_left += from_gas_left
211
    evm.state_gas_spilled -= from_gas_left
212
    evm.state_gas_left += amount - from_gas_left
213
    evm.state_gas_used -= int(amount)

incorporate_child_on_success

Incorporate the state of a successful child_evm into the parent evm.

Parameters

evm : The parent EVM. child_evm : The child evm to incorporate.

def incorporate_child_on_success(evm: Evm, ​​child_evm: Evm) -> None:
217
    <snip>
228
    evm.gas_left += child_evm.gas_left
229
    evm.state_gas_left += child_evm.state_gas_left
230
    evm.state_gas_spilled += child_evm.state_gas_spilled
231
    evm.logs += child_evm.logs
232
    evm.refund_counter += child_evm.refund_counter
233
    evm.accounts_to_delete.update(child_evm.accounts_to_delete)
234
    evm.accessed_addresses.update(child_evm.accessed_addresses)
182
    evm.accessed_storage_keys.update(child_evm.accessed_storage_keys)
235
    evm.accessed_storage_keys.update(child_evm.accessed_storage_keys)
236
    evm.regular_gas_used += child_evm.regular_gas_used
237
    evm.state_gas_used += child_evm.state_gas_used

refill_frame_state_gas

Roll back the frame's state gas in LIFO order on revert or halt.

The frame's state changes are undone, so the state gas it consumed is credited back to gas_left first and then to the reservoir, restoring the pools the charges drew from.

Parameters

evm : The frame whose state gas is rolled back.

def refill_frame_state_gas(evm: Evm) -> None:
241
    <snip>
254
    evm.gas_left += evm.state_gas_spilled
255
    evm.state_gas_left = Uint(
256
        int(evm.state_gas_left)
257
        + evm.state_gas_used
258
        - int(evm.state_gas_spilled)
259
    )
260
    evm.state_gas_used = 0
261
    evm.state_gas_spilled = Uint(0)

incorporate_child_on_error

Incorporate the state of an unsuccessful child_evm into the parent evm.

The child rolls back its own state gas via refill_frame_state_gas before returning (on both reverts and exceptional halts), so its gas_left and reservoir already reflect the LIFO refill and its state_gas_used is zero. The parent therefore only reabsorbs the child's gas_left and reservoir.

Parameters

evm : The parent EVM. child_evm : The child evm to incorporate.

def incorporate_child_on_error(evm: Evm, ​​child_evm: Evm) -> None:
268
    <snip>
197
    evm.gas_left += child_evm.gas_left
285
    evm.gas_left += child_evm.gas_left
286
    evm.state_gas_left += child_evm.state_gas_left
287
    evm.regular_gas_used += child_evm.regular_gas_used

emit_transfer_log

Emit a LOG3 for all ETH transfers satisfying EIP-7708.

Parameters

evm : The state of the ethereum virtual machine sender : The account address sending the transfer recipient : The account address receiving the transfer transfer_amount : The amount of ETH transacted

def emit_transfer_log(evm: Evm, ​​sender: Address, ​​recipient: Address, ​​transfer_amount: U256) -> None:
296
    <snip>
311
    if transfer_amount == 0:
312
        return
313
314
    padded_sender = left_pad_zero_bytes(sender, 32)
315
    padded_recipient = left_pad_zero_bytes(recipient, 32)
316
    log_entry = Log(
317
        address=SYSTEM_ADDRESS,
318
        topics=(
319
            TRANSFER_TOPIC,
320
            Hash32(padded_sender),
321
            Hash32(padded_recipient),
322
        ),
323
        data=transfer_amount.to_be_bytes32(),
324
    )
325
326
    evm.logs = evm.logs + (log_entry,)

emit_burn_log

Emit a LOG2 for ETH burn per EIP-7708.

Parameters

evm : The state of the ethereum virtual machine account : The account address whose ETH is being burned amount : The amount of ETH being burned

def emit_burn_log(evm: Evm, ​​account: Address, ​​amount: U256) -> None:
334
    <snip>
347
    if amount == 0:
348
        return
349
350
    padded_account = left_pad_zero_bytes(account, 32)
351
    log_entry = Log(
352
        address=SYSTEM_ADDRESS,
353
        topics=(
354
            BURN_TOPIC,
355
            Hash32(padded_account),
356
        ),
357
        data=amount.to_be_bytes32(),
358
    )
359
360
    evm.logs = evm.logs + (log_entry,)