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.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.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.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
    # Non-existent accounts default to EMPTY_ACCOUNT, which has empty code.
342
    codesize = U256(len(get_account(evm.env.state, address).code))
343
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.env.state, address).code
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
    # STACK
394
    pass
395
396
    # GAS
397
    charge_gas(evm, GAS_BASE)
398
399
    # OPERATION
400
    push(evm.stack, U256(len(evm.return_data)))
401
402
    # PROGRAM COUNTER
403
    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:
407
    """
408
    Copies data from the return data buffer code to memory
409
410
    Parameters
411
    ----------
412
    evm :
413
        The current EVM frame.
414
    """
415
    # STACK
416
    memory_start_index = pop(evm.stack)
417
    return_data_start_position = pop(evm.stack)
418
    size = pop(evm.stack)
419
420
    # GAS
421
    words = ceil32(Uint(size)) // Uint(32)
422
    copy_gas_cost = GAS_RETURN_DATA_COPY * words
423
    extend_memory = calculate_gas_extend_memory(
424
        evm.memory, [(memory_start_index, size)]
425
    )
426
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
427
    if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data):
428
        raise OutOfBoundsRead
429
430
    evm.memory += b"\x00" * extend_memory.expand_by
431
    value = evm.return_data[
432
        return_data_start_position : return_data_start_position + size
433
    ]
434
    memory_write(evm.memory, memory_start_index, value)
435
436
    # PROGRAM COUNTER
437
    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:
441
    """
442
    Returns the keccak256 hash of a contract’s bytecode
443
    Parameters
444
    ----------
445
    evm :
446
        The current EVM frame.
447
    """
448
    # STACK
449
    address = to_address(pop(evm.stack))
450
451
    # GAS
452
    charge_gas(evm, GAS_CODE_HASH)
453
454
    # OPERATION
455
    account = get_account(evm.env.state, address)
456
457
    if account == EMPTY_ACCOUNT:
458
        codehash = U256(0)
459
    else:
460
        codehash = U256.from_be_bytes(keccak256(account.code))
461
462
    push(evm.stack, codehash)
463
464
    # PROGRAM COUNTER
465
    evm.pc += Uint(1)