ethereum.berlin.vm.instructions.environmentethereum.london.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:
40
    """
41
    Pushes the address of the current executing account to the stack.
42
43
    Parameters
44
    ----------
45
    evm :
46
        The current EVM frame.
47
48
    """
49
    # STACK
50
    pass
51
52
    # GAS
53
    charge_gas(evm, GAS_BASE)
54
55
    # OPERATION
56
    push(evm.stack, U256.from_be_bytes(evm.message.current_target))
57
58
    # PROGRAM COUNTER
59
    evm.pc += 1

balance

Pushes the balance of the given account onto the stack.

Parameters

evm : The current EVM frame.

def balance(evm: Evm) -> None:
63
    """
64
    Pushes the balance of the given account onto the stack.
65
66
    Parameters
67
    ----------
68
    evm :
69
        The current EVM frame.
70
71
    """
72
    # STACK
73
    address = to_address(pop(evm.stack))
74
75
    # GAS
76
    if address in evm.accessed_addresses:
77
        charge_gas(evm, GAS_WARM_ACCESS)
78
    else:
79
        evm.accessed_addresses.add(address)
80
        charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS)
81
82
    # OPERATION
83
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
84
    balance = get_account(evm.env.state, address).balance
85
86
    push(evm.stack, balance)
87
88
    # PROGRAM COUNTER
89
    evm.pc += 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:
93
    """
94
    Pushes the address of the original transaction sender to the stack.
95
    The origin address can only be an EOA.
96
97
    Parameters
98
    ----------
99
    evm :
100
        The current EVM frame.
101
102
    """
103
    # STACK
104
    pass
105
106
    # GAS
107
    charge_gas(evm, GAS_BASE)
108
109
    # OPERATION
110
    push(evm.stack, U256.from_be_bytes(evm.env.origin))
111
112
    # PROGRAM COUNTER
113
    evm.pc += 1

caller

Pushes the address of the caller onto the stack.

Parameters

evm : The current EVM frame.

def caller(evm: Evm) -> None:
117
    """
118
    Pushes the address of the caller onto the stack.
119
120
    Parameters
121
    ----------
122
    evm :
123
        The current EVM frame.
124
125
    """
126
    # STACK
127
    pass
128
129
    # GAS
130
    charge_gas(evm, GAS_BASE)
131
132
    # OPERATION
133
    push(evm.stack, U256.from_be_bytes(evm.message.caller))
134
135
    # PROGRAM COUNTER
136
    evm.pc += 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:
140
    """
141
    Push the value (in wei) sent with the call onto the stack.
142
143
    Parameters
144
    ----------
145
    evm :
146
        The current EVM frame.
147
148
    """
149
    # STACK
150
    pass
151
152
    # GAS
153
    charge_gas(evm, GAS_BASE)
154
155
    # OPERATION
156
    push(evm.stack, evm.message.value)
157
158
    # PROGRAM COUNTER
159
    evm.pc += 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:
163
    """
164
    Push a word (32 bytes) of the input data belonging to the current
165
    environment onto the stack.
166
167
    Parameters
168
    ----------
169
    evm :
170
        The current EVM frame.
171
172
    """
173
    # STACK
174
    start_index = pop(evm.stack)
175
176
    # GAS
177
    charge_gas(evm, GAS_VERY_LOW)
178
179
    # OPERATION
180
    value = buffer_read(evm.message.data, start_index, U256(32))
181
182
    push(evm.stack, U256.from_be_bytes(value))
183
184
    # PROGRAM COUNTER
185
    evm.pc += 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:
189
    """
190
    Push the size of input data in current environment onto the stack.
191
192
    Parameters
193
    ----------
194
    evm :
195
        The current EVM frame.
196
197
    """
198
    # STACK
199
    pass
200
201
    # GAS
202
    charge_gas(evm, GAS_BASE)
203
204
    # OPERATION
205
    push(evm.stack, U256(len(evm.message.data)))
206
207
    # PROGRAM COUNTER
208
    evm.pc += 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:
212
    """
213
    Copy a portion of the input data in current environment to memory.
214
215
    This will also expand the memory, in case that the memory is insufficient
216
    to store the data.
217
218
    Parameters
219
    ----------
220
    evm :
221
        The current EVM frame.
222
223
    """
224
    # STACK
225
    memory_start_index = pop(evm.stack)
226
    data_start_index = pop(evm.stack)
227
    size = pop(evm.stack)
228
229
    # GAS
230
    words = ceil32(Uint(size)) // 32
