ethereum.forks.istanbul.vm.instructions.environmentethereum.forks.muir_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:
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 += Uint(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_masked(pop(evm.stack))
74
75
    # GAS
76
    charge_gas(evm, GAS_BALANCE)
77
78
    # OPERATION
79
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
80
    balance = get_account(evm.message.block_env.state, address).balance
81
82
    push(evm.stack, balance)
83
84
    # PROGRAM COUNTER
85
    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:
89
    """
90
    Pushes the address of the original transaction sender to the stack.
91
    The origin address can only be an EOA.
92
93
    Parameters
94
    ----------
95
    evm :
96
        The current EVM frame.
97
98
    """
99
    # STACK
100
    pass
101
102
    # GAS
103
    charge_gas(evm, GAS_BASE)
104
105
    # OPERATION
106
    push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin))
107
108
    # PROGRAM COUNTER
109
    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:
113
    """
114
    Pushes the address of the caller onto the stack.
115
116
    Parameters
117
    ----------
118
    evm :
119
        The current EVM frame.
120
121
    """
122
    # STACK
123
    pass
124
125
    # GAS
126
    charge_gas(evm, GAS_BASE)
127
128
    # OPERATION
129
    push(evm.stack, U256.from_be_bytes(evm.message.caller))
130
131
    # PROGRAM COUNTER
132
    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:
136
    """
137
    Push the value (in wei) sent with the call onto the stack.
138
139
    Parameters
140
    ----------
141
    evm :
142
        The current EVM frame.
143
144
    """
145
    # STACK
146
    pass
147
148
    # GAS
149
    charge_gas(evm, GAS_BASE)
150
151
    # OPERATION
152
    push(evm.stack, evm.message.value)
153
154
    # PROGRAM COUNTER
155
    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:
159
    """
160
    Push a word (32 bytes) of the input data belonging to the current
161
    environment onto the stack.
162
163
    Parameters
164
    ----------
165
    evm :
166
        The current EVM frame.
167
168
    """
169
    # STACK
170
    start_index = pop(evm.stack)
171
172
    # GAS
173
    charge_gas(evm, GAS_VERY_LOW)
174
175
    # OPERATION
176
    value = buffer_read(evm.message.data, start_index, U256(32))
177
178
    push(evm.stack, U256.from_be_bytes(value))
179
180
    # PROGRAM COUNTER
181
    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:
185
    """
186
    Push the size of input data in current environment onto the stack.
187
188
    Parameters
189
    ----------
190
    evm :
191
        The current EVM frame.
192
193
    """
194
    # STACK
195
    pass
196
197
    # GAS
198
    charge_gas(evm, GAS_BASE)
199
200
    # OPERATION
201
    push(evm.stack, U256(len(evm.message.data)))
202
203
    # PROGRAM COUNTER
204
    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:
208
    """
209
    Copy a portion of the input data in current environment to memory.
210
211
    This will also expand the memory, in case that the memory is insufficient
212
    to store the data.
213
214
    Parameters
215
    ----------
216
    evm :
217
        The current EVM frame.
218
219
    """
220
    # STACK
221
    memory_start_index = pop(evm.stack)
222
    data_start_index = pop(evm.stack)
223
    size = pop(evm.stack)
224
225
    # GAS
226
    words = ceil32(Uint(size)) // Uint(32)
227
    copy_gas_cost = GAS_COPY * words
228
    extend_memory = calculate_gas_extend_memory(
229
        evm.memory, [(memory_start_index, size)]
230
    )
231
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
232
233
    # OPERATION
234
    evm.memory += b"\x00" * extend_memory.expand_by
235
    value = buffer_read(evm.message.data, data_start_index, size)
236
    memory_write(evm.memory, memory_start_index, value)
237
238
    # PROGRAM COUNTER
239
    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:
243
    """
244
    Push the size of code running in current environment onto the stack.
245
246
    Parameters
247
    ----------
248
    evm :
249
        The current EVM frame.
250
251
    """
252
    # STACK
253
    pass
254
255
    # GAS
256
    charge_gas(evm, GAS_BASE)
257
258
    # OPERATION
259
    push(evm.stack, U256(len(evm.code)))
260
261
    # PROGRAM COUNTER
262
    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:
266
    """
267
    Copy a portion of the code in current environment to memory.
268
269
    This will also expand the memory, in case that the memory is insufficient
270
    to store the data.
271
272
    Parameters
273
    ----------
274
    evm :
275
        The current EVM frame.
276
277
    """
278
    # STACK
279
    memory_start_index = pop(evm.stack)
280
    code_start_index = pop(evm.stack)
281
    size = pop(evm.stack)
282
283
    # GAS
284
    words = ceil32(Uint(size)) // Uint(32)
285
    copy_gas_cost = GAS_COPY * words
286
    extend_memory = calculate_gas_extend_memory(
287
        evm.memory, [(memory_start_index, size)]
288
    )
289
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
290
291
    # OPERATION
292
    evm.memory += b"\x00" * extend_memory.expand_by
