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:
41
    """
42
    Pushes the address of the current executing account to the stack.
43
44
    Parameters
45
    ----------
46
    evm :
47
        The current EVM frame.
48
49
    """
50
    # STACK
51
    pass
52
53
    # GAS
54
    charge_gas(evm, GAS_BASE)
55
56
    # OPERATION
57
    push(evm.stack, U256.from_be_bytes(evm.message.current_target))
58
59
    # PROGRAM COUNTER
60
    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:
64
    """
65
    Pushes the balance of the given account onto the stack.
66
67
    Parameters
68
    ----------
69
    evm :
70
        The current EVM frame.
71
72
    """
73
    # STACK
74
    address = to_address(pop(evm.stack))
75
76
    # GAS
77
    if address in evm.accessed_addresses:
78
        charge_gas(evm, GAS_WARM_ACCESS)
79
    else:
80
        evm.accessed_addresses.add(address)
81
        charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS)
82
83
    # OPERATION
84
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
85
    balance = get_account(evm.message.block_env.state, address).balance
86
87
    push(evm.stack, balance)
88
89
    # PROGRAM COUNTER
90
    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:
94
    """
95
    Pushes the address of the original transaction sender to the stack.
96
    The origin address can only be an EOA.
97
98
    Parameters
99
    ----------
100
    evm :
101
        The current EVM frame.
102
103
    """
104
    # STACK
105
    pass
106
107
    # GAS
108
    charge_gas(evm, GAS_BASE)
109
110
    # OPERATION
111
    push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin))
112
113
    # PROGRAM COUNTER
114
    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:
118
    """
119
    Pushes the address of the caller onto the stack.
120
121
    Parameters
122
    ----------
123
    evm :
124
        The current EVM frame.
125
126
    """
127
    # STACK
128
    pass
129
130
    # GAS
131
    charge_gas(evm, GAS_BASE)
132
133
    # OPERATION
134
    push(evm.stack, U256.from_be_bytes(evm.message.caller))
135
136
    # PROGRAM COUNTER
137
    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:
141
    """
142
    Push the value (in wei) sent with the call onto the stack.
143
144
    Parameters
145
    ----------
146
    evm :
147
        The current EVM frame.
148
149
    """
150
    # STACK
151
    pass
152
153
    # GAS
154
    charge_gas(evm, GAS_BASE)
155
156
    # OPERATION
157
    push(evm.stack, evm.message.value)
158
159
    # PROGRAM COUNTER
160
    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:
164
    """
165
    Push a word (32 bytes) of the input data belonging to the current
166
    environment onto the stack.
167
168
    Parameters
169
    ----------
170
    evm :
171
        The current EVM frame.
172
173
    """
174
    # STACK
175
    start_index = pop(evm.stack)
176
177
    # GAS
178
    charge_gas(evm, GAS_VERY_LOW)
179
180
    # OPERATION
181
    value = buffer_read(evm.message.data, start_index, U256(32))
182
183
    push(evm.stack, U256.from_be_bytes(value))
184
185
    # PROGRAM COUNTER
186
    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:
190
    """
191
    Push the size of input data in current environment onto the stack.
192
193
    Parameters
194
    ----------
195
    evm :
196
        The current EVM frame.
197
198
    """
199
    # STACK
200
    pass
201
202
    # GAS
203
    charge_gas(evm, GAS_BASE)
204
205
    # OPERATION
206
    push(evm.stack, U256(len(evm.message.data)))
207
208
    # PROGRAM COUNTER
209
    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:
213
    """
214
    Copy a portion of the input data in current environment to memory.
215
216
    This will also expand the memory, in case that the memory is insufficient
217
    to store the data.
218
219
    Parameters
220
    ----------
221
    evm :
222
        The current EVM frame.
223
224
    """
225
    # STACK
226
    memory_start_index = pop(evm.stack)
227
    data_start_index = pop(evm.stack)
228
    size = pop(evm.stack)
229
230
    # GAS
231
    words = ceil32(Uint(size)) // Uint(32)
232
    copy_gas_cost = GAS_COPY * words
233
    extend_memory = calculate_gas_extend_memory(
234
        evm.memory, [(memory_start_index, size)]
235
    )
236
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
237
238
    # OPERATION
239
    evm.memory += b"\x00" * extend_memory.expand_by
240
    value = buffer_read(evm.message.data, data_start_index, size)
