ethereum.shanghai.vm.instructions.environmentethereum.cancun.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:
42
    """
43
    Pushes the address of the current executing account to the stack.
44
45
    Parameters
46
    ----------
47
    evm :
48
        The current EVM frame.
49
50
    """
51
    # STACK
52
    pass
53
54
    # GAS
55
    charge_gas(evm, GAS_BASE)
56
57
    # OPERATION
58
    push(evm.stack, U256.from_be_bytes(evm.message.current_target))
59
60
    # PROGRAM COUNTER
61
    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:
65
    """
66
    Pushes the balance of the given account onto the stack.
67
68
    Parameters
69
    ----------
70
    evm :
71
        The current EVM frame.
72
73
    """
74
    # STACK
75
    address = to_address(pop(evm.stack))
76
77
    # GAS
78
    if address in evm.accessed_addresses:
79
        charge_gas(evm, GAS_WARM_ACCESS)
80
    else:
81
        evm.accessed_addresses.add(address)
82
        charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS)
83
84
    # OPERATION
85
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
86
    balance = get_account(evm.env.state, address).balance
87
88
    push(evm.stack, balance)
89
90
    # PROGRAM COUNTER
91
    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:
95
    """
96
    Pushes the address of the original transaction sender to the stack.
97
    The origin address can only be an EOA.
98
99
    Parameters
100
    ----------
101
    evm :
102
        The current EVM frame.
103
104
    """
105
    # STACK
106
    pass
107
108
    # GAS
109
    charge_gas(evm, GAS_BASE)
110
111
    # OPERATION
112
    push(evm.stack, U256.from_be_bytes(evm.env.origin))
113
114
    # PROGRAM COUNTER
115
    evm.pc += 1

caller

Pushes the address of the caller onto the stack.

Parameters

evm : The current EVM frame.

def caller(evm: Evm) -> None:
119
    """
120
    Pushes the address of the caller onto the stack.
121
122
    Parameters
123
    ----------
124
    evm :
125
        The current EVM frame.
126
127
    """
128
    # STACK
129
    pass
130
131
    # GAS
132
    charge_gas(evm, GAS_BASE)
133
134
    # OPERATION
135
    push(evm.stack, U256.from_be_bytes(evm.message.caller))
136
137
    # PROGRAM COUNTER
138
    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:
142
    """
143
    Push the value (in wei) sent with the call onto the stack.
144
145
    Parameters
146
    ----------
147
    evm :
148
        The current EVM frame.
149
150
    """
151
    # STACK
152
    pass
153
154
    # GAS
155
    charge_gas(evm, GAS_BASE)
156
157
    # OPERATION
158
    push(evm.stack, evm.message.value)
159
160
    # PROGRAM COUNTER
161
    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:
165
    """
166
    Push a word (32 bytes) of the input data belonging to the current
167
    environment onto the stack.
168
169
    Parameters
170
    ----------
171
    evm :
172
        The current EVM frame.
173
174
    """
175
    # STACK
176
    start_index = pop(evm.stack)
177
178
    # GAS
179
    charge_gas(evm, GAS_VERY_LOW)
180
181
    # OPERATION
182
    value = buffer_read(evm.message.data, start_index, U256(32))
183
184
    push(evm.stack, U256.from_be_bytes(value))
185
186
    # PROGRAM COUNTER
187
    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:
191
    """
192
    Push the size of input data in current environment onto the stack.
193
194
    Parameters
195
    ----------
196
    evm :
197
        The current EVM frame.
198
199
    """
200
    # STACK
201
    pass
202
203
    # GAS
204
    charge_gas(evm, GAS_BASE)
205
206
    # OPERATION
207
    push(evm.stack, U256(len(evm.message.data)))
208
209
    # PROGRAM COUNTER
210
    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:
214
    """
215
    Copy a portion of the input data in current environment to memory.
216
217
    This will also expand the memory, in case that the memory is insufficient
218
    to store the data.
219
220
    Parameters
221
    ----------
222
    evm :
223
        The current EVM frame.
224
225
    """
226
    # STACK
227
    memory_start_index = pop(evm.stack)
228
    data_start_index = pop(evm.stack)
229
    size = pop(evm.stack)
230
231
    # GAS
232
    words = ceil32(Uint(size)) // 32
233
    copy_gas_cost = GAS_COPY * words
234
    extend_memory = calculate_gas_extend_memory(
235
        evm.memory, [(memory_start_index, size)]
236
    )
237
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
238
239
    # OPERATION
240
    evm.memory += b"\x00" * extend_memory.expand_by
