ethereum.forks.dao_fork.vm.instructions.environment

Ethereum Virtual Machine (EVM) Environmental Instructions.

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

Introduction

Implementations of the EVM environment related instructions.

address

Pushes the address of the current executing account to the stack.

Parameters

evm : The current EVM frame.

def address(evm: Evm) -> None:
31
    """
32
    Pushes the address of the current executing account to the stack.
33
34
    Parameters
35
    ----------
36
    evm :
37
        The current EVM frame.
38
39
    """
40
    # STACK
41
    pass
42
43
    # GAS
44
    charge_gas(evm, GasCosts.OPCODE_ADDRESS)
45
46
    # OPERATION
47
    push(evm.stack, U256.from_be_bytes(evm.message.current_target))
48
49
    # PROGRAM COUNTER
50
    evm.pc += Uint(1)

balance

Pushes the balance of the given account onto the stack.

Parameters

evm : The current EVM frame.

def balance(evm: Evm) -> None:
54
    """
55
    Pushes the balance of the given account onto the stack.
56
57
    Parameters
58
    ----------
59
    evm :
60
        The current EVM frame.
61
62
    """
63
    # STACK
64
    address = to_address_masked(pop(evm.stack))
65
66
    # GAS
67
    charge_gas(evm, GasCosts.OPCODE_BALANCE)
68
69
    # OPERATION
70
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
71
    tx_state = evm.message.tx_env.state
72
    balance = get_account(tx_state, address).balance
73
74
    push(evm.stack, balance)
75
76
    # PROGRAM COUNTER
77
    evm.pc += Uint(1)

origin

Pushes the address of the original transaction sender to the stack. The origin address can only be an EOA.

Parameters

evm : The current EVM frame.

def origin(evm: Evm) -> None:
81
    """
82
    Pushes the address of the original transaction sender to the stack.
83
    The origin address can only be an EOA.
84
85
    Parameters
86
    ----------
87
    evm :
88
        The current EVM frame.
89
90
    """
91
    # STACK
92
    pass
93
94
    # GAS
95
    charge_gas(evm, GasCosts.OPCODE_ORIGIN)
96
97
    # OPERATION
98
    push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin))
99
100
    # PROGRAM COUNTER
101
    evm.pc += Uint(1)

caller

Pushes the address of the caller onto the stack.

Parameters

evm : The current EVM frame.

def caller(evm: Evm) -> None:
105
    """
106
    Pushes the address of the caller onto the stack.
107
108
    Parameters
109
    ----------
110
    evm :
111
        The current EVM frame.
112
113
    """
114
    # STACK
115
    pass
116
117
    # GAS
118
    charge_gas(evm, GasCosts.OPCODE_CALLER)
119
120
    # OPERATION
121
    push(evm.stack, U256.from_be_bytes(evm.message.caller))
122
123
    # PROGRAM COUNTER
124
    evm.pc += Uint(1)

callvalue

Push the value (in wei) sent with the call onto the stack.

Parameters

evm : The current EVM frame.

def callvalue(evm: Evm) -> None:
128
    """
129
    Push the value (in wei) sent with the call onto the stack.
130
131
    Parameters
132
    ----------
133
    evm :
134
        The current EVM frame.
135
136
    """
137
    # STACK
138
    pass
139
140
    # GAS
141
    charge_gas(evm, GasCosts.OPCODE_CALLVALUE)
142
143
    # OPERATION
144
    push(evm.stack, evm.message.value)
145
146
    # PROGRAM COUNTER
147
    evm.pc += Uint(1)

calldataload

Push a word (32 bytes) of the input data belonging to the current environment onto the stack.

Parameters

evm : The current EVM frame.

def calldataload(evm: Evm) -> None:
151
    """
152
    Push a word (32 bytes) of the input data belonging to the current
153
    environment onto the stack.
154
155
    Parameters
156
    ----------
157
    evm :
158
        The current EVM frame.
159
160
    """
161
    # STACK
162
    start_index = pop(evm.stack)
163
164
    # GAS
165
    charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD)
166
167
    # OPERATION
168
    value = buffer_read(evm.message.data, start_index, U256(32))
169
170
    push(evm.stack, U256.from_be_bytes(value))
171
172
    # PROGRAM COUNTER
173
    evm.pc += Uint(1)

calldatasize

Push the size of input data in current environment onto the stack.

Parameters

evm : The current EVM frame.

def calldatasize(evm: Evm) -> None:
177
    """
178
    Push the size of input data in current environment onto the stack.
179
180
    Parameters
181
    ----------
182
    evm :
183
        The current EVM frame.
184
185
    """
186
    # STACK
187
    pass
188
189
    # GAS
190
    charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE)
191
192
    # OPERATION
193
    push(evm.stack, U256(len(evm.message.data)))
194
195
    # PROGRAM COUNTER
196
    evm.pc += Uint(1)

calldatacopy

Copy a portion of the input data in current environment to memory.

This will also expand the memory, in case that the memory is insufficient to store the data.

Parameters

evm : The current EVM frame.

def calldatacopy(evm: Evm) -> None:
200
    """
201
    Copy a portion of the input data in current environment to memory.
202
203
    This will also expand the memory, in case that the memory is insufficient
204
    to store the data.
205
206
    Parameters
207
    ----------
208
    evm :
209
        The current EVM frame.
210
211
    """
212
    # STACK
213
    memory_start_index = pop(evm.stack)
