ethereum.dao_fork.vm.instructions.environmentethereum.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:
35
    """
36
    Pushes the address of the current executing account to the stack.
37
38
    Parameters
39
    ----------
40
    evm :
41
        The current EVM frame.
42
43
    """
44
    # STACK
45
    pass
46
47
    # GAS
48
    charge_gas(evm, GAS_BASE)
49
50
    # OPERATION
51
    push(evm.stack, U256.from_be_bytes(evm.message.current_target))
52
53
    # PROGRAM COUNTER
54
    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:
58
    """
59
    Pushes the balance of the given account onto the stack.
60
61
    Parameters
62
    ----------
63
    evm :
64
        The current EVM frame.
65
66
    """
67
    # STACK
68
    address = to_address(pop(evm.stack))
69
70
    # GAS
71
    charge_gas(evm, GAS_BALANCE)
72
73
    # OPERATION
74
    # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0.
75
    balance = get_account(evm.env.state, address).balance
76
77
    push(evm.stack, balance)
78
79
    # PROGRAM COUNTER
80
    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:
84
    """
85
    Pushes the address of the original transaction sender to the stack.
86
    The origin address can only be an EOA.
87
88
    Parameters
89
    ----------
90
    evm :
91
        The current EVM frame.
92
93
    """
94
    # STACK
95
    pass
96
97
    # GAS
98
    charge_gas(evm, GAS_BASE)
99
100
    # OPERATION
101
    push(evm.stack, U256.from_be_bytes(evm.env.origin))
102
103
    # PROGRAM COUNTER
104
    evm.pc += 1

caller

Pushes the address of the caller onto the stack.

Parameters

evm : The current EVM frame.

def caller(evm: Evm) -> None:
108
    """
109
    Pushes the address of the caller onto the stack.
110
111
    Parameters
112
    ----------
113
    evm :
114
        The current EVM frame.
115
116
    """
117
    # STACK
118
    pass
119
120
    # GAS
121
    charge_gas(evm, GAS_BASE)
122
123
    # OPERATION
124
    push(evm.stack, U256.from_be_bytes(evm.message.caller))
125
126
    # PROGRAM COUNTER
127
    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:
131
    """
132
    Push the value (in wei) sent with the call onto the stack.
133
134
    Parameters
135
    ----------
136
    evm :
137
        The current EVM frame.
138
139
    """
140
    # STACK
141
    pass
142
143
    # GAS
144
    charge_gas(evm, GAS_BASE)
145
146
    # OPERATION
147
    push(evm.stack, evm.message.value)
148
149
    # PROGRAM COUNTER
150
    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:
154
    """
155
    Push a word (32 bytes) of the input data belonging to the current
156
    environment onto the stack.
157
158
    Parameters
159
    ----------
160
    evm :
161
        The current EVM frame.
162
163
    """
164
    # STACK
165
    start_index = pop(evm.stack)
166
167
    # GAS
168
    charge_gas(evm, GAS_VERY_LOW)
169
170
    # OPERATION
171
    value = buffer_read(evm.message.data, start_index, U256(32))
172
173
    push(evm.stack, U256.from_be_bytes(value))
174
175
    # PROGRAM COUNTER
176
    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:
180
    """
181
    Push the size of input data in current environment onto the stack.
182
183
    Parameters
184
    ----------
185
    evm :
186
        The current EVM frame.
187
188
    """
189
    # STACK
190
    pass
191
192
    # GAS
193
    charge_gas(evm, GAS_BASE)
194
195
    # OPERATION
196
    push(evm.stack, U256(len(evm.message.data)))
197
198
    # PROGRAM COUNTER
199
    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:
203
    """
204
    Copy a portion of the input data in current environment to memory.
205
206
    This will also expand the memory, in case that the memory is insufficient
207
    to store the data.
208
209
    Parameters
210
    ----------
211
    evm :
212
        The current EVM frame.
213
214
    """
215
    # STACK
216
    memory_start_index = pop(evm.stack)
217
    data_start_index = pop(evm.stack)
218
    size = pop(evm.stack)
219
220
    # GAS
221
    words = ceil32(Uint(size)) // 32
222
    copy_gas_cost = GAS_COPY * words
223
    extend_memory = calculate_gas_extend_memory(
224
        evm.memory, [(memory_start_index, size)]
225
    )
226
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
227
228
    # OPERATION
229
    evm.memory += b"\x00" * extend_memory.expand_by
230
    value = buffer_read(evm.message.data, data_start_index, size)
231
    memory_write(evm.memory, memory_start_index, value)
232
233
    # PROGRAM COUNTER
234
    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:
238
    """
239
    Push the size of code running in current environment onto the stack.
240
241
    Parameters
242
    ----------
243
    evm :
244
        The current EVM frame.
245
246
    """
247
    # STACK
248
    pass
249
250
    # GAS
251
    charge_gas(evm, GAS_BASE)
252
253
    # OPERATION
254
    push(evm.stack, U256(len(evm.code)))
255
256
    # PROGRAM COUNTER
257
    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:
261
    """
262
    Copy a portion of the code in current environment to memory.
263
264
    This will also expand the memory, in case that the memory is insufficient
265
    to store the data.
266
267
    Parameters
268
    ----------
269
    evm :
270
        The current EVM frame.
271
272
    """
273
    # STACK
274
    memory_start_index = pop(evm.stack)
275
    code_start_index = pop(evm.stack)
276
    size = pop(evm.stack)
277
278
    # GAS
279
    words = ceil32(Uint(size)) // 32
280
    copy_gas_cost = GAS_COPY * words
281
    extend_memory = calculate_gas_extend_memory(
282
        evm.memory, [(memory_start_index, size)]
283
    )
284
    charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost)
285
286
    # OPERATION
287
    evm.memory += b"\x00" * extend_memory.expand_by
288
    value = buffer_read(evm.code, code_start_index, size)
289
    memory_write(evm.memory, memory_start_index, value)
290
291
    # PROGRAM COUNTER
292
    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:
296
    """
297
    Push the gas price used in current environment onto the stack.
298
299
    Parameters
300
    ----------
301
    evm :
302
        The current EVM frame.
303
304
    """
305
    # STACK
306
    pass
307
308
    # GAS
309
    charge_gas(evm, GAS_BASE)
310
311
    # OPERATION
312
    push(evm.stack, U256(evm.env.gas_price))
313
314
    # PROGRAM COUNTER
315
    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:
319
    """
320
    Push the code size of a given account onto the stack.
321
322
    Parameters
323
    ----------
324
    evm :
325
        The current EVM frame.
326
327
    """
328
    # STACK
329
    address = to_address(pop(evm.stack))
330
331
    # GAS
332
    charge_gas(evm, GAS_EXTERNAL)
333
334
    # OPERATION
335
    # Non-existent accounts default to EMPTY_ACCOUNT, which has empty code.
336
    codesize = U256(len(get_account(evm.env.state, address).code))
337
338
    push(evm.stack, codesize)
339
340
    # PROGRAM COUNTER
341
    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:
345
    """
346
    Copy a portion of an account's code to memory.
347
348
    Parameters
349
    ----------
350
    evm :
351
        The current EVM frame.
352
353
    """
354
    # STACK
355
    address = to_address(pop(evm.stack))
356
    memory_start_index = pop(evm.stack)
357
    code_start_index = pop(evm.stack)
358
    size = pop(evm.stack)
359
360
    # GAS
361
    words = ceil32(Uint(size)) // 32
362
    copy_gas_cost = GAS_COPY * words
363
    extend_memory = calculate_gas_extend_memory(
364
        evm.memory, [(memory_start_index, size)]
365
    )
366
    charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost)
367
368
    # OPERATION
369
    evm.memory += b"\x00" * extend_memory.expand_by
370
    code = get_account(evm.env.state, address).code
371
    value = buffer_read(code, code_start_index, size)
372
    memory_write(evm.memory, memory_start_index, value)
373
374
    # PROGRAM COUNTER
375
    evm.pc += 1