ethereum.istanbul.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.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.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.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
    # Non-existent accounts default to EMPTY_ACCOUNT, which has empty code.
343
    codesize = U256(len(get_account(evm.env.state, address).code))
344
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.env.state, address).code
378
    value = buffer_read(code, code_start_index, size)
379
    memory_write(evm.memory, memory_start_index, value)
380
381
    # PROGRAM COUNTER
382
    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:
386
    """
387
    Pushes the size of the return data buffer onto the stack.
388
389
    Parameters
390
    ----------
391
    evm :
392
        The current EVM frame.
393
    """
394
    # STACK
395
    pass
396
397
    # GAS
398
    charge_gas(evm, GAS_BASE)
399
400
    # OPERATION
401
    push(evm.stack, U256(len(evm.return_data)))
402
403
    # PROGRAM COUNTER
404
    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:
408
    """
409
    Copies data from the return data buffer code to memory
410
411
    Parameters
412
    ----------
413
    evm :
414
        The current EVM frame.
415
    """
416
    # STACK
417
    memory_start_index = pop(evm.stack)
418
    return_data_start_position = pop(evm.stack)
419
    size = pop(evm.stack)
420
421
    # GAS
422
    words = ceil32(Uint(size)) // Uint(32)
423
    copy_gas_cost = GAS_RETURN_DATA_COPY * words
424
    extend_memory = calculate_gas_extend_memory(
425
        evm.memory, [(memory_start_index, size)]
426
    )
427
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
428
    if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data):
429
        raise OutOfBoundsRead
430
431
    evm.memory += b"\x00" * extend_memory.expand_by
432
    value = evm.return_data[
433
        return_data_start_position : return_data_start_position + size
434
    ]
435
    memory_write(evm.memory, memory_start_index, value)
436
437
    # PROGRAM COUNTER
438
    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:
442
    """
443
    Returns the keccak256 hash of a contract’s bytecode
444
    Parameters
445
    ----------
446
    evm :
447
        The current EVM frame.
448
    """
449
    # STACK
450
    address = to_address(pop(evm.stack))
451
452
    # GAS
453
    charge_gas(evm, GAS_CODE_HASH)
454
455
    # OPERATION
456
    account = get_account(evm.env.state, address)
457
458
    if account == EMPTY_ACCOUNT:
459
        codehash = U256(0)
460
    else:
461
        codehash = U256.from_be_bytes(keccak256(account.code))
462
463
    push(evm.stack, codehash)
464
465
    # PROGRAM COUNTER
466
    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:
470
    """
471
    Pushes the balance of the current address to the stack.
472
473
    Parameters
474
    ----------
475
    evm :
476
        The current EVM frame.
477
478
    """
479
    # STACK
480
    pass
481
482
    # GAS
483
    charge_gas(evm, GAS_FAST_STEP)
484
485
    # OPERATION
486
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
487
    balance = get_account(evm.env.state, evm.message.current_target).balance
488
489
    push(evm.stack, balance)
490
491
    # PROGRAM COUNTER
492
    evm.pc += Uint(1)