214
    data_start_index = pop(evm.stack)
215
    size = pop(evm.stack)
216
217
    # GAS
218
    words = ceil32(Uint(size)) // Uint(32)
219
    copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words
220
    extend_memory = calculate_gas_extend_memory(
221
        evm.memory, [(memory_start_index, size)]
222
    )
223
    charge_gas(
224
        evm,
225
        GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost,
226
    )
227
228
    # OPERATION
229
    evm.memory += b"\x00" * extend_memory.expand_by
230
    value = buffer_read(evm.message.data, data_start_index, size)
231
    memory_write(evm.memory, memory_start_index, value)
232
233
    # PROGRAM COUNTER
234
    evm.pc += Uint(1)

codesize

Push the size of code running in current environment onto the stack.

Parameters

evm : The current EVM frame.

def codesize(evm: Evm) -> None:
238
    """
239
    Push the size of code running in current environment onto the stack.
240
241
    Parameters
242
    ----------
243
    evm :
244
        The current EVM frame.
245
246
    """
247
    # STACK
248
    pass
249
250
    # GAS
251
    charge_gas(evm, GasCosts.OPCODE_CODESIZE)
252
253
    # OPERATION
254
    push(evm.stack, U256(len(evm.code)))
255
256
    # PROGRAM COUNTER
257
    evm.pc += Uint(1)

codecopy

Copy a portion of the code in current environment to memory.

This will also expand the memory, in case that the memory is insufficient to store the data.

Parameters

evm : The current EVM frame.

def codecopy(evm: Evm) -> None:
261
    """
262
    Copy a portion of the code in current environment to memory.
263
264
    This will also expand the memory, in case that the memory is insufficient
265
    to store the data.
266
267
    Parameters
268
    ----------
269
    evm :
270
        The current EVM frame.
271
272
    """
273
    # STACK
274
    memory_start_index = pop(evm.stack)
275
    code_start_index = pop(evm.stack)
276
    size = pop(evm.stack)
277
278
    # GAS
279
    words = ceil32(Uint(size)) // Uint(32)
280
    copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words
281
    extend_memory = calculate_gas_extend_memory(
282
        evm.memory, [(memory_start_index, size)]
283
    )
284
    charge_gas(
285
        evm,
286
        GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost,
287
    )
288
289
    # OPERATION
290
    evm.memory += b"\x00" * extend_memory.expand_by
291
    value = buffer_read(evm.code, code_start_index, size)
292
    memory_write(evm.memory, memory_start_index, value)
293
294
    # PROGRAM COUNTER
295
    evm.pc += Uint(1)

gasprice

Push the gas price used in current environment onto the stack.

Parameters

evm : The current EVM frame.

def gasprice(evm: Evm) -> None:
299
    """
300
    Push the gas price used in current environment onto the stack.
301
302
    Parameters
303
    ----------
304
    evm :
305
        The current EVM frame.
306
307
    """
308
    # STACK
309
    pass
310
311
    # GAS
312
    charge_gas(evm, GasCosts.OPCODE_GASPRICE)
313
314
    # OPERATION
315
    push(evm.stack, U256(evm.message.tx_env.gas_price))
316
317
    # PROGRAM COUNTER
318
    evm.pc += Uint(1)

extcodesize

Push the code size of a given account onto the stack.

Parameters

evm : The current EVM frame.

def extcodesize(evm: Evm) -> None:
322
    """
323
    Push the code size of a given account onto the stack.
324
325
    Parameters
326
    ----------
327
    evm :
328
        The current EVM frame.
329
330
    """
331
    # STACK
332
    address = to_address_masked(pop(evm.stack))
333
334
    # GAS
335
    charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE)
336
337
    # OPERATION
338
    tx_state = evm.message.tx_env.state
339
    account = get_account(tx_state, address)
340
    code = get_code(tx_state, account.code_hash)
341
342
    codesize = U256(len(code))
343
    push(evm.stack, codesize)
344
345
    # PROGRAM COUNTER
346
    evm.pc += Uint(1)

extcodecopy

Copy a portion of an account's code to memory.

Parameters

evm : The current EVM frame.

def extcodecopy(evm: Evm) -> None:
350
    """
351
    Copy a portion of an account's code to memory.
352
353
    Parameters
354
    ----------
355
    evm :
356
        The current EVM frame.
357
358
    """
359
    # STACK
360
    address = to_address_masked(pop(evm.stack))
361
    memory_start_index = pop(evm.stack)
362
    code_start_index = pop(evm.stack)
363
    size = pop(evm.stack)
364
365
    # GAS
366
    words = ceil32(Uint(size)) // Uint(32)
367
    copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words
368
    extend_memory = calculate_gas_extend_memory(
369
        evm.memory, [(memory_start_index, size)]
370
    )
371
    charge_gas(
372
        evm,
373
        GasCosts.OPCODE_EXTERNAL_BASE + copy_gas_cost + extend_memory.cost,
374
    )
375
376
    # OPERATION
377
    evm.memory += b"\x00" * extend_memory.expand_by
378
    tx_state = evm.message.tx_env.state
379
    account = get_account(tx_state, address)
380
    code = get_code(tx_state, account.code_hash)
381
382
    value = buffer_read(code, code_start_index, size)
383
    memory_write(evm.memory, memory_start_index, value)
384
385
    # PROGRAM COUNTER
386
    evm.pc += Uint(1)