ethereum.forks.byzantium.vm.instructions.environmentethereum.forks.constantinople.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
    charge_gas(evm, GAS_BALANCE)
76
77
    # OPERATION
78
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
79
    balance = get_account(evm.message.block_env.state, address).balance
80
81
    push(evm.stack, balance)
82
83
    # PROGRAM COUNTER
84
    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:
88
    """
89
    Pushes the address of the original transaction sender to the stack.
90
    The origin address can only be an EOA.
91
92
    Parameters
93
    ----------
94
    evm :
95
        The current EVM frame.
96
97
    """
98
    # STACK
99
    pass
100
101
    # GAS
102
    charge_gas(evm, GAS_BASE)
103
104
    # OPERATION
105
    push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin))
106
107
    # PROGRAM COUNTER
108
    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:
112
    """
113
    Pushes the address of the caller onto the stack.
114
115
    Parameters
116
    ----------
117
    evm :
118
        The current EVM frame.
119
120
    """
121
    # STACK
122
    pass
123
124
    # GAS
125
    charge_gas(evm, GAS_BASE)
126
127
    # OPERATION
128
    push(evm.stack, U256.from_be_bytes(evm.message.caller))
129
130
    # PROGRAM COUNTER
131
    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:
135
    """
136
    Push the value (in wei) sent with the call onto the stack.
137
138
    Parameters
139
    ----------
140
    evm :
141
        The current EVM frame.
142
143
    """
144
    # STACK
145
    pass
146
147
    # GAS
148
    charge_gas(evm, GAS_BASE)
149
150
    # OPERATION
151
    push(evm.stack, evm.message.value)
152
153
    # PROGRAM COUNTER
154
    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:
158
    """
159
    Push a word (32 bytes) of the input data belonging to the current
160
    environment onto the stack.
161
162
    Parameters
163
    ----------
164
    evm :
165
        The current EVM frame.
166
167
    """
168
    # STACK
169
    start_index = pop(evm.stack)
170
171
    # GAS
172
    charge_gas(evm, GAS_VERY_LOW)
173
174
    # OPERATION
175
    value = buffer_read(evm.message.data, start_index, U256(32))
176
177
    push(evm.stack, U256.from_be_bytes(value))
178
179
    # PROGRAM COUNTER
180
    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:
184
    """
185
    Push the size of input data in current environment onto the stack.
186
187
    Parameters
188
    ----------
189
    evm :
190
        The current EVM frame.
191
192
    """
193
    # STACK
194
    pass
195
196
    # GAS
197
    charge_gas(evm, GAS_BASE)
198
199
    # OPERATION
200
    push(evm.stack, U256(len(evm.message.data)))
201
202
    # PROGRAM COUNTER
203
    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:
207
    """
208
    Copy a portion of the input data in current environment to memory.
209
210
    This will also expand the memory, in case that the memory is insufficient
211
    to store the data.
212
213
    Parameters
214
    ----------
215
    evm :
216
        The current EVM frame.
217
218
    """
219
    # STACK
220
    memory_start_index = pop(evm.stack)
221
    data_start_index = pop(evm.stack)
222
    size = pop(evm.stack)
223
224
    # GAS
225
    words = ceil32(Uint(size)) // Uint(32)
226
    copy_gas_cost = GAS_COPY * words
227
    extend_memory = calculate_gas_extend_memory(
228
        evm.memory, [(memory_start_index, size)]
229
    )
230
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
231
232
    # OPERATION
233
    evm.memory += b"\x00" * extend_memory.expand_by
234
    value = buffer_read(evm.message.data, data_start_index, size)
235
    memory_write(evm.memory, memory_start_index, value)
236
237
    # PROGRAM COUNTER
238
    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:
242
    """
243
    Push the size of code running in current environment onto the stack.
244
245
    Parameters
246
    ----------
247
    evm :
248
        The current EVM frame.
249
250
    """
251
    # STACK
252
    pass
253
254
    # GAS
255
    charge_gas(evm, GAS_BASE)
256
257
    # OPERATION
258
    push(evm.stack, U256(len(evm.code)))
259
260
    # PROGRAM COUNTER
261
    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:
265
    """
266
    Copy a portion of the code in current environment to memory.
267
268
    This will also expand the memory, in case that the memory is insufficient
269
    to store the data.
270
271
    Parameters
272
    ----------
273
    evm :
274
        The current EVM frame.
275
276
    """
277
    # STACK
278
    memory_start_index = pop(evm.stack)
