ethereum.forks.tangerine_whistle.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:
31
    """
32
    Pushes the address of the current executing account to the stack.
33
34
    Parameters
35
    ----------
36
    evm :
37
        The current EVM frame.
38
39
    """
40
    # STACK
41
    pass
42
43
    # GAS
44
    charge_gas(evm, GasCosts.OPCODE_ADDRESS)
45
46
    # OPERATION
47
    push(evm.stack, U256.from_be_bytes(evm.message.current_target))
48
49
    # PROGRAM COUNTER
50
    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:
54
    """
55
    Pushes the balance of the given account onto the stack.
56
57
    Parameters
58
    ----------
59
    evm :
60
        The current EVM frame.
61
62
    """
63
    # STACK
64
    address = to_address_masked(pop(evm.stack))
65
66
    # GAS
67
    charge_gas(evm, GasCosts.OPCODE_BALANCE)
68
69
    # OPERATION
70
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
71
    balance = get_account(evm.message.block_env.state, address).balance
72
73
    push(evm.stack, balance)
74
75
    # PROGRAM COUNTER
76
    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:
80
    """
81
    Pushes the address of the original transaction sender to the stack.
82
    The origin address can only be an EOA.
83
84
    Parameters
85
    ----------
86
    evm :
87
        The current EVM frame.
88
89
    """
90
    # STACK
91
    pass
92
93
    # GAS
94
    charge_gas(evm, GasCosts.OPCODE_ORIGIN)
95
96
    # OPERATION
97
    push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin))
98
99
    # PROGRAM COUNTER
100
    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:
104
    """
105
    Pushes the address of the caller onto the stack.
106
107
    Parameters
108
    ----------
109
    evm :
110
        The current EVM frame.
111
112
    """
113
    # STACK
114
    pass
115
116
    # GAS
117
    charge_gas(evm, GasCosts.OPCODE_CALLER)
118
119
    # OPERATION
120
    push(evm.stack, U256.from_be_bytes(evm.message.caller))
121
122
    # PROGRAM COUNTER
123
    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:
127
    """
128
    Push the value (in wei) sent with the call onto the stack.
129
130
    Parameters
131
    ----------
132
    evm :
133
        The current EVM frame.
134
135
    """
136
    # STACK
137
    pass
138
139
    # GAS
140
    charge_gas(evm, GasCosts.OPCODE_CALLVALUE)
141
142
    # OPERATION
143
    push(evm.stack, evm.message.value)
144
145
    # PROGRAM COUNTER
146
    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:
150
    """
151
    Push a word (32 bytes) of the input data belonging to the current
152
    environment onto the stack.
153
154
    Parameters
155
    ----------
156
    evm :
157
        The current EVM frame.
158
159
    """
160
    # STACK
161
    start_index = pop(evm.stack)
162
163
    # GAS
164
    charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD)
165
166
    # OPERATION
167
    value = buffer_read(evm.message.data, start_index, U256(32))
168
169
    push(evm.stack, U256.from_be_bytes(value))
170
171
    # PROGRAM COUNTER
172
    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:
176
    """
177
    Push the size of input data in current environment onto the stack.
178
179
    Parameters
180
    ----------
181
    evm :
182
        The current EVM frame.
183
184
    """
185
    # STACK
186
    pass
187
188
    # GAS
189
    charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE)
190
191
    # OPERATION
192
    push(evm.stack, U256(len(evm.message.data)))
193
194
    # PROGRAM COUNTER
195
    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:
199
    """
200
    Copy a portion of the input data in current environment to memory.
201
202
    This will also expand the memory, in case that the memory is insufficient
203
    to store the data.
204
205
    Parameters
206
    ----------
207
    evm :
208
        The current EVM frame.
209
210
    """
211
    # STACK
212
    memory_start_index = pop(evm.stack)
213
    data_start_index = pop(evm.stack)
214
    size = pop(evm.stack)
