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
    tx_state = evm.message.tx_env.state
73
    balance = get_account(tx_state, address).balance
74
75
    push(evm.stack, balance)
76
77
    # PROGRAM COUNTER
78
    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:
82
    """
83
    Pushes the address of the original transaction sender to the stack.
84
    The origin address can only be an EOA.
85
86
    Parameters
87
    ----------
88
    evm :
89
        The current EVM frame.
90
91
    """
92
    # STACK
93
    pass
94
95
    # GAS
96
    charge_gas(evm, GasCosts.OPCODE_ORIGIN)
97
98
    # OPERATION
99
    push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin))
100
101
    # PROGRAM COUNTER
102
    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:
106
    """
107
    Pushes the address of the caller onto the stack.
108
109
    Parameters
110
    ----------
111
    evm :
112
        The current EVM frame.
113
114
    """
115
    # STACK
116
    pass
117
118
    # GAS
119
    charge_gas(evm, GasCosts.OPCODE_CALLER)
120
121
    # OPERATION
122
    push(evm.stack, U256.from_be_bytes(evm.message.caller))
123
124
    # PROGRAM COUNTER
125
    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:
129
    """
130
    Push the value (in wei) sent with the call onto the stack.
131
132
    Parameters
133
    ----------
134
    evm :
135
        The current EVM frame.
136
137
    """
138
    # STACK
139
    pass
140
141
    # GAS
142
    charge_gas(evm, GasCosts.OPCODE_CALLVALUE)
143
144
    # OPERATION
145
    push(evm.stack, evm.message.value)
146
147
    # PROGRAM COUNTER
148
    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:
152
    """
153
    Push a word (32 bytes) of the input data belonging to the current
154
    environment onto the stack.
155
156
    Parameters
157
    ----------
158
    evm :
159
        The current EVM frame.
160
161
    """
162
    # STACK
163
    start_index = pop(evm.stack)
164
165
    # GAS
166
    charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD)
167
168
    # OPERATION
169
    value = buffer_read(evm.message.data, start_index, U256(32))
170
171
    push(evm.stack, U256.from_be_bytes(value))
172
173
    # PROGRAM COUNTER
174
    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:
178
    """
179
    Push the size of input data in current environment onto the stack.
180
181
    Parameters
182
    ----------
183
    evm :
184
        The current EVM frame.
185
186
    """
187
    # STACK
188
    pass
189
190
    # GAS
191
    charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE)
192
193
    # OPERATION
194
    push(evm.stack, U256(len(evm.message.data)))
195
196
    # PROGRAM COUNTER
197
    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:
201
    """
202
    Copy a portion of the input data in current environment to memory.
203
204
    This will also expand the memory, in case that the memory is insufficient
205
    to store the data.
206
207
    Parameters
208
    ----------
209
    evm :
210
        The current EVM frame.
211
212
    """
213
    # STACK
214
    memory_start_index = pop(evm.stack)
215
    data_start_index = pop(evm.stack)
216
    size = pop(evm.stack)
217
218
    # GAS
219
    words = ceil32(Uint(size)) // Uint(32)
220
    copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words
221
    extend_memory = calculate_gas_extend_memory(
222
        evm.memory, [(memory_start_index, size)]
223
    )
224
    charge_gas(
225
        evm,
226
        GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost,
227
    )
228
229
    # OPERATION
230
    evm.memory += b"\x00" * extend_memory.expand_by
231
    value = buffer_read(evm.message.data, data_start_index, size)
232
    memory_write(evm.memory, memory_start_index, value)
233
234
    # PROGRAM COUNTER
235
    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:
239
    """
240
    Push the size of code running in current environment onto the stack.
241
242
    Parameters
243
    ----------
244
    evm :
245
        The current EVM frame.
246
247
    """
248
    # STACK
249
    pass
250
251
    # GAS
252
    charge_gas(evm, GasCosts.OPCODE_CODESIZE)
253
254
    # OPERATION
255
    push(evm.stack, U256(len(evm.code)))
256
257
    # PROGRAM COUNTER
258
    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:
262
    """
263
    Copy a portion of the code in current environment to memory.
264
265
    This will also expand the memory, in case that the memory is insufficient
266
    to store the data.
267
268
    Parameters
269
    ----------
270
    evm :
271
        The current EVM frame.
272
273
    """
274
    # STACK
275
    memory_start_index = pop(evm.stack)
276
    code_start_index = pop(evm.stack)
277
    size = pop(evm.stack)
278
279
    # GAS
280
    words = ceil32(Uint(size)) // Uint(32)
281
    copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words
282
    extend_memory = calculate_gas_extend_memory(
283
        evm.memory, [(memory_start_index, size)]
284
    )
285
    charge_gas(
286
        evm,
287
        GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost,
288
    )
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, GasCosts.OPCODE_GASPRICE)
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, GasCosts.OPCODE_EXTERNAL_BASE)
337
338
    # OPERATION
339
    tx_state = evm.message.tx_env.state
340
    account = get_account(tx_state, address)
341
    code = get_code(tx_state, account.code_hash)
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_masked(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 = GasCosts.OPCODE_COPY_PER_WORD * words
369
    extend_memory = calculate_gas_extend_memory(
370
        evm.memory, [(memory_start_index, size)]
371
    )
372
    charge_gas(
373
        evm,
374
        GasCosts.OPCODE_EXTERNAL_BASE + copy_gas_cost + extend_memory.cost,
375
    )
376
377
    # OPERATION
378
    evm.memory += b"\x00" * extend_memory.expand_by
379
    tx_state = evm.message.tx_env.state
380
    account = get_account(tx_state, address)
381
    code = get_code(tx_state, account.code_hash)
382
383
    value = buffer_read(code, code_start_index, size)
384
    memory_write(evm.memory, memory_start_index, value)
385
386
    # PROGRAM COUNTER
387
    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:
391
    """
392
    Pushes the size of the return data buffer onto the stack.
393
394
    Parameters
395
    ----------
396
    evm :
397
        The current EVM frame.
398
399
    """
400
    # STACK
401
    pass
402
403
    # GAS
404
    charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE)
405
406
    # OPERATION
407
    push(evm.stack, U256(len(evm.return_data)))
408
409
    # PROGRAM COUNTER
410
    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:
414
    """
415
    Copies data from the return data buffer to memory.
416
417
    Parameters
418
    ----------
419
    evm :
420
        The current EVM frame.
421
422
    """
423
    # STACK
424
    memory_start_index = pop(evm.stack)
425
    return_data_start_position = pop(evm.stack)
426
    size = pop(evm.stack)
427
428
    # GAS
429
    words = ceil32(Uint(size)) // Uint(32)
430
    copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words
431
    extend_memory = calculate_gas_extend_memory(
432
        evm.memory, [(memory_start_index, size)]
433
    )
434
    charge_gas(
435
        evm,
436
        GasCosts.OPCODE_RETURNDATACOPY_BASE
437
        + copy_gas_cost
438
        + extend_memory.cost,
439
    )
440
    if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data):
441
        raise OutOfBoundsRead
442
443
    evm.memory += b"\x00" * extend_memory.expand_by
444
    value = evm.return_data[
445
        return_data_start_position : return_data_start_position + size
446
    ]
447
    memory_write(evm.memory, memory_start_index, value)
448
449
    # PROGRAM COUNTER
450
    evm.pc += Uint(1)