279
    code_start_index = pop(evm.stack)
280
    size = pop(evm.stack)
281
282
    # GAS
283
    words = ceil32(Uint(size)) // Uint(32)
284
    copy_gas_cost = GAS_COPY * words
285
    extend_memory = calculate_gas_extend_memory(
286
        evm.memory, [(memory_start_index, size)]
287
    )
288
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
289
290
    # OPERATION
291
    evm.memory += b"\x00" * extend_memory.expand_by
292
    value = buffer_read(evm.code, code_start_index, size)
293
    memory_write(evm.memory, memory_start_index, value)
294
295
    # PROGRAM COUNTER
296
    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:
300
    """
301
    Push the gas price used in current environment onto the stack.
302
303
    Parameters
304
    ----------
305
    evm :
306
        The current EVM frame.
307
308
    """
309
    # STACK
310
    pass
311
312
    # GAS
313
    charge_gas(evm, GAS_BASE)
314
315
    # OPERATION
316
    push(evm.stack, U256(evm.message.tx_env.gas_price))
317
318
    # PROGRAM COUNTER
319
    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:
323
    """
324
    Push the code size of a given account onto the stack.
325
326
    Parameters
327
    ----------
328
    evm :
329
        The current EVM frame.
330
331
    """
332
    # STACK
333
    address = to_address_masked(pop(evm.stack))
334
335
    # GAS
336
    charge_gas(evm, GAS_EXTERNAL)
337
338
    # OPERATION
339
    account = get_account(evm.message.block_env.state, address)
340
    code = get_code(evm.message.block_env.state, account.code_hash)
341
342
    codesize = U256(len(code))
343
    push(evm.stack, codesize)
344
345
    # PROGRAM COUNTER
346
    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:
350
    """
351
    Copy a portion of an account's code to memory.
352
353
    Parameters
354
    ----------
355
    evm :
356
        The current EVM frame.
357
358
    """
359
    # STACK
360
    address = to_address_masked(pop(evm.stack))
361
    memory_start_index = pop(evm.stack)
362
    code_start_index = pop(evm.stack)
363
    size = pop(evm.stack)
364
365
    # GAS
366
    words = ceil32(Uint(size)) // Uint(32)
367
    copy_gas_cost = GAS_COPY * words
368
    extend_memory = calculate_gas_extend_memory(
369
        evm.memory, [(memory_start_index, size)]
370
    )
371
    charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost)
372
373
    # OPERATION
374
    evm.memory += b"\x00" * extend_memory.expand_by
375
    account = get_account(evm.message.block_env.state, address)
376
    code = get_code(evm.message.block_env.state, account.code_hash)
377
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
    """
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 to memory.

Parameters

evm : The current EVM frame.

def returndatacopy(evm: Evm) -> None:
409
    """
410
    Copies data from the return data buffer to memory.
411
412
    Parameters
413
    ----------
414
    evm :
415
        The current EVM frame.
416
417
    """
418
    # STACK
419
    memory_start_index = pop(evm.stack)
420
    return_data_start_position = pop(evm.stack)
421
    size = pop(evm.stack)
422
423
    # GAS
424
    words = ceil32(Uint(size)) // Uint(32)
425
    copy_gas_cost = GAS_RETURN_DATA_COPY * words
426
    extend_memory = calculate_gas_extend_memory(
427
        evm.memory, [(memory_start_index, size)]
428
    )
429
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
430
    if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data):
431
        raise OutOfBoundsRead
432
433
    evm.memory += b"\x00" * extend_memory.expand_by
434
    value = evm.return_data[
435
        return_data_start_position : return_data_start_position + size
436
    ]
437
    memory_write(evm.memory, memory_start_index, value)
438
439
    # PROGRAM COUNTER
440
    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:
444
    """
445
    Returns the keccak256 hash of a contract’s bytecode.
446
447
    Parameters
448
    ----------
449
    evm :
450
        The current EVM frame.
451
452
    """
453
    # STACK
454
    address = to_address_masked(pop(evm.stack))
455
456
    # GAS
457
    charge_gas(evm, GAS_CODE_HASH)
458
459
    # OPERATION
460
    account = get_account(evm.message.block_env.state, address)
461
462
    if account == EMPTY_ACCOUNT:
463
        codehash = U256(0)
464
    else:
465
        codehash = U256.from_be_bytes(account.code_hash)
466
467
    push(evm.stack, codehash)
468
469
    # PROGRAM COUNTER
470
    evm.pc += Uint(1)