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:
40
    """
41
    Pushes the address of the current executing account to the stack.
42
43
    Parameters
44
    ----------
45
    evm :
46
        The current EVM frame.
47
48
    """
49
    # STACK
50
    pass
51
52
    # GAS
53
    charge_gas(evm, GAS_BASE)
54
55
    # OPERATION
56
    push(evm.stack, U256.from_be_bytes(evm.message.current_target))
57
58
    # PROGRAM COUNTER
59
    evm.pc += 1

balance

Pushes the balance of the given account onto the stack.

Parameters

evm : The current EVM frame.

def balance(evm: Evm) -> None:
63
    """
64
    Pushes the balance of the given account onto the stack.
65
66
    Parameters
67
    ----------
68
    evm :
69
        The current EVM frame.
70
71
    """
72
    # STACK
73
    address = to_address(pop(evm.stack))
74
75
    # GAS
76
    charge_gas(evm, GAS_BALANCE)
77
78
    # OPERATION
79
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
80
    balance = get_account(evm.env.state, address).balance
81
82
    push(evm.stack, balance)
83
84
    # PROGRAM COUNTER
85
    evm.pc += 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:
89
    """
90
    Pushes the address of the original transaction sender to the stack.
91
    The origin address can only be an EOA.
92
93
    Parameters
94
    ----------
95
    evm :
96
        The current EVM frame.
97
98
    """
99
    # STACK
100
    pass
101
102
    # GAS
103
    charge_gas(evm, GAS_BASE)
104
105
    # OPERATION
106
    push(evm.stack, U256.from_be_bytes(evm.env.origin))
107
108
    # PROGRAM COUNTER
109
    evm.pc += 1

caller

Pushes the address of the caller onto the stack.

Parameters

evm : The current EVM frame.

def caller(evm: Evm) -> None:
113
    """
114
    Pushes the address of the caller onto the stack.
115
116
    Parameters
117
    ----------
118
    evm :
119
        The current EVM frame.
120
121
    """
122
    # STACK
123
    pass
124
125
    # GAS
126
    charge_gas(evm, GAS_BASE)
127
128
    # OPERATION
129
    push(evm.stack, U256.from_be_bytes(evm.message.caller))
130
131
    # PROGRAM COUNTER
132
    evm.pc += 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:
136
    """
137
    Push the value (in wei) sent with the call onto the stack.
138
139
    Parameters
140
    ----------
141
    evm :
142
        The current EVM frame.
143
144
    """
145
    # STACK
146
    pass
147
148
    # GAS
149
    charge_gas(evm, GAS_BASE)
150
151
    # OPERATION
152
    push(evm.stack, evm.message.value)
153
154
    # PROGRAM COUNTER
155
    evm.pc += 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:
159
    """
160
    Push a word (32 bytes) of the input data belonging to the current
161
    environment onto the stack.
162
163
    Parameters
164
    ----------
165
    evm :
166
        The current EVM frame.
167
168
    """
169
    # STACK
170
    start_index = pop(evm.stack)
171
172
    # GAS
173
    charge_gas(evm, GAS_VERY_LOW)
174
175
    # OPERATION
176
    value = buffer_read(evm.message.data, start_index, U256(32))
177
178
    push(evm.stack, U256.from_be_bytes(value))
179
180
    # PROGRAM COUNTER
181
    evm.pc += 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:
185
    """
186
    Push the size of input data in current environment onto the stack.
187
188
    Parameters
189
    ----------
190
    evm :
191
        The current EVM frame.
192
193
    """
194
    # STACK
195
    pass
196
197
    # GAS
198
    charge_gas(evm, GAS_BASE)
199
200
    # OPERATION
201
    push(evm.stack, U256(len(evm.message.data)))
202
203
    # PROGRAM COUNTER
204
    evm.pc += 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:
208
    """
209
    Copy a portion of the input data in current environment to memory.
210
211
    This will also expand the memory, in case that the memory is insufficient
212
    to store the data.
213
214
    Parameters
215
    ----------
216
    evm :
217
        The current EVM frame.
218
219
    """
220
    # STACK
221
    memory_start_index = pop(evm.stack)
222
    data_start_index = pop(evm.stack)
223
    size = pop(evm.stack)
224
225
    # GAS
226
    words = ceil32(Uint(size)) // 32
227
    copy_gas_cost = GAS_COPY * words
228
    extend_memory = calculate_gas_extend_memory(
229
        evm.memory, [(memory_start_index, size)]
230
    )
231
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
232
233
    # OPERATION
234
    evm.memory += b"\x00" * extend_memory.expand_by
235
    value = buffer_read(evm.message.data, data_start_index, size)
236
    memory_write(evm.memory, memory_start_index, value)
237
238
    # PROGRAM COUNTER
239
    evm.pc += 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:
243
    """
244
    Push the size of code running in current environment onto the stack.
245
246
    Parameters
247
    ----------
248
    evm :
249
        The current EVM frame.
250
251
    """
252
    # STACK
253
    pass
254
255
    # GAS
256
    charge_gas(evm, GAS_BASE)
257
258
    # OPERATION
259
    push(evm.stack, U256(len(evm.code)))
260
261
    # PROGRAM COUNTER
262
    evm.pc += 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:
266
    """
267
    Copy a portion of the code in current environment to memory.
268
269
    This will also expand the memory, in case that the memory is insufficient
270
    to store the data.
271
272
    Parameters
273
    ----------
274
    evm :
275
        The current EVM frame.
276
277
    """
278
    # STACK
279
    memory_start_index = pop(evm.stack)
280
    code_start_index = pop(evm.stack)
281
    size = pop(evm.stack)
282
283
    # GAS
284
    words = ceil32(Uint(size)) // 32