293
    value = buffer_read(evm.code, code_start_index, size)
294
    memory_write(evm.memory, memory_start_index, value)
295
296
    # PROGRAM COUNTER
297
    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:
301
    """
302
    Push the gas price used in current environment onto the stack.
303
304
    Parameters
305
    ----------
306
    evm :
307
        The current EVM frame.
308
309
    """
310
    # STACK
311
    pass
312
313
    # GAS
314
    charge_gas(evm, GAS_BASE)
315
316
    # OPERATION
317
    push(evm.stack, U256(evm.message.tx_env.gas_price))
318
319
    # PROGRAM COUNTER
320
    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:
324
    """
325
    Push the code size of a given account onto the stack.
326
327
    Parameters
328
    ----------
329
    evm :
330
        The current EVM frame.
331
332
    """
333
    # STACK
334
    address = to_address_masked(pop(evm.stack))
335
336
    # GAS
337
    charge_gas(evm, GAS_EXTERNAL)
338
339
    # OPERATION
340
    account = get_account(evm.message.block_env.state, address)
341
    code = get_code(evm.message.block_env.state, account.code_hash)
342
343
    codesize = U256(len(code))
344
    push(evm.stack, codesize)
345
346
    # PROGRAM COUNTER
347
    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:
351
    """
352
    Copy a portion of an account's code to memory.
353
354
    Parameters
355
    ----------
356
    evm :
357
        The current EVM frame.
358
359
    """
360
    # STACK
361
    address = to_address_masked(pop(evm.stack))
362
    memory_start_index = pop(evm.stack)
363
    code_start_index = pop(evm.stack)
364
    size = pop(evm.stack)
365
366
    # GAS
367
    words = ceil32(Uint(size)) // Uint(32)
368
    copy_gas_cost = GAS_COPY * words
369
    extend_memory = calculate_gas_extend_memory(
370
        evm.memory, [(memory_start_index, size)]
371
    )
372
    charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost)
373
374
    # OPERATION
375
    evm.memory += b"\x00" * extend_memory.expand_by
376
    account = get_account(evm.message.block_env.state, address)
377
    code = get_code(evm.message.block_env.state, account.code_hash)
378
379
    value = buffer_read(code, code_start_index, size)
380
    memory_write(evm.memory, memory_start_index, value)
381
382
    # PROGRAM COUNTER
383
    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:
387
    """
388
    Pushes the size of the return data buffer onto the stack.
389
390
    Parameters
391
    ----------
392
    evm :
393
        The current EVM frame.
394
395
    """
396
    # STACK
397
    pass
398
399
    # GAS
400
    charge_gas(evm, GAS_BASE)
401
402
    # OPERATION
403
    push(evm.stack, U256(len(evm.return_data)))
404
405
    # PROGRAM COUNTER
406
    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:
410
    """
411
    Copies data from the return data buffer to memory.
412
413
    Parameters
414
    ----------
415
    evm :
416
        The current EVM frame.
417
418
    """
419
    # STACK
420
    memory_start_index = pop(evm.stack)
421
    return_data_start_position = pop(evm.stack)
422
    size = pop(evm.stack)
423
424
    # GAS
425
    words = ceil32(Uint(size)) // Uint(32)
426
    copy_gas_cost = GAS_RETURN_DATA_COPY * words
427
    extend_memory = calculate_gas_extend_memory(
428
        evm.memory, [(memory_start_index, size)]
429
    )
430
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
431
    if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data):
432
        raise OutOfBoundsRead
433
434
    evm.memory += b"\x00" * extend_memory.expand_by
435
    value = evm.return_data[
436
        return_data_start_position : return_data_start_position + size
437
    ]
438
    memory_write(evm.memory, memory_start_index, value)
439
440
    # PROGRAM COUNTER
441
    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:
445
    """
446
    Returns the keccak256 hash of a contract’s bytecode.
447
448
    Parameters
449
    ----------
450
    evm :
451
        The current EVM frame.
452
453
    """
454
    # STACK
455
    address = to_address_masked(pop(evm.stack))
456
457
    # GAS
458
    charge_gas(evm, GAS_CODE_HASH)
459
460
    # OPERATION
461
    account = get_account(evm.message.block_env.state, address)
462
463
    if account == EMPTY_ACCOUNT:
464
        codehash = U256(0)
465
    else:
466
        codehash = U256.from_be_bytes(account.code_hash)
467
468
    push(evm.stack, codehash)
469
470
    # PROGRAM COUNTER
471
    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:
475
    """
476
    Pushes the balance of the current address to the stack.
477
478
    Parameters
479
    ----------
480
    evm :
481
        The current EVM frame.
482
483
    """
484
    # STACK
485
    pass
486
487
    # GAS
488
    charge_gas(evm, GAS_FAST_STEP)
489
490
    # OPERATION
491
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
492
    balance = get_account(
493
        evm.message.block_env.state, evm.message.current_target
494
    ).balance
495
496
    push(evm.stack, balance)
497
498
    # PROGRAM COUNTER
499
    evm.pc += Uint(1)