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

returndatacopy

Copies data from the return data buffer to memory.

Parameters

evm : The current EVM frame.

def returndatacopy(evm: Evm) -> None:
426
    """
427
    Copies data from the return data buffer to memory.
428
429
    Parameters
430
    ----------
431
    evm :
432
        The current EVM frame.
433
434
    """
435
    # STACK
436
    memory_start_index = pop(evm.stack)
437
    return_data_start_position = pop(evm.stack)
438
    size = pop(evm.stack)
439
440
    # GAS
441
    words = ceil32(Uint(size)) // Uint(32)
442
    copy_gas_cost = GAS_RETURN_DATA_COPY * words
443
    extend_memory = calculate_gas_extend_memory(
444
        evm.memory, [(memory_start_index, size)]
445
    )
446
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
447
    if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data):
448
        raise OutOfBoundsRead
449
450
    evm.memory += b"\x00" * extend_memory.expand_by
451
    value = evm.return_data[
452
        return_data_start_position : return_data_start_position + size
453
    ]
454
    memory_write(evm.memory, memory_start_index, value)
455
456
    # PROGRAM COUNTER
457
    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:
461
    """
462
    Returns the keccak256 hash of a contract’s bytecode.
463
464
    Parameters
465
    ----------
466
    evm :
467
        The current EVM frame.
468
469
    """
470
    # STACK
471
    address = to_address_masked(pop(evm.stack))
472
473
    # GAS
474
    if address in evm.accessed_addresses:
475
        access_gas_cost = GAS_WARM_ACCESS
476
    else:
477
        evm.accessed_addresses.add(address)
478
        access_gas_cost = GAS_COLD_ACCOUNT_ACCESS
479
480
    charge_gas(evm, access_gas_cost)
481
482
    # OPERATION
483
    account = get_account(evm.message.block_env.state, address)
484
485
    if account == EMPTY_ACCOUNT:
486
        codehash = U256(0)
487
    else:
488
        codehash = U256.from_be_bytes(account.code_hash)
489
490
    push(evm.stack, codehash)
491
492
    # PROGRAM COUNTER
493
    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:
497
    """
498
    Pushes the balance of the current address to the stack.
499
500
    Parameters
501
    ----------
502
    evm :
503
        The current EVM frame.
504
505
    """
506
    # STACK
507
    pass
508
509
    # GAS
510
    charge_gas(evm, GAS_FAST_STEP)
511
512
    # OPERATION
513
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
514
    balance = get_account(
515
        evm.message.block_env.state, evm.message.current_target
516
    ).balance
517
518
    push(evm.stack, balance)
519
520
    # PROGRAM COUNTER
521
    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:
525
    """
526
    Pushes the base fee of the current block on to the stack.
527
528
    Parameters
529
    ----------
530
    evm :
531
        The current EVM frame.
532
533
    """
534
    # STACK
535
    pass
536
537
    # GAS
538
    charge_gas(evm, GAS_BASE)
539
540
    # OPERATION
541
    push(evm.stack, U256(evm.message.block_env.base_fee_per_gas))
542
543
    # PROGRAM COUNTER
544
    evm.pc += Uint(1)