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