285
    copy_gas_cost = GAS_COPY * words
286
    extend_memory = calculate_gas_extend_memory(
287
        evm.memory, [(memory_start_index, size)]
288
    )
289
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
290
291
    # OPERATION
292
    evm.memory += b"\x00" * extend_memory.expand_by
293
    value = buffer_read(evm.code, code_start_index, size)
294
    memory_write(evm.memory, memory_start_index, value)
295
296
    # PROGRAM COUNTER
297
    evm.pc += 1

gasprice

Push the gas price used in current environment onto the stack.

Parameters

evm : The current EVM frame.

def gasprice(evm: Evm) -> None:
301
    """
302
    Push the gas price used in current environment onto the stack.
303
304
    Parameters
305
    ----------
306
    evm :
307
        The current EVM frame.
308
309
    """
310
    # STACK
311
    pass
312
313
    # GAS
314
    charge_gas(evm, GAS_BASE)
315
316
    # OPERATION
317
    push(evm.stack, U256(evm.env.gas_price))
318
319
    # PROGRAM COUNTER
320
    evm.pc += 1

extcodesize

Push the code size of a given account onto the stack.

Parameters

evm : The current EVM frame.

def extcodesize(evm: Evm) -> None:
324
    """
325
    Push the code size of a given account onto the stack.
326
327
    Parameters
328
    ----------
329
    evm :
330
        The current EVM frame.
331
332
    """
333
    # STACK
334
    address = to_address(pop(evm.stack))
335
336
    # GAS
337
    charge_gas(evm, GAS_EXTERNAL)
338
339
    # OPERATION
340
    # Non-existent accounts default to EMPTY_ACCOUNT, which has empty code.
341
    codesize = U256(len(get_account(evm.env.state, address).code))
342
343
    push(evm.stack, codesize)
344
345
    # PROGRAM COUNTER
346
    evm.pc += 1

extcodecopy

Copy a portion of an account's code to memory.

Parameters

evm : The current EVM frame.

def extcodecopy(evm: Evm) -> None:
350
    """
351
    Copy a portion of an account's code to memory.
352
353
    Parameters
354
    ----------
355
    evm :
356
        The current EVM frame.
357
358
    """
359
    # STACK
360
    address = to_address(pop(evm.stack))
361
    memory_start_index = pop(evm.stack)
362
    code_start_index = pop(evm.stack)
363
    size = pop(evm.stack)
364
365
    # GAS
366
    words = ceil32(Uint(size)) // 32
367
    copy_gas_cost = GAS_COPY * words
368
    extend_memory = calculate_gas_extend_memory(
369
        evm.memory, [(memory_start_index, size)]
370
    )
371
    charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost)
372
373
    # OPERATION
374
    evm.memory += b"\x00" * extend_memory.expand_by
375
    code = get_account(evm.env.state, address).code
376
    value = buffer_read(code, code_start_index, size)
377
    memory_write(evm.memory, memory_start_index, value)
378
379
    # PROGRAM COUNTER
380
    evm.pc += 1

returndatasize

Pushes the size of the return data buffer onto the stack.

Parameters

evm : The current EVM frame.

def returndatasize(evm: Evm) -> None:
384
    """
385
    Pushes the size of the return data buffer onto the stack.
386
387
    Parameters
388
    ----------
389
    evm :
390
        The current EVM frame.
391
    """
392
    # STACK
393
    pass
394
395
    # GAS
396
    charge_gas(evm, GAS_BASE)
397
398
    # OPERATION
399
    push(evm.stack, U256(len(evm.return_data)))
400
401
    # PROGRAM COUNTER
402
    evm.pc += 1

returndatacopy

Copies data from the return data buffer code to memory

Parameters

evm : The current EVM frame.

def returndatacopy(evm: Evm) -> None:
406
    """
407
    Copies data from the return data buffer code to memory
408
409
    Parameters
410
    ----------
411
    evm :
412
        The current EVM frame.
413
    """
414
    # STACK
415
    memory_start_index = pop(evm.stack)
416
    return_data_start_position = pop(evm.stack)
417
    size = pop(evm.stack)
418
419
    # GAS
420
    words = ceil32(Uint(size)) // 32
421
    copy_gas_cost = GAS_RETURN_DATA_COPY * words
422
    extend_memory = calculate_gas_extend_memory(
423
        evm.memory, [(memory_start_index, size)]
424
    )
425
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
426
    if Uint(return_data_start_position) + Uint(size) > len(evm.return_data):
427
        raise OutOfBoundsRead
428
429
    evm.memory += b"\x00" * extend_memory.expand_by
430
    value = evm.return_data[
431
        return_data_start_position : return_data_start_position + size
432
    ]
433
    memory_write(evm.memory, memory_start_index, value)
434
435
    # PROGRAM COUNTER
436
    evm.pc += 1

extcodehash

Returns the keccak256 hash of a contract’s bytecode Parameters

evm : The current EVM frame.

def extcodehash(evm: Evm) -> None:
440
    """
441
    Returns the keccak256 hash of a contract’s bytecode
442
    Parameters
443
    ----------
444
    evm :
445
        The current EVM frame.
446
    """
447
    # STACK
448
    address = to_address(pop(evm.stack))
449
450
    # GAS
451
    charge_gas(evm, GAS_CODE_HASH)
452
453
    # OPERATION
454
    account = get_account(evm.env.state, address)
455
456
    if account == EMPTY_ACCOUNT:
457
        codehash = U256(0)
458
    else:
459
        codehash = U256.from_be_bytes(keccak256(account.code))
460
461
    push(evm.stack, codehash)
462
463
    # PROGRAM COUNTER
464
    evm.pc += 1