ethereum.forks.byzantium.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:
32
    """
33
    Pushes the address of the current executing account to the stack.
34
35
    Parameters
36
    ----------
37
    evm :
38
        The current EVM frame.
39
40
    """
41
    # STACK
42
    pass
43
44
    # GAS
45
    charge_gas(evm, GasCosts.OPCODE_ADDRESS)
46
47
    # OPERATION
48
    push(evm.stack, U256.from_be_bytes(evm.message.current_target))
49
50
    # PROGRAM COUNTER
51
    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:
55
    """
56
    Pushes the balance of the given account onto the stack.
57
58
    Parameters
59
    ----------
60
    evm :
61
        The current EVM frame.
62
63
    """
64
    # STACK
65
    address = to_address_masked(pop(evm.stack))
66
67
    # GAS
68
    charge_gas(evm, GasCosts.OPCODE_BALANCE)
69
70
    # OPERATION
71
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
72
    balance = get_account(evm.message.block_env.state, address).balance
73
74
    push(evm.stack, balance)
75
76
    # PROGRAM COUNTER
77
    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:
81
    """
82
    Pushes the address of the original transaction sender to the stack.
83
    The origin address can only be an EOA.
84
85
    Parameters
86
    ----------
87
    evm :
88
        The current EVM frame.
89
90
    """
91
    # STACK
92
    pass
93
94
    # GAS
95
    charge_gas(evm, GasCosts.OPCODE_ORIGIN)
96
97
    # OPERATION
98
    push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin))
99
100
    # PROGRAM COUNTER
101
    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:
105
    """
106
    Pushes the address of the caller onto the stack.
107
108
    Parameters
109
    ----------
110
    evm :
111
        The current EVM frame.
112
113
    """
114
    # STACK
115
    pass
116
117
    # GAS
118
    charge_gas(evm, GasCosts.OPCODE_CALLER)
119
120
    # OPERATION
121
    push(evm.stack, U256.from_be_bytes(evm.message.caller))
122
123
    # PROGRAM COUNTER
124
    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:
128
    """
129
    Push the value (in wei) sent with the call onto the stack.
130
131
    Parameters
132
    ----------
133
    evm :
134
        The current EVM frame.
135
136
    """
137
    # STACK
138
    pass
139
140
    # GAS
141
    charge_gas(evm, GasCosts.OPCODE_CALLVALUE)
142
143
    # OPERATION
144
    push(evm.stack, evm.message.value)
145
146
    # PROGRAM COUNTER
147
    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:
151
    """
152
    Push a word (32 bytes) of the input data belonging to the current
153
    environment onto the stack.
154
155
    Parameters
156
    ----------
157
    evm :
158
        The current EVM frame.
159
160
    """
161
    # STACK
162
    start_index = pop(evm.stack)
163
164
    # GAS
165
    charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD)
166
167
    # OPERATION
168
    value = buffer_read(evm.message.data, start_index, U256(32))
169
170
    push(evm.stack, U256.from_be_bytes(value))
171
172
    # PROGRAM COUNTER
173
    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:
177
    """
178
    Push the size of input data in current environment onto the stack.
179
180
    Parameters
181
    ----------
182
    evm :
183
        The current EVM frame.
184
185
    """
186
    # STACK
187
    pass
188
189
    # GAS
190
    charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE)
191
192
    # OPERATION
193
    push(evm.stack, U256(len(evm.message.data)))
194
195
    # PROGRAM COUNTER
196
    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:
200
    """
201
    Copy a portion of the input data in current environment to memory.
202
203
    This will also expand the memory, in case that the memory is insufficient
204
    to store the data.
205
206
    Parameters
207
    ----------
208
    evm :
209
        The current EVM frame.
210
211
    """
212
    # STACK
213
    memory_start_index = pop(evm.stack)
214
    data_start_index = pop(evm.stack)
215
    size = pop(evm.stack)
216
217
    # GAS
218
    words = ceil32(Uint(size)) // Uint(32)
219
    copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words
220
    extend_memory = calculate_gas_extend_memory(
221
        evm.memory, [(memory_start_index, size)]
222
    )
223
    charge_gas(
224
        evm,
225
        GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost,
226
    )
227
228
    # OPERATION
229
    evm.memory += b"\x00" * extend_memory.expand_by
230
    value = buffer_read(evm.message.data, data_start_index, size)
231
    memory_write(evm.memory, memory_start_index, value)
232
233
    # PROGRAM COUNTER
234
    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:
238
    """
239
    Push the size of code running in current environment onto the stack.
240
241
    Parameters
242
    ----------
243
    evm :
244
        The current EVM frame.
245
246
    """
247
    # STACK
248
    pass
249
250
    # GAS
251
    charge_gas(evm, GasCosts.OPCODE_CODESIZE)
252
253
    # OPERATION
254
    push(evm.stack, U256(len(evm.code)))
