ethereum.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:
37 | """ |
---|---|
38 | Pushes the address of the current executing account to the stack. |
39 |
|
40 | Parameters |
41 | ---------- |
42 | evm : |
43 | The current EVM frame. |
44 |
|
45 | """ |
46 | # STACK |
47 | pass |
48 | |
49 | # GAS |
50 | charge_gas(evm, GAS_BASE) |
51 | |
52 | # OPERATION |
53 | push(evm.stack, U256.from_be_bytes(evm.message.current_target)) |
54 | |
55 | # PROGRAM COUNTER |
56 | 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:
60 | """ |
---|---|
61 | Pushes the balance of the given account onto the stack. |
62 |
|
63 | Parameters |
64 | ---------- |
65 | evm : |
66 | The current EVM frame. |
67 |
|
68 | """ |
69 | # STACK |
70 | address = to_address(pop(evm.stack)) |
71 | |
72 | # GAS |
73 | charge_gas(evm, GAS_BALANCE) |
74 | |
75 | # OPERATION |
76 | # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. |
77 | balance = get_account(evm.env.state, address).balance |
78 | |
79 | push(evm.stack, balance) |
80 | |
81 | # PROGRAM COUNTER |
82 | 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:
86 | """ |
---|---|
87 | Pushes the address of the original transaction sender to the stack. |
88 | The origin address can only be an EOA. |
89 |
|
90 | Parameters |
91 | ---------- |
92 | evm : |
93 | The current EVM frame. |
94 |
|
95 | """ |
96 | # STACK |
97 | pass |
98 | |
99 | # GAS |
100 | charge_gas(evm, GAS_BASE) |
101 | |
102 | # OPERATION |
103 | push(evm.stack, U256.from_be_bytes(evm.env.origin)) |
104 | |
105 | # PROGRAM COUNTER |
106 | evm.pc += 1 |
caller
Pushes the address of the caller onto the stack.
Parameters
evm : The current EVM frame.
def caller(evm: Evm) -> None:
110 | """ |
---|---|
111 | Pushes the address of the caller onto the stack. |
112 |
|
113 | Parameters |
114 | ---------- |
115 | evm : |
116 | The current EVM frame. |
117 |
|
118 | """ |
119 | # STACK |
120 | pass |
121 | |
122 | # GAS |
123 | charge_gas(evm, GAS_BASE) |
124 | |
125 | # OPERATION |
126 | push(evm.stack, U256.from_be_bytes(evm.message.caller)) |
127 | |
128 | # PROGRAM COUNTER |
129 | 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:
133 | """ |
---|---|
134 | Push the value (in wei) sent with the call onto the stack. |
135 |
|
136 | Parameters |
137 | ---------- |
138 | evm : |
139 | The current EVM frame. |
140 |
|
141 | """ |
142 | # STACK |
143 | pass |
144 | |
145 | # GAS |
146 | charge_gas(evm, GAS_BASE) |
147 | |
148 | # OPERATION |
149 | push(evm.stack, evm.message.value) |
150 | |
151 | # PROGRAM COUNTER |
152 | 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:
156 | """ |
---|---|
157 | Push a word (32 bytes) of the input data belonging to the current |
158 | environment onto the stack. |
159 |
|
160 | Parameters |
161 | ---------- |
162 | evm : |
163 | The current EVM frame. |
164 |
|
165 | """ |
166 | # STACK |
167 | start_index = pop(evm.stack) |
168 | |
169 | # GAS |
170 | charge_gas(evm, GAS_VERY_LOW) |
171 | |
172 | # OPERATION |
173 | value = buffer_read(evm.message.data, start_index, U256(32)) |
174 | |
175 | push(evm.stack, U256.from_be_bytes(value)) |
176 | |
177 | # PROGRAM COUNTER |
178 | 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:
182 | """ |
---|---|
183 | Push the size of input data in current environment onto the stack. |
184 |
|
185 | Parameters |
186 | ---------- |
187 | evm : |
188 | The current EVM frame. |
189 |
|
190 | """ |
191 | # STACK |
192 | pass |
193 | |
194 | # GAS |
195 | charge_gas(evm, GAS_BASE) |
196 | |
197 | # OPERATION |
198 | push(evm.stack, U256(len(evm.message.data))) |
199 | |
200 | # PROGRAM COUNTER |
201 | 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:
205 | """ |
---|---|
206 | Copy a portion of the input data in current environment to memory. |
207 |
|
208 | This will also expand the memory, in case that the memory is insufficient |
209 | to store the data. |
210 |
|
211 | Parameters |
212 | ---------- |
213 | evm : |
214 | The current EVM frame. |
215 |
|
216 | """ |
217 | # STACK |
218 | memory_start_index = pop(evm.stack) |
219 | data_start_index = pop(evm.stack) |
220 | size = pop(evm.stack) |
221 | |
222 | # GAS |
223 | words = ceil32(Uint(size)) // 32 |
224 | copy_gas_cost = GAS_COPY * words |
225 | extend_memory = calculate_gas_extend_memory( |
226 | evm.memory, [(memory_start_index, size)] |
227 | ) |
228 | charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) |
229 | |
230 | # OPERATION |
231 | evm.memory += b"\x00" * extend_memory.expand_by |
232 | value = buffer_read(evm.message.data, data_start_index, size) |
233 | memory_write(evm.memory, memory_start_index, value) |
234 | |
235 | # PROGRAM COUNTER |
236 | 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:
240 | """ |
---|---|
241 | Push the size of code running in current environment onto the stack. |
242 |
|
243 | Parameters |
244 | ---------- |
245 | evm : |
246 | The current EVM frame. |
247 |
|
248 | """ |
249 | # STACK |
250 | pass |
251 | |
252 | # GAS |
253 | charge_gas(evm, GAS_BASE) |
254 | |
255 | # OPERATION |
256 | push(evm.stack, U256(len(evm.code))) |
257 | |
258 | # PROGRAM COUNTER |
259 | 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:
263 | """ |
---|---|
264 | Copy a portion of the code in current environment to memory. |
265 |
|
266 | This will also expand the memory, in case that the memory is insufficient |
267 | to store the data. |
268 |
|
269 | Parameters |
270 | ---------- |
271 | evm : |
272 | The current EVM frame. |
273 |
|
274 | """ |
275 | # STACK |
276 | memory_start_index = pop(evm.stack) |
277 | code_start_index = pop(evm.stack) |
278 | size = pop(evm.stack) |
279 | |
280 | # GAS |
281 | words = ceil32(Uint(size)) // 32 |
282 | copy_gas_cost = GAS_COPY * words |
283 | extend_memory = calculate_gas_extend_memory( |
284 | evm.memory, [(memory_start_index, size)] |
285 | ) |
286 | charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) |
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 += 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, GAS_BASE) |
312 | |
313 | # OPERATION |
314 | push(evm.stack, U256(evm.env.gas_price)) |
315 | |
316 | # PROGRAM COUNTER |
317 | 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:
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(pop(evm.stack)) |
332 | |
333 | # GAS |
334 | charge_gas(evm, GAS_EXTERNAL) |
335 | |
336 | # OPERATION |
337 | # Non-existent accounts default to EMPTY_ACCOUNT, which has empty code. |
338 | codesize = U256(len(get_account(evm.env.state, address).code)) |
339 | |
340 | push(evm.stack, codesize) |
341 | |
342 | # PROGRAM COUNTER |
343 | 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:
347 | """ |
---|---|
348 | Copy a portion of an account's code to memory. |
349 |
|
350 | Parameters |
351 | ---------- |
352 | evm : |
353 | The current EVM frame. |
354 |
|
355 | """ |
356 | # STACK |
357 | address = to_address(pop(evm.stack)) |
358 | memory_start_index = pop(evm.stack) |
359 | code_start_index = pop(evm.stack) |
360 | size = pop(evm.stack) |
361 | |
362 | # GAS |
363 | words = ceil32(Uint(size)) // 32 |
364 | copy_gas_cost = GAS_COPY * words |
365 | extend_memory = calculate_gas_extend_memory( |
366 | evm.memory, [(memory_start_index, size)] |
367 | ) |
368 | charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost) |
369 | |
370 | # OPERATION |
371 | evm.memory += b"\x00" * extend_memory.expand_by |
372 | code = get_account(evm.env.state, address).code |
373 | value = buffer_read(code, code_start_index, size) |
374 | memory_write(evm.memory, memory_start_index, value) |
375 | |
376 | # PROGRAM COUNTER |
377 | 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:
381 | """ |
---|---|
382 | Pushes the size of the return data buffer onto the stack. |
383 |
|
384 | Parameters |
385 | ---------- |
386 | evm : |
387 | The current EVM frame. |
388 | """ |
389 | # STACK |
390 | pass |
391 | |
392 | # GAS |
393 | charge_gas(evm, GAS_BASE) |
394 | |
395 | # OPERATION |
396 | push(evm.stack, U256(len(evm.return_data))) |
397 | |
398 | # PROGRAM COUNTER |
399 | 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:
403 | """ |
---|---|
404 | Copies data from the return data buffer code to memory |
405 |
|
406 | Parameters |
407 | ---------- |
408 | evm : |
409 | The current EVM frame. |
410 | """ |
411 | # STACK |
412 | memory_start_index = pop(evm.stack) |
413 | return_data_start_position = pop(evm.stack) |
414 | size = pop(evm.stack) |
415 | |
416 | # GAS |
417 | words = ceil32(Uint(size)) // 32 |
418 | copy_gas_cost = GAS_RETURN_DATA_COPY * words |
419 | extend_memory = calculate_gas_extend_memory( |
420 | evm.memory, [(memory_start_index, size)] |
421 | ) |
422 | charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) |
423 | if Uint(return_data_start_position) + Uint(size) > len(evm.return_data): |
424 | raise OutOfBoundsRead |
425 | |
426 | evm.memory += b"\x00" * extend_memory.expand_by |
427 | value = evm.return_data[ |
428 | return_data_start_position : return_data_start_position + size |
429 | ] |
430 | memory_write(evm.memory, memory_start_index, value) |
431 | |
432 | # PROGRAM COUNTER |
433 | evm.pc += 1 |