215
216
    # GAS
217
    words = ceil32(Uint(size)) // Uint(32)
218
    copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words
219
    extend_memory = calculate_gas_extend_memory(
220
        evm.memory, [(memory_start_index, size)]
221
    )
222
    charge_gas(
223
        evm,
224
        GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost,
225
    )
226
227
    # OPERATION
228
    evm.memory += b"\x00" * extend_memory.expand_by
229
    value = buffer_read(evm.message.data, data_start_index, size)
230
    memory_write(evm.memory, memory_start_index, value)
231
232
    # PROGRAM COUNTER
233
    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:
237
    """
238
    Push the size of code running in current environment onto the stack.
239
240
    Parameters
241
    ----------
242
    evm :
243
        The current EVM frame.
244
245
    """
246
    # STACK
247
    pass
248
249
    # GAS
250
    charge_gas(evm, GasCosts.OPCODE_CODESIZE)
251
252
    # OPERATION
253
    push(evm.stack, U256(len(evm.code)))
254
255
    # PROGRAM COUNTER
256
    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:
260
    """
261
    Copy a portion of the code in current environment to memory.
262
263
    This will also expand the memory, in case that the memory is insufficient
264
    to store the data.
265
266
    Parameters
267
    ----------
268
    evm :
269
        The current EVM frame.
270
271
    """
272
    # STACK
273
    memory_start_index = pop(evm.stack)
274
    code_start_index = pop(evm.stack)
275
    size = pop(evm.stack)
276
277
    # GAS
278
    words = ceil32(Uint(size)) // Uint(32)
279
    copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words
280
    extend_memory = calculate_gas_extend_memory(
281
        evm.memory, [(memory_start_index, size)]
282
    )
283
    charge_gas(
284
        evm,
285
        GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost,
286
    )
287
288
    # OPERATION
289
    evm.memory += b"\x00" * extend_memory.expand_by
290
    value = buffer_read(evm.code, code_start_index, size)
291
    memory_write(evm.memory, memory_start_index, value)
292
293
    # PROGRAM COUNTER
294
    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:
298
    """
299
    Push the gas price used in current environment onto the stack.
300
301
    Parameters
302
    ----------
303
    evm :
304
        The current EVM frame.
305
306
    """
307
    # STACK
308
    pass
309
310
    # GAS
311
    charge_gas(evm, GasCosts.OPCODE_GASPRICE)
312
313
    # OPERATION
314
    push(evm.stack, U256(evm.message.tx_env.gas_price))
315
316
    # PROGRAM COUNTER
317
    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:
321
    """
322
    Push the code size of a given account onto the stack.
323
324
    Parameters
325
    ----------
326
    evm :
327
        The current EVM frame.
328
329
    """
330
    # STACK
331
    address = to_address_masked(pop(evm.stack))
332
333
    # GAS
334
    charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE)
335
336
    # OPERATION
337
    account = get_account(evm.message.block_env.state, address)
338
    code = get_code(evm.message.block_env.state, account.code_hash)
339
340
    codesize = U256(len(code))
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_masked(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 = GasCosts.OPCODE_COPY_PER_WORD * words
366
    extend_memory = calculate_gas_extend_memory(
367
        evm.memory, [(memory_start_index, size)]
368
    )
369
    charge_gas(
370
        evm,
371
        GasCosts.OPCODE_EXTERNAL_BASE + copy_gas_cost + extend_memory.cost,
372
    )
373
374
    # OPERATION
375
    evm.memory += b"\x00" * extend_memory.expand_by
376
    account = get_account(evm.message.block_env.state, address)
377
    code = get_code(evm.message.block_env.state, account.code_hash)
378
379
    value = buffer_read(code, code_start_index, size)
380
    memory_write(evm.memory, memory_start_index, value)
381
382
    # PROGRAM COUNTER
383
    evm.pc += Uint(1)