255
256
    # PROGRAM COUNTER
257
    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:
261
    """
262
    Copy a portion of the code in current environment to memory.
263
264
    This will also expand the memory, in case that the memory is insufficient
265
    to store the data.
266
267
    Parameters
268
    ----------
269
    evm :
270
        The current EVM frame.
271
272
    """
273
    # STACK
274
    memory_start_index = pop(evm.stack)
275
    code_start_index = pop(evm.stack)
276
    size = pop(evm.stack)
277
278
    # GAS
279
    words = ceil32(Uint(size)) // Uint(32)
280
    copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words
281
    extend_memory = calculate_gas_extend_memory(
282
        evm.memory, [(memory_start_index, size)]
283
    )
284
    charge_gas(
285
        evm,
286
        GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost,
287
    )
288
289
    # OPERATION
290
    evm.memory += b"\x00" * extend_memory.expand_by
291
    value = buffer_read(evm.code, code_start_index, size)
292
    memory_write(evm.memory, memory_start_index, value)
293
294
    # PROGRAM COUNTER
295
    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:
299
    """
300
    Push the gas price used in current environment onto the stack.
301
302
    Parameters
303
    ----------
304
    evm :
305
        The current EVM frame.
306
307
    """
308
    # STACK
309
    pass
310
311
    # GAS
312
    charge_gas(evm, GasCosts.OPCODE_GASPRICE)
313
314
    # OPERATION
315
    push(evm.stack, U256(evm.message.tx_env.gas_price))
316
317
    # PROGRAM COUNTER
318
    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:
322
    """
323
    Push the code size of a given account onto the stack.
324
325
    Parameters
326
    ----------
327
    evm :
328
        The current EVM frame.
329
330
    """
331
    # STACK
332
    address = to_address_masked(pop(evm.stack))
333
334
    # GAS
335
    charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE)
336
337
    # OPERATION
338
    account = get_account(evm.message.block_env.state, address)
339
    code = get_code(evm.message.block_env.state, account.code_hash)
340
341
    codesize = U256(len(code))
342
    push(evm.stack, codesize)
343
344
    # PROGRAM COUNTER
345
    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:
349
    """
350
    Copy a portion of an account's code to memory.
351
352
    Parameters
353
    ----------
354
    evm :
355
        The current EVM frame.
356
357
    """
358
    # STACK
359
    address = to_address_masked(pop(evm.stack))
360
    memory_start_index = pop(evm.stack)
361
    code_start_index = pop(evm.stack)
362
    size = pop(evm.stack)
363
364
    # GAS
365
    words = ceil32(Uint(size)) // Uint(32)
366
    copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words
367
    extend_memory = calculate_gas_extend_memory(
368
        evm.memory, [(memory_start_index, size)]
369
    )
370
    charge_gas(
371
        evm,
372
        GasCosts.OPCODE_EXTERNAL_BASE + copy_gas_cost + extend_memory.cost,
373
    )
374
375
    # OPERATION
376
    evm.memory += b"\x00" * extend_memory.expand_by
377
    account = get_account(evm.message.block_env.state, address)
378
    code = get_code(evm.message.block_env.state, account.code_hash)
379
380
    value = buffer_read(code, code_start_index, size)
381
    memory_write(evm.memory, memory_start_index, value)
382
383
    # PROGRAM COUNTER
384
    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:
388
    """
389
    Pushes the size of the return data buffer onto the stack.
390
391
    Parameters
392
    ----------
393
    evm :
394
        The current EVM frame.
395
396
    """
397
    # STACK
398
    pass
399
400
    # GAS
401
    charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE)
402
403
    # OPERATION
404
    push(evm.stack, U256(len(evm.return_data)))
405
406
    # PROGRAM COUNTER
407
    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:
411
    """
412
    Copies data from the return data buffer to memory.
413
414
    Parameters
415
    ----------
416
    evm :
417
        The current EVM frame.
418
419
    """
420
    # STACK
421
    memory_start_index = pop(evm.stack)
422
    return_data_start_position = pop(evm.stack)
423
    size = pop(evm.stack)
424
425
    # GAS
426
    words = ceil32(Uint(size)) // Uint(32)
427
    copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words
428
    extend_memory = calculate_gas_extend_memory(
429
        evm.memory, [(memory_start_index, size)]
430
    )
431
    charge_gas(
432
        evm,
433
        GasCosts.OPCODE_RETURNDATACOPY_BASE
434
        + copy_gas_cost
435
        + extend_memory.cost,
436
    )
437
    if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data):
438
        raise OutOfBoundsRead
439
440
    evm.memory += b"\x00" * extend_memory.expand_by
441
    value = evm.return_data[
442
        return_data_start_position : return_data_start_position + size
443
    ]
444
    memory_write(evm.memory, memory_start_index, value)
445
446
    # PROGRAM COUNTER
447
    evm.pc += Uint(1)