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) |