ethereum.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:
41
    """
42
    Pushes the address of the current executing account to the stack.
43
44
    Parameters
45
    ----------
46
    evm :
47
        The current EVM frame.
48
49
    """
50
    # STACK
51
    pass
52
53
    # GAS
54
    charge_gas(evm, GAS_BASE)
55
56
    # OPERATION
57
    push(evm.stack, U256.from_be_bytes(evm.message.current_target))
58
59
    # PROGRAM COUNTER
60
    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:
64
    """
65
    Pushes the balance of the given account onto the stack.
66
67
    Parameters
68
    ----------
69
    evm :
70
        The current EVM frame.
71
72
    """
73
    # STACK
74
    address = to_address(pop(evm.stack))
75
76
    # GAS
77
    charge_gas(evm, GAS_BALANCE)
78
79
    # OPERATION
80
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
81
    balance = get_account(evm.message.block_env.state, address).balance
82
83
    push(evm.stack, balance)
84
85
    # PROGRAM COUNTER
86
    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:
90
    """
91
    Pushes the address of the original transaction sender to the stack.
92
    The origin address can only be an EOA.
93
94
    Parameters
95
    ----------
96
    evm :
97
        The current EVM frame.
98
99
    """
100
    # STACK
101
    pass
102
103
    # GAS
104
    charge_gas(evm, GAS_BASE)
105
106
    # OPERATION
107
    push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin))
108
109
    # PROGRAM COUNTER
110
    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:
114
    """
115
    Pushes the address of the caller onto the stack.
116
117
    Parameters
118
    ----------
119
    evm :
120
        The current EVM frame.
121
122
    """
123
    # STACK
124
    pass
125
126
    # GAS
127
    charge_gas(evm, GAS_BASE)
128
129
    # OPERATION
130
    push(evm.stack, U256.from_be_bytes(evm.message.caller))
131
132
    # PROGRAM COUNTER
133
    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:
137
    """
138
    Push the value (in wei) sent with the call onto the stack.
139
140
    Parameters
141
    ----------
142
    evm :
143
        The current EVM frame.
144
145
    """
146
    # STACK
147
    pass
148
149
    # GAS
150
    charge_gas(evm, GAS_BASE)
151
152
    # OPERATION
153
    push(evm.stack, evm.message.value)
154
155
    # PROGRAM COUNTER
156
    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:
160
    """
161
    Push a word (32 bytes) of the input data belonging to the current
162
    environment onto the stack.
163
164
    Parameters
165
    ----------
166
    evm :
167
        The current EVM frame.
168
169
    """
170
    # STACK
171
    start_index = pop(evm.stack)
172
173
    # GAS
174
    charge_gas(evm, GAS_VERY_LOW)
175
176
    # OPERATION
177
    value = buffer_read(evm.message.data, start_index, U256(32))
178
179
    push(evm.stack, U256.from_be_bytes(value))
180
181
    # PROGRAM COUNTER
182
    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:
186
    """
187
    Push the size of input data in current environment onto the stack.
188
189
    Parameters
190
    ----------
191
    evm :
192
        The current EVM frame.
193
194
    """
195
    # STACK
196
    pass
197
198
    # GAS
199
    charge_gas(evm, GAS_BASE)
200
201
    # OPERATION
202
    push(evm.stack, U256(len(evm.message.data)))
203
204
    # PROGRAM COUNTER
205
    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:
209
    """
210
    Copy a portion of the input data in current environment to memory.
211
212
    This will also expand the memory, in case that the memory is insufficient
213
    to store the data.
214
215
    Parameters
216
    ----------
217
    evm :
218
        The current EVM frame.
219
220
    """
221
    # STACK
222
    memory_start_index = pop(evm.stack)
223
    data_start_index = pop(evm.stack)
224
    size = pop(evm.stack)
225
226
    # GAS
227
    words = ceil32(Uint(size)) // Uint(32)
228
    copy_gas_cost = GAS_COPY * words
229
    extend_memory = calculate_gas_extend_memory(
230
        evm.memory, [(memory_start_index, size)]
231
    )
232
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
233
234
    # OPERATION
235
    evm.memory += b"\x00" * extend_memory.expand_by
236
    value = buffer_read(evm.message.data, data_start_index, size)
237
    memory_write(evm.memory, memory_start_index, value)
238
239
    # PROGRAM COUNTER
240
    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:
244
    """
245
    Push the size of code running in current environment onto the stack.
246
247
    Parameters
248
    ----------
249
    evm :
250
        The current EVM frame.
251
252
    """
253
    # STACK
254
    pass
255
256
    # GAS
257
    charge_gas(evm, GAS_BASE)
258
259
    # OPERATION
260
    push(evm.stack, U256(len(evm.code)))
261
262
    # PROGRAM COUNTER
263
    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:
267
    """
268
    Copy a portion of the code in current environment to memory.
269
270
    This will also expand the memory, in case that the memory is insufficient
271
    to store the data.
272
273
    Parameters
274
    ----------
275
    evm :
276
        The current EVM frame.
277
278
    """
279
    # STACK
280
    memory_start_index = pop(evm.stack)
281
    code_start_index = pop(evm.stack)
282
    size = pop(evm.stack)
283
284
    # GAS
285
    words = ceil32(Uint(size)) // Uint(32)
286
    copy_gas_cost = GAS_COPY * words
287
    extend_memory = calculate_gas_extend_memory(
288
        evm.memory, [(memory_start_index, size)]
289
    )
290
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
291
292
    # OPERATION
293
    evm.memory += b"\x00" * extend_memory.expand_by
294
    value = buffer_read(evm.code, code_start_index, size)
295
    memory_write(evm.memory, memory_start_index, value)
296
297
    # PROGRAM COUNTER
298
    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:
302
    """
303
    Push the gas price used in current environment onto the stack.
304
305
    Parameters
306
    ----------
307
    evm :
308
        The current EVM frame.
309
310
    """
311
    # STACK
312
    pass
313
314
    # GAS
315
    charge_gas(evm, GAS_BASE)
316
317
    # OPERATION
318
    push(evm.stack, U256(evm.message.tx_env.gas_price))
319
320
    # PROGRAM COUNTER
321
    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:
325
    """
326
    Push the code size of a given account onto the stack.
327
328
    Parameters
329
    ----------
330
    evm :
331
        The current EVM frame.
332
333
    """
334
    # STACK
335
    address = to_address(pop(evm.stack))
336
337
    # GAS
338
    charge_gas(evm, GAS_EXTERNAL)
339
340
    # OPERATION
341
    code = get_account(evm.message.block_env.state, address).code
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(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
    code = get_account(evm.message.block_env.state, address).code
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
    # 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.message.block_env.state, address)
457
458
    if account == EMPTY_ACCOUNT:
459
        codehash = U256(0)
460
    else:
461
        code = account.code
462
        codehash = U256.from_be_bytes(keccak256(code))
463
464
    push(evm.stack, codehash)
465
466
    # PROGRAM COUNTER
467
    evm.pc += Uint(1)