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)")

SYSTEM_ADDRESS

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

CALL_SUCCESS

38
CALL_SUCCESS = U256(1)

BlockEnvironment

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

41
@final
42
@dataclass
class BlockEnvironment:

chain_id

48
    chain_id: U64

state

49
    state: BlockState

block_gas_limit

50
    block_gas_limit: Uint

block_hashes

51
    block_hashes: List[Hash32]

coinbase

52
    coinbase: Address

number

53
    number: Uint

base_fee_per_gas

54
    base_fee_per_gas: Uint

time

55
    time: U256

prev_randao

56
    prev_randao: Bytes32

excess_blob_gas

57
    excess_blob_gas: U64

parent_beacon_block_root

58
    parent_beacon_block_root: Hash32

block_access_list_builder

59
    block_access_list_builder: BlockAccessListBuilder

slot_number

60
    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.

63
@final
64
@dataclass
class BlockOutput:

block_gas_used

96
    block_gas_used: Uint = Uint(0)

block_state_gas_used

97
    block_state_gas_used: Uint = Uint(0)

cumulative_gas_used

98
    cumulative_gas_used: Uint = Uint(0)

transactions_trie

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

receipts_trie

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

receipt_keys

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

block_logs

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

withdrawals_trie

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

blob_gas_used

110
    blob_gas_used: U64 = U64(0)

requests

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

block_access_list

112
    block_access_list: BlockAccessList = field(default_factory=list)

TransactionEnvironment

Items that are used while processing a transaction.

115
@final
116
@dataclass
class TransactionEnvironment:

origin

122
    origin: Address

recipient

123
    recipient: Bytes0 | Address

value

124
    value: U256

gas_price

125
    gas_price: Uint

gas

126
    gas: Uint

state_gas_reservoir

127
    state_gas_reservoir: Uint

access_list_addresses

128
    access_list_addresses: Set[Address]

access_list_storage_keys

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

state

130
    state: TransactionState

blob_versioned_hashes

131
    blob_versioned_hashes: Tuple[VersionedHash, ...]

authorizations

132
    authorizations: Tuple[Authorization, ...]

index_in_block

133
    index_in_block: Optional[Uint]

tx_hash

134
    tx_hash: Optional[Hash32]

intrinsic_regular_gas

135
    intrinsic_regular_gas: Uint

intrinsic_state_gas

136
    intrinsic_state_gas: Uint

Message

Items that are used by contract creation or message call.

139
@final
140
@dataclass
class Message:

block_env

146
    block_env: BlockEnvironment

tx_env

147
    tx_env: TransactionEnvironment

caller

148
    caller: Address

target

149
    target: Bytes0 | Address

current_target

150
    current_target: Address

gas

151
    gas: Uint

state_gas_reservoir

152
    state_gas_reservoir: Uint

value

153
    value: U256

data

154
    data: Bytes

code_address

155
    code_address: Optional[Address]

code

156
    code: Bytes

depth

157
    depth: Uint

should_transfer_value

158
    should_transfer_value: bool

is_static

159
    is_static: bool

accessed_addresses

160
    accessed_addresses: Set[Address]

accessed_storage_keys

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

disable_precompiles

162
    disable_precompiles: bool

parent_evm

163
    parent_evm: Optional["Evm"]

Evm

The internal state of the virtual machine.

166
@final
167
@dataclass
class Evm:

pc

171
    pc: Uint

stack

172
    stack: List[U256]

memory

173
    memory: bytearray

code

174
    code: Bytes

gas_left

175
    gas_left: Uint

state_gas_left

176
    state_gas_left: Uint

valid_jump_destinations

177
    valid_jump_destinations: Set[Uint]

logs

178
    logs: Tuple[Log, ...]

refund_counter

179
    refund_counter: int

running

180
    running: bool

message

181
    message: Message

output

182
    output: Bytes

accounts_to_delete

183
    accounts_to_delete: Set[Address]

return_data

184
    return_data: Bytes

error

185
    error: Optional[EthereumException]

accessed_addresses

186
    accessed_addresses: Set[Address]

accessed_storage_keys

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

regular_gas_used

188
    regular_gas_used: Uint = Uint(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: StateGas) -> 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

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:
216
    <snip>
227
    evm.gas_left += child_evm.gas_left
228
    evm.state_gas_left += child_evm.state_gas_left
229
    evm.state_gas_spilled += child_evm.state_gas_spilled
230
    evm.logs += child_evm.logs
231
    evm.refund_counter += child_evm.refund_counter
232
    evm.accounts_to_delete.update(child_evm.accounts_to_delete)
233
    evm.accessed_addresses.update(child_evm.accessed_addresses)
182
    evm.accessed_storage_keys.update(child_evm.accessed_storage_keys)
234
    evm.accessed_storage_keys.update(child_evm.accessed_storage_keys)
235
    evm.regular_gas_used += child_evm.regular_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:
239
    <snip>
252
    evm.gas_left += evm.state_gas_spilled
253
    evm.state_gas_left = evm.message.state_gas_reservoir
254
    evm.state_gas_spilled = Uint(0)

frame_state_gas_used

Return the net state gas consumed by a finished frame.

Equal to the reservoir drawn down (state_gas_reservoir at entry minus the reservoir now) plus state_gas_spilled. May be negative when refunds exceed charges.

Parameters

evm : The finished frame.

def frame_state_gas_used(evm: Evm) -> int:
258
    <snip>
274
    return (
275
        int(evm.message.state_gas_reservoir)
276
        - int(evm.state_gas_left)
277
        + int(evm.state_gas_spilled)
278
    )

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. 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:
285
    <snip>
197
    evm.gas_left += child_evm.gas_left
301
    evm.gas_left += child_evm.gas_left
302
    evm.state_gas_left += child_evm.state_gas_left
303
    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:
312
    <snip>
327
    if transfer_amount == 0:
328
        return
329
330
    padded_sender = left_pad_zero_bytes(sender, 32)
331
    padded_recipient = left_pad_zero_bytes(recipient, 32)
332
    log_entry = Log(
333
        address=SYSTEM_ADDRESS,
334
        topics=(
335
            TRANSFER_TOPIC,
336
            Hash32(padded_sender),
337
            Hash32(padded_recipient),
338
        ),
339
        data=transfer_amount.to_be_bytes32(),
340
    )
341
342
    evm.logs = evm.logs + (log_entry,)