ethereum.spurious_dragon.vm.instructions.environmentethereum.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:
38
    """
39
    Pushes the address of the current executing account to the stack.
40
41
    Parameters
42
    ----------
43
    evm :
44
        The current EVM frame.
45
46
    """
47
    # STACK
48
    pass
49
50
    # GAS
51
    charge_gas(evm, GAS_BASE)
52
53
    # OPERATION
54
    push(evm.stack, U256.from_be_bytes(evm.message.current_target))
55
56
    # PROGRAM COUNTER
57
    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:
61
    """
62
    Pushes the balance of the given account onto the stack.
63
64
    Parameters
65
    ----------
66
    evm :
67
        The current EVM frame.
68
69
    """
70
    # STACK
71
    address = to_address(pop(evm.stack))
72
73
    # GAS
74
    charge_gas(evm, GAS_BALANCE)
75
76
    # OPERATION
77
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
78
    balance = get_account(evm.env.state, address).balance
79
80
    push(evm.stack, balance)
81
82
    # PROGRAM COUNTER
83
    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:
87
    """
88
    Pushes the address of the original transaction sender to the stack.
89
    The origin address can only be an EOA.
90
91
    Parameters
92
    ----------
93
    evm :
94
        The current EVM frame.
95
96
    """
97
    # STACK
98
    pass
99
100
    # GAS
101
    charge_gas(evm, GAS_BASE)
102
103
    # OPERATION
104
    push(evm.stack, U256.from_be_bytes(evm.env.origin))
105
106
    # PROGRAM COUNTER
107
    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:
111
    """
112
    Pushes the address of the caller onto the stack.
113
114
    Parameters
115
    ----------
116
    evm :
117
        The current EVM frame.
118
119
    """
120
    # STACK
121
    pass
122
123
    # GAS
124
    charge_gas(evm, GAS_BASE)
125
126
    # OPERATION
127
    push(evm.stack, U256.from_be_bytes(evm.message.caller))
128
129
    # PROGRAM COUNTER
130
    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:
134
    """
135
    Push the value (in wei) sent with the call onto the stack.
136
137
    Parameters
138
    ----------
139
    evm :
140
        The current EVM frame.
141
142
    """
143
    # STACK
144
    pass
145
146
    # GAS
147
    charge_gas(evm, GAS_BASE)
148
149
    # OPERATION
150
    push(evm.stack, evm.message.value)
151
152
    # PROGRAM COUNTER
153
    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:
157
    """
158
    Push a word (32 bytes) of the input data belonging to the current
159
    environment onto the stack.
160
161
    Parameters
162
    ----------
163
    evm :
164
        The current EVM frame.
165
166
    """
167
    # STACK
168
    start_index = pop(evm.stack)
169
170
    # GAS
171
    charge_gas(evm, GAS_VERY_LOW)
172
173
    # OPERATION
174
    value = buffer_read(evm.message.data, start_index, U256(32))
175
176
    push(evm.stack, U256.from_be_bytes(value))
177
178
    # PROGRAM COUNTER
179
    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:
183
    """
184
    Push the size of input data in current environment onto the stack.
185
186
    Parameters
187
    ----------
188
    evm :
189
        The current EVM frame.
190
191
    """
192
    # STACK
193
    pass
194
195
    # GAS
196
    charge_gas(evm, GAS_BASE)
197
198
    # OPERATION
199
    push(evm.stack, U256(len(evm.message.data)))
200
201
    # PROGRAM COUNTER
202
    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:
206
    """
207
    Copy a portion of the input data in current environment to memory.
208
209
    This will also expand the memory, in case that the memory is insufficient
210
    to store the data.
211
212
    Parameters
213
    ----------
214
    evm :
215
        The current EVM frame.
216
217
    """
218
    # STACK
219
    memory_start_index = pop(evm.stack)
220
    data_start_index = pop(evm.stack)
221
    size = pop(evm.stack)
222
223
    # GAS
224
    words = ceil32(Uint(size)) // Uint(32)
225
    copy_gas_cost = GAS_COPY * words
226
    extend_memory = calculate_gas_extend_memory(
227
        evm.memory, [(memory_start_index, size)]
228
    )
229
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
230
231
    # OPERATION
232
    evm.memory += b"\x00" * extend_memory.expand_by