241
    value = buffer_read(evm.message.data, data_start_index, size)
242
    memory_write(evm.memory, memory_start_index, value)
243
244
    # PROGRAM COUNTER
245
    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:
249
    """
250
    Push the size of code running in current environment onto the stack.
251
252
    Parameters
253
    ----------
254
    evm :
255
        The current EVM frame.
256
257
    """
258
    # STACK
259
    pass
260
261
    # GAS
262
    charge_gas(evm, GAS_BASE)
263
264
    # OPERATION
265
    push(evm.stack, U256(len(evm.code)))
266
267
    # PROGRAM COUNTER
268
    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:
272
    """
273
    Copy a portion of the code in current environment to memory.
274
275
    This will also expand the memory, in case that the memory is insufficient
276
    to store the data.
277
278
    Parameters
279
    ----------
280
    evm :
281
        The current EVM frame.
282
283
    """
284
    # STACK
285
    memory_start_index = pop(evm.stack)
286
    code_start_index = pop(evm.stack)
287
    size = pop(evm.stack)
288
289
    # GAS
290
    words = ceil32(Uint(size)) // 32
291
    copy_gas_cost = GAS_COPY * words
292
    extend_memory = calculate_gas_extend_memory(
293
        evm.memory, [(memory_start_index, size)]
294
    )
295
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
296
297
    # OPERATION
298
    evm.memory += b"\x00" * extend_memory.expand_by
299
    value = buffer_read(evm.code, code_start_index, size)
300
    memory_write(evm.memory, memory_start_index, value)
301
302
    # PROGRAM COUNTER
303
    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:
307
    """
308
    Push the gas price used in current environment onto the stack.
309
310
    Parameters
311
    ----------
312
    evm :
313
        The current EVM frame.
314
315
    """
316
    # STACK
317
    pass
318
319
    # GAS
320
    charge_gas(evm, GAS_BASE)
321
322
    # OPERATION
323
    push(evm.stack, U256(evm.env.gas_price))
324
325
    # PROGRAM COUNTER
326
    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:
330
    """
331
    Push the code size of a given account onto the stack.
332
333
    Parameters
334
    ----------
335
    evm :
336
        The current EVM frame.
337
338
    """
339
    # STACK
340
    address = to_address(pop(evm.stack))
341
342
    # GAS
343
    if address in evm.accessed_addresses:
344
        charge_gas(evm, GAS_WARM_ACCESS)
345
    else:
346
        evm.accessed_addresses.add(address)
347
        charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS)
348
349
    # OPERATION
350
    # Non-existent accounts default to EMPTY_ACCOUNT, which has empty code.
351
    codesize = U256(len(get_account(evm.env.state, address).code))
352
353
    push(evm.stack, codesize)
354
355
    # PROGRAM COUNTER
356
    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:
360
    """
361
    Copy a portion of an account's code to memory.
362
363
    Parameters
364
    ----------
365
    evm :
366
        The current EVM frame.
367
368
    """
369
    # STACK
370
    address = to_address(pop(evm.stack))
371
    memory_start_index = pop(evm.stack)
372
    code_start_index = pop(evm.stack)
373
    size = pop(evm.stack)
374
375
    # GAS
376
    words = ceil32(Uint(size)) // 32
377
    copy_gas_cost = GAS_COPY * words
378
    extend_memory = calculate_gas_extend_memory(
379
        evm.memory, [(memory_start_index, size)]
380
    )
381
382
    if address in evm.accessed_addresses:
383
        charge_gas(evm, GAS_WARM_ACCESS + copy_gas_cost + extend_memory.cost)
384
    else:
385
        evm.accessed_addresses.add(address)
386
        charge_gas(
387
            evm, GAS_COLD_ACCOUNT_ACCESS + copy_gas_cost + extend_memory.cost
388
        )
389
390
    # OPERATION
391
    evm.memory += b"\x00" * extend_memory.expand_by
392
    code = get_account(evm.env.state, address).code
393
    value = buffer_read(code, code_start_index, size)
394
    memory_write(evm.memory, memory_start_index, value)
395
396
    # PROGRAM COUNTER
397
    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:
401
    """
402
    Pushes the size of the return data buffer onto the stack.
403
404
    Parameters
405
    ----------
406
    evm :
407
        The current EVM frame.
408
    """
409
    # STACK
410
    pass
411
412
    # GAS
413
    charge_gas(evm, GAS_BASE)
414
415
    # OPERATION
416
    push(evm.stack, U256(len(evm.return_data)))
417
418
    # PROGRAM COUNTER
419
    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:
423
    """
424
    Copies data from the return data buffer code to memory
425
426
    Parameters
427
    ----------
428
    evm :
429
        The current EVM frame.
430
    """
431
    # STACK
432
    memory_start_index = pop(evm.stack)
433
    return_data_start_position = pop(evm.stack)
434
    size = pop(evm.stack)
435
436
    # GAS
437
    words = ceil32(Uint(size)) // 32
438
    copy_gas_cost = GAS_RETURN_DATA_COPY * words
439
    extend_memory = calculate_gas_extend_memory(
440
        evm.memory, [(memory_start_index, size)]
441
    )
442
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
443
    if Uint(return_data_start_position) + Uint(size) > len(evm.return_data):
444
        raise OutOfBoundsRead
445
446
    evm.memory += b"\x00" * extend_memory.expand_by
447
    value = evm.return_data[
448
        return_data_start_position : return_data_start_position + size
449
    ]
450
    memory_write(evm.memory, memory_start_index, value)
451
452
    # PROGRAM COUNTER
453
    evm.pc += 1

extcodehash

Returns the keccak256 hash of a contract’s bytecode Parameters

evm : The current EVM frame.

def extcodehash(evm: Evm) -> None:
457
    """
458
    Returns the keccak256 hash of a contract’s bytecode
459
    Parameters
460
    ----------
461
    evm :
462
        The current EVM frame.
463
    """
464
    # STACK
465
    address = to_address(pop(evm.stack))
466
467
    # GAS
468
    if address in evm.accessed_addresses:
469
        charge_gas(evm, GAS_WARM_ACCESS)
470
    else:
471
        evm.accessed_addresses.add(address)
472
        charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS)
473
474
    # OPERATION
475
    account = get_account(evm.env.state, address)
476
477
    if account == EMPTY_ACCOUNT:
478
        codehash = U256(0)
479
    else:
480
        codehash = U256.from_be_bytes(keccak256(account.code))
481
482
    push(evm.stack, codehash)
483
484
    # PROGRAM COUNTER
485
    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:
489
    """
490
    Pushes the balance of the current address to the stack.
491
492
    Parameters
493
    ----------
494
    evm :
495
        The current EVM frame.
496
497
    """
498
    # STACK
499
    pass
500
501
    # GAS
502
    charge_gas(evm, GAS_FAST_STEP)
503
504
    # OPERATION
505
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
506
    balance = get_account(evm.env.state, evm.message.current_target).balance
507
508
    push(evm.stack, balance)
509
510
    # PROGRAM COUNTER
511
    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:
515
    """
516
    Pushes the base fee of the current block on to the stack.
517
518
    Parameters
519
    ----------
520
    evm :
521
        The current EVM frame.
522
523
    """
524
    # STACK
525
    pass
526
527
    # GAS
528
    charge_gas(evm, GAS_BASE)
529
530
    # OPERATION
531
    push(evm.stack, U256(evm.env.base_fee_per_gas))
532
533
    # PROGRAM COUNTER
534
    evm.pc += 1

blob_hash

Pushes the versioned hash at a particular index on to the stack.

Parameters

evm : The current EVM frame.

def blob_hash(evm: Evm) -> None:
538
    """
539
    Pushes the versioned hash at a particular index on to the stack.
540
541
    Parameters
542
    ----------
543
    evm :
544
        The current EVM frame.
545
546
    """
547
    # STACK
548
    index = pop(evm.stack)
549
550
    # GAS
551
    charge_gas(evm, GAS_BLOBHASH_OPCODE)
552
553
    # OPERATION
554
    if index < len(evm.env.blob_versioned_hashes):
555
        blob_hash = evm.env.blob_versioned_hashes[index]
556
    else:
557
        blob_hash = Bytes32(b"\x00" * 32)
558
    push(evm.stack, U256.from_be_bytes(blob_hash))
559
560
    # PROGRAM COUNTER
561
    evm.pc += 1

blob_base_fee

Pushes the blob base fee on to the stack.

Parameters

evm : The current EVM frame.

def blob_base_fee(evm: Evm) -> None:
565
    """
566
    Pushes the blob base fee on to the stack.
567
568
    Parameters
569
    ----------
570
    evm :
571
        The current EVM frame.
572
573
    """
574
    # STACK
575
    pass
576
577
    # GAS
578
    charge_gas(evm, GAS_BASE)
579
580
    # OPERATION
581
    blob_base_fee = calculate_blob_gas_price(evm.env.excess_blob_gas)
582
    push(evm.stack, U256(blob_base_fee))
583
584
    # PROGRAM COUNTER
585
    evm.pc += 1