ethereum.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:
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
    code = get_account(evm.message.block_env.state, address).code
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
    code = get_account(evm.message.block_env.state, address).code
376
377
    value = buffer_read(code, code_start_index, size)
378
    memory_write(evm.memory, memory_start_index, value)
379
380
    # PROGRAM COUNTER
381
    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:
385
    """
386
    Pushes the size of the return data buffer onto the stack.
387
388
    Parameters
389
    ----------
390
    evm :
391
        The current EVM frame.
392
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
    """
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
446
    Parameters
447
    ----------
448
    evm :
449
        The current EVM frame.
450
451
    """
452
    # STACK
453
    address = to_address_masked(pop(evm.stack))
454
455
    # GAS
456
    charge_gas(evm, GAS_CODE_HASH)
457
458
    # OPERATION
459
    account = get_account(evm.message.block_env.state, address)
460
461
    if account == EMPTY_ACCOUNT:
462
        codehash = U256(0)
463
    else:
464
        code = account.code
465
        codehash = U256.from_be_bytes(keccak256(code))
466
467
    push(evm.stack, codehash)
468
469
    # PROGRAM COUNTER
470
    evm.pc += Uint(1)