233
    value = buffer_read(evm.message.data, data_start_index, size)
234
    memory_write(evm.memory, memory_start_index, value)
235
236
    # PROGRAM COUNTER
237
    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:
241
    """
242
    Push the size of code running in current environment onto the stack.
243
244
    Parameters
245
    ----------
246
    evm :
247
        The current EVM frame.
248
249
    """
250
    # STACK
251
    pass
252
253
    # GAS
254
    charge_gas(evm, GAS_BASE)
255
256
    # OPERATION
257
    push(evm.stack, U256(len(evm.code)))
258
259
    # PROGRAM COUNTER
260
    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:
264
    """
265
    Copy a portion of the code in current environment to memory.
266
267
    This will also expand the memory, in case that the memory is insufficient
268
    to store the data.
269
270
    Parameters
271
    ----------
272
    evm :
273
        The current EVM frame.
274
275
    """
276
    # STACK
277
    memory_start_index = pop(evm.stack)
278
    code_start_index = pop(evm.stack)
279
    size = pop(evm.stack)
280
281
    # GAS
282
    words = ceil32(Uint(size)) // Uint(32)
283
    copy_gas_cost = GAS_COPY * words
284
    extend_memory = calculate_gas_extend_memory(
285
        evm.memory, [(memory_start_index, size)]
286
    )
287
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
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, GAS_BASE)
313
314
    # OPERATION
315
    push(evm.stack, U256(evm.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(pop(evm.stack))
333
334
    # GAS
335
    charge_gas(evm, GAS_EXTERNAL)
336
337
    # OPERATION
338
    # Non-existent accounts default to EMPTY_ACCOUNT, which has empty code.
339
    codesize = U256(len(get_account(evm.env.state, address).code))
340
341
    push(evm.stack, codesize)
342
343
    # PROGRAM COUNTER
344
    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:
348
    """
349
    Copy a portion of an account's code to memory.
350
351
    Parameters
352
    ----------
353
    evm :
354
        The current EVM frame.
355
356
    """
357
    # STACK
358
    address = to_address(pop(evm.stack))
359
    memory_start_index = pop(evm.stack)
360
    code_start_index = pop(evm.stack)
361
    size = pop(evm.stack)
362
363
    # GAS
364
    words = ceil32(Uint(size)) // Uint(32)
365
    copy_gas_cost = GAS_COPY * words
366
    extend_memory = calculate_gas_extend_memory(
367
        evm.memory, [(memory_start_index, size)]
368
    )
369
    charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost)
370
371
    # OPERATION
372
    evm.memory += b"\x00" * extend_memory.expand_by
373
    code = get_account(evm.env.state, address).code
374
    value = buffer_read(code, code_start_index, size)
375
    memory_write(evm.memory, memory_start_index, value)
376
377
    # PROGRAM COUNTER
378
    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:
382
    """
383
    Pushes the size of the return data buffer onto the stack.
384
385
    Parameters
386
    ----------
387
    evm :
388
        The current EVM frame.
389
    """
390
    # STACK
391
    pass
392
393
    # GAS
394
    charge_gas(evm, GAS_BASE)
395
396
    # OPERATION
397
    push(evm.stack, U256(len(evm.return_data)))
398
399
    # PROGRAM COUNTER
400
    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:
404
    """
405
    Copies data from the return data buffer code to memory
406
407
    Parameters
408
    ----------
409
    evm :
410
        The current EVM frame.
411
    """
412
    # STACK
413
    memory_start_index = pop(evm.stack)
414
    return_data_start_position = pop(evm.stack)
415
    size = pop(evm.stack)
416
417
    # GAS
418
    words = ceil32(Uint(size)) // Uint(32)
419
    copy_gas_cost = GAS_RETURN_DATA_COPY * words
420
    extend_memory = calculate_gas_extend_memory(
421
        evm.memory, [(memory_start_index, size)]
422
    )
423
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
424
    if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data):
425
        raise OutOfBoundsRead
426
427
    evm.memory += b"\x00" * extend_memory.expand_by
428
    value = evm.return_data[
429
        return_data_start_position : return_data_start_position + size
430
    ]
431
    memory_write(evm.memory, memory_start_index, value)
432
433
    # PROGRAM COUNTER
434
    evm.pc += Uint(1)