241
    memory_write(evm.memory, memory_start_index, value)
242
243
    # PROGRAM COUNTER
244
    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:
248
    """
249
    Push the size of code running in current environment onto the stack.
250
251
    Parameters
252
    ----------
253
    evm :
254
        The current EVM frame.
255
256
    """
257
    # STACK
258
    pass
259
260
    # GAS
261
    charge_gas(evm, GAS_BASE)
262
263
    # OPERATION
264
    push(evm.stack, U256(len(evm.code)))
265
266
    # PROGRAM COUNTER
267
    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:
271
    """
272
    Copy a portion of the code in current environment to memory.
273
274
    This will also expand the memory, in case that the memory is insufficient
275
    to store the data.
276
277
    Parameters
278
    ----------
279
    evm :
280
        The current EVM frame.
281
282
    """
283
    # STACK
284
    memory_start_index = pop(evm.stack)
285
    code_start_index = pop(evm.stack)
286
    size = pop(evm.stack)
287
288
    # GAS
289
    words = ceil32(Uint(size)) // Uint(32)
290
    copy_gas_cost = GAS_COPY * words
291
    extend_memory = calculate_gas_extend_memory(
292
        evm.memory, [(memory_start_index, size)]
293
    )
294
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
295
296
    # OPERATION
297
    evm.memory += b"\x00" * extend_memory.expand_by
298
    value = buffer_read(evm.code, code_start_index, size)
299
    memory_write(evm.memory, memory_start_index, value)
300
301
    # PROGRAM COUNTER
302
    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:
306
    """
307
    Push the gas price used in current environment onto the stack.
308
309
    Parameters
310
    ----------
311
    evm :
312
        The current EVM frame.
313
314
    """
315
    # STACK
316
    pass
317
318
    # GAS
319
    charge_gas(evm, GAS_BASE)
320
321
    # OPERATION
322
    push(evm.stack, U256(evm.message.tx_env.gas_price))
323
324
    # PROGRAM COUNTER
325
    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:
329
    """
330
    Push the code size of a given account onto the stack.
331
332
    Parameters
333
    ----------
334
    evm :
335
        The current EVM frame.
336
337
    """
338
    # STACK
339
    address = to_address(pop(evm.stack))
340
341
    # GAS
342
    if address in evm.accessed_addresses:
343
        access_gas_cost = GAS_WARM_ACCESS
344
    else:
345
        evm.accessed_addresses.add(address)
346
        access_gas_cost = GAS_COLD_ACCOUNT_ACCESS
347
348
    charge_gas(evm, access_gas_cost)
349
350
    # OPERATION
351
    code = get_account(evm.message.block_env.state, address).code
352
353
    codesize = U256(len(code))
354
    push(evm.stack, codesize)
355
356
    # PROGRAM COUNTER
357
    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:
361
    """
362
    Copy a portion of an account's code to memory.
363
364
    Parameters
365
    ----------
366
    evm :
367
        The current EVM frame.
368
369
    """
370
    # STACK
371
    address = to_address(pop(evm.stack))
372
    memory_start_index = pop(evm.stack)
373
    code_start_index = pop(evm.stack)
374
    size = pop(evm.stack)
375
376
    # GAS
377
    words = ceil32(Uint(size)) // Uint(32)
378
    copy_gas_cost = GAS_COPY * words
379
    extend_memory = calculate_gas_extend_memory(
380
        evm.memory, [(memory_start_index, size)]
381
    )
382
383
    if address in evm.accessed_addresses:
384
        access_gas_cost = GAS_WARM_ACCESS
385
    else:
386
        evm.accessed_addresses.add(address)
387
        access_gas_cost = GAS_COLD_ACCOUNT_ACCESS
388
389
    charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost)
390
391
    # OPERATION
392
    evm.memory += b"\x00" * extend_memory.expand_by
393
    code = get_account(evm.message.block_env.state, address).code
394
395
    value = buffer_read(code, code_start_index, size)
396
    memory_write(evm.memory, memory_start_index, value)
397
398
    # PROGRAM COUNTER
399
    evm.pc += Uint(1)

returndatasize

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

Parameters

evm : The current EVM frame.

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

returndatacopy

Copies data from the return data buffer code to memory

Parameters

evm : The current EVM frame.

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

extcodehash

Returns the keccak256 hash of a contract’s bytecode Parameters

evm : The current EVM frame.

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