ethereum.dao_fork.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 |