231
    copy_gas_cost = GAS_COPY * words
232
    extend_memory = calculate_gas_extend_memory(
233
        evm.memory, [(memory_start_index, size)]
234
    )
235
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
236
237
    # OPERATION
238
    evm.memory += b"\x00" * extend_memory.expand_by
239
    value = buffer_read(evm.message.data, data_start_index, size)
240
    memory_write(evm.memory, memory_start_index, value)
241
242
    # PROGRAM COUNTER
243
    evm.pc += 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:
247
    """
248
    Push the size of code running in current environment onto the stack.
249
250
    Parameters
251
    ----------
252
    evm :
253
        The current EVM frame.
254
255
    """
256
    # STACK
257
    pass
258
259
    # GAS
260
    charge_gas(evm, GAS_BASE)
261
262
    # OPERATION
263
    push(evm.stack, U256(len(evm.code)))
264
265
    # PROGRAM COUNTER
266
    evm.pc += 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:
270
    """
271
    Copy a portion of the code in current environment to memory.
272
273
    This will also expand the memory, in case that the memory is insufficient
274
    to store the data.
275
276
    Parameters
277
    ----------
278
    evm :
279
        The current EVM frame.
280
281
    """
282
    # STACK
283
    memory_start_index = pop(evm.stack)
284
    code_start_index = pop(evm.stack)
285
    size = pop(evm.stack)
286
287
    # GAS
288
    words = ceil32(Uint(size)) // 32
289
    copy_gas_cost = GAS_COPY * words
290
    extend_memory = calculate_gas_extend_memory(
291
        evm.memory, [(memory_start_index, size)]
292
    )
293
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
294
295
    # OPERATION
296
    evm.memory += b"\x00" * extend_memory.expand_by
297
    value = buffer_read(evm.code, code_start_index, size)
298
    memory_write(evm.memory, memory_start_index, value)
299
300
    # PROGRAM COUNTER
301
    evm.pc += 1

gasprice

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

Parameters

evm : The current EVM frame.

def gasprice(evm: Evm) -> None:
305
    """
306
    Push the gas price used in current environment onto the stack.
307
308
    Parameters
309
    ----------
310
    evm :
311
        The current EVM frame.
312
313
    """
314
    # STACK
315
    pass
316
317
    # GAS
318
    charge_gas(evm, GAS_BASE)
319
320
    # OPERATION
321
    push(evm.stack, U256(evm.env.gas_price))
322
323
    # PROGRAM COUNTER
324
    evm.pc += 1

extcodesize

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

Parameters

evm : The current EVM frame.

def extcodesize(evm: Evm) -> None:
328
    """
329
    Push the code size of a given account onto the stack.
330
331
    Parameters
332
    ----------
333
    evm :
334
        The current EVM frame.
335
336
    """
337
    # STACK
338
    address = to_address(pop(evm.stack))
339
340
    # GAS
341
    if address in evm.accessed_addresses:
342
        charge_gas(evm, GAS_WARM_ACCESS)
343
    else:
344
        evm.accessed_addresses.add(address)
345
        charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS)
346
347
    # OPERATION
348
    # Non-existent accounts default to EMPTY_ACCOUNT, which has empty code.
349
    codesize = U256(len(get_account(evm.env.state, address).code))
350
351
    push(evm.stack, codesize)
352
353
    # PROGRAM COUNTER
354
    evm.pc += 1

extcodecopy

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

Parameters

evm : The current EVM frame.

def extcodecopy(evm: Evm) -> None:
358
    """
359
    Copy a portion of an account's code to memory.
360
361
    Parameters
362
    ----------
363
    evm :
364
        The current EVM frame.
365
366
    """
367
    # STACK
368
    address = to_address(pop(evm.stack))
369
    memory_start_index = pop(evm.stack)
370
    code_start_index = pop(evm.stack)
371
    size = pop(evm.stack)
372
373
    # GAS
374
    words = ceil32(Uint(size)) // 32
375
    copy_gas_cost = GAS_COPY * words
376
    extend_memory = calculate_gas_extend_memory(
377
        evm.memory, [(memory_start_index, size)]
378
    )
379
380
    if address in evm.accessed_addresses:
381
        charge_gas(evm, GAS_WARM_ACCESS + copy_gas_cost + extend_memory.cost)
382
    else:
383
        evm.accessed_addresses.add(address)
384
        charge_gas(
385
            evm, GAS_COLD_ACCOUNT_ACCESS + copy_gas_cost + extend_memory.cost
386
        )
387
388
    # OPERATION
389
    evm.memory += b"\x00" * extend_memory.expand_by
390
    code = get_account(evm.env.state, address).code
391
    value = buffer_read(code, code_start_index, size)
392
    memory_write(evm.memory, memory_start_index, value)
393
394
    # PROGRAM COUNTER
395
    evm.pc += 1

returndatasize

Pushes the size of the return data buffer onto the stack.

Parameters

evm : The current EVM frame.

def returndatasize(evm: Evm) -> None:
399
    """
400
    Pushes the size of the return data buffer onto the stack.
401
402
    Parameters
403
    ----------
404
    evm :
405
        The current EVM frame.
406
    """
407
    # STACK
408
    pass
409
410
    # GAS
411
    charge_gas(evm, GAS_BASE)
412
413
    # OPERATION
414
    push(evm.stack, U256(len(evm.return_data)))
415
416
    # PROGRAM COUNTER
417
    evm.pc += 1

returndatacopy

Copies data from the return data buffer code to memory

Parameters

evm : The current EVM frame.

def returndatacopy(evm: Evm) -> None:
421
    """
422
    Copies data from the return data buffer code to memory
423
424
    Parameters
425
    ----------
426
    evm :
427
        The current EVM frame.
428
    """
429
    # STACK
430
    memory_start_index = pop(evm.stack)
431
    return_data_start_position = pop(evm.stack)
432
    size = pop(evm.stack)
433
434
    # GAS
435
    words = ceil32(Uint(size)) // 32
436
    copy_gas_cost = GAS_RETURN_DATA_COPY * words
437
    extend_memory = calculate_gas_extend_memory(
438
        evm.memory, [(memory_start_index, size)]
439
    )
440
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
441
    if Uint(return_data_start_position) + Uint(size) > len(evm.return_data):
442
        raise OutOfBoundsRead
443
444
    evm.memory += b"\x00" * extend_memory.expand_by
445
    value = evm.return_data[
446
        return_data_start_position : return_data_start_position + size
447
    ]
448
    memory_write(evm.memory, memory_start_index, value)
449
450
    # PROGRAM COUNTER
451
    evm.pc += 1

extcodehash

Returns the keccak256 hash of a contract’s bytecode Parameters

evm : The current EVM frame.

def extcodehash(evm: Evm) -> None:
455
    """
456
    Returns the keccak256 hash of a contract’s bytecode
457
    Parameters
458
    ----------
459
    evm :
460
        The current EVM frame.
461
    """
462
    # STACK
463
    address = to_address(pop(evm.stack))
464
465
    # GAS
466
    if address in evm.accessed_addresses:
467
        charge_gas(evm, GAS_WARM_ACCESS)
468
    else:
469
        evm.accessed_addresses.add(address)
470
        charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS)
471
472
    # OPERATION
473
    account = get_account(evm.env.state, address)
474
475
    if account == EMPTY_ACCOUNT:
476
        codehash = U256(0)
477
    else:
478
        codehash = U256.from_be_bytes(keccak256(account.code))
479
480
    push(evm.stack, codehash)
481
482
    # PROGRAM COUNTER
483
    evm.pc += 1

self_balance

Pushes the balance of the current address to the stack.

Parameters

evm : The current EVM frame.

def self_balance(evm: Evm) -> None:
487
    """
488
    Pushes the balance of the current address to the stack.
489
490
    Parameters
491
    ----------
492
    evm :
493
        The current EVM frame.
494
495
    """
496
    # STACK
497
    pass
498
499
    # GAS
500
    charge_gas(evm, GAS_FAST_STEP)
501
502
    # OPERATION
503
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
504
    balance = get_account(evm.env.state, evm.message.current_target).balance
505
506
    push(evm.stack, balance)
507
508
    # PROGRAM COUNTER
509
    evm.pc += 1

base_fee

Pushes the base fee of the current block on to the stack.

Parameters

evm : The current EVM frame.

def base_fee(evm: Evm) -> None:
513
    """
514
    Pushes the base fee of the current block on to the stack.
515
516
    Parameters
517
    ----------
518
    evm :
519
        The current EVM frame.
520
521
    """
522
    # STACK
523
    pass
524
525
    # GAS
526
    charge_gas(evm, GAS_BASE)
527
528
    # OPERATION
529
    push(evm.stack, U256(evm.env.base_fee_per_gas))
530
531
    # PROGRAM COUNTER
532
    evm.pc += 1