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 |