evm_opcode/lib.rs
1//! Ethereum virtual machine opcode
2
3/// Ethereum virtual machine opcode.
4#[derive(Clone, Copy, Debug)]
5pub enum OpCode {
6 // 0x0 range - Stop and Arithmetic Operations
7 //
8 /// Halts execution.
9 STOP,
10 /// Addition operation.
11 ADD,
12 /// Multiplication operation.
13 MUL,
14 /// Subtraction operation.
15 SUB,
16 /// Integer division operation.
17 DIV,
18 /// Signed integer division operation (truncated).
19 SDIV,
20 /// Modulo remainder operation.
21 MOD,
22 /// Signed modulo remainder operation.
23 SMOD,
24 /// Modulo addition operation.
25 ADDMOD,
26 /// Modulo multiplication operation.
27 MULMOD,
28 /// Exponential operation.
29 EXP,
30 /// Extend length of signed integer.
31 SIGNEXTEND,
32 // 0x10 range - Comparison & Bitwise Logic Operations
33 //
34 /// Less-than comparision.
35 LT,
36 /// Greater-than comparision.
37 GT,
38 /// Signed less-than comparision.
39 SLT,
40 /// Signed greater-than comparision.
41 SGT,
42 /// Equality comparision.
43 EQ,
44 /// Simple not operator.
45 ISZERO,
46 /// Bitwise AND operation.
47 AND,
48 /// Bitwise OR operation.
49 OR,
50 /// Bitwise XOR operation.
51 XOR,
52 /// Bitwise NOT operation.
53 NOT,
54 /// Retrieve single byte from word.
55 BYTE,
56 /// Shift left operation.
57 SHL,
58 /// Logical shift right operation.
59 SHR,
60 /// Arithmetic shift right operation.
61 SAR,
62 // 0x20 range - SHA3
63 //
64 /// Compute Keccak-256 hash.
65 SHA3,
66 // 0x30 range - Environmental Information
67 //
68 /// Get address of currently executing account.
69 ADDRESS,
70 /// Get balance of the given account.
71 BALANCE,
72 /// Get execution origination address.
73 ORIGIN,
74 /// Get caller address.
75 CALLER,
76 /// Get deposited value by the instruction/transaction responsible for this execution.
77 CALLVALUE,
78 /// Get input data of current environment.
79 CALLDATALOAD,
80 /// Get size of input data in current environment.
81 CALLDATASIZE,
82 /// Copy input data in current environment to memory.
83 CALLDATACOPY,
84 /// Get size of code running in current environment.
85 CODESIZE,
86 /// Copy code running in current environment to memory.
87 CODECOPY,
88 /// Get price of gas in current environment.
89 GASPRICE,
90 /// Get external code size.
91 EXTCODESIZE,
92 /// Copy external code to memory.
93 EXTCODECOPY,
94 /// Get size of available gas.
95 RETURNDATASIZE,
96 /// Copy output data to memory.
97 RETURNDATACOPY,
98 /// Get size of code running in current environment.
99 EXTCODEHASH,
100 // 0x40 range - Block Information
101 //
102 /// Get hash of most recent complete block.
103 BLOCKHASH,
104 /// Get the block's coinbase address.
105 COINBASE,
106 /// Get the block's timestamp.
107 TIMESTAMP,
108 /// Get the block's number.
109 NUMBER,
110 /// Get the block's difficulty.
111 DIFFICULTY,
112 /// Get the block's gas limit.
113 GASLIMIT,
114 /// Get the chain ID.
115 CHAINID,
116 /// Get balance of currently executing account.
117 SELFBALANCE,
118 /// Get the base fee.
119 BASEFEE,
120 // 0x50 range - Stack, Memory, Storage and Flow Operations
121 //
122 /// Remove item from stack.
123 POP,
124 /// Load word from memory.
125 MLOAD,
126 /// Save word to memory.
127 MSTORE,
128 /// Save byte to memory.
129 MSTORE8,
130 /// Load word from storage.
131 SLOAD,
132 /// Save word to storage.
133 SSTORE,
134 /// Alter the program counter.
135 JUMP,
136 /// Conditionally alter the program counter.
137 JUMPI,
138 /// Get the program counter.
139 PC,
140 /// Get the size of active memory.
141 MSIZE,
142 /// Get the amount of available gas.
143 GAS,
144 /// Set a potential jump destination.
145 JUMPDEST,
146 // 0x5f range - Push Operations
147 //
148 /// Place value 0 on stack.
149 PUSH0,
150 /// Place 1 byte item on stack.
151 PUSH1,
152 /// Place 2 byte item on stack.
153 PUSH2,
154 /// Place 3 byte item on stack.
155 PUSH3,
156 /// Place 4 byte item on stack.
157 PUSH4,
158 /// Place 5 byte item on stack.
159 PUSH5,
160 /// Place 6 byte item on stack.
161 PUSH6,
162 /// Place 7 byte item on stack.
163 PUSH7,
164 /// Place 8 byte item on stack.
165 PUSH8,
166 /// Place 9 byte item on stack.
167 PUSH9,
168 /// Place 10 byte item on stack.
169 PUSH10,
170 /// Place 11 byte item on stack.
171 PUSH11,
172 /// Place 12 byte item on stack.
173 PUSH12,
174 /// Place 13 byte item on stack.
175 PUSH13,
176 /// Place 14 byte item on stack.
177 PUSH14,
178 /// Place 15 byte item on stack.
179 PUSH15,
180 /// Place 16 byte item on stack.
181 PUSH16,
182 /// Place 17 byte item on stack.
183 PUSH17,
184 /// Place 18 byte item on stack.
185 PUSH18,
186 /// Place 19 byte item on stack.
187 PUSH19,
188 /// Place 20 byte item on stack.
189 PUSH20,
190 /// Place 21 byte item on stack.
191 PUSH21,
192 /// Place 22 byte item on stack.
193 PUSH22,
194 /// Place 23 byte item on stack.
195 PUSH23,
196 /// Place 24 byte item on stack.
197 PUSH24,
198 /// Place 25 byte item on stack.
199 PUSH25,
200 /// Place 26 byte item on stack.
201 PUSH26,
202 /// Place 27 byte item on stack.
203 PUSH27,
204 /// Place 28 byte item on stack.
205 PUSH28,
206 /// Place 29 byte item on stack.
207 PUSH29,
208 /// Place 30 byte item on stack.
209 PUSH30,
210 /// Place 31 byte item on stack.
211 PUSH31,
212 /// Place 32 byte item on stack.
213 PUSH32,
214 // 0x80 range - Duplication Operations
215 //
216 /// Duplicate 1st stack item.
217 DUP1,
218 /// Duplicate 2nd stack item.
219 DUP2,
220 /// Duplicate 3rd stack item.
221 DUP3,
222 /// Duplicate 4th stack item.
223 DUP4,
224 /// Duplicate 5th stack item.
225 DUP5,
226 /// Duplicate 6th stack item.
227 DUP6,
228 /// Duplicate 7th stack item.
229 DUP7,
230 /// Duplicate 8th stack item.
231 DUP8,
232 /// Duplicate 9th stack item.
233 DUP9,
234 /// Duplicate 10th stack item.
235 DUP10,
236 /// Duplicate 11th stack item.
237 DUP11,
238 /// Duplicate 12th stack item.
239 DUP12,
240 /// Duplicate 13th stack item.
241 DUP13,
242 /// Duplicate 14th stack item.
243 DUP14,
244 /// Duplicate 15th stack item.
245 DUP15,
246 /// Duplicate 16th stack item.
247 DUP16,
248 // 0x90 range - Exchange Operations
249 //
250 /// Exchange 1st and 2nd stack items.
251 SWAP1,
252 /// Exchange 1st and 3rd stack items.
253 SWAP2,
254 /// Exchange 1st and 4th stack items.
255 SWAP3,
256 /// Exchange 1st and 5th stack items.
257 SWAP4,
258 /// Exchange 1st and 6th stack items.
259 SWAP5,
260 /// Exchange 1st and 7th stack items.
261 SWAP6,
262 /// Exchange 1st and 8th stack items.
263 SWAP7,
264 /// Exchange 1st and 9th stack items.
265 SWAP8,
266 /// Exchange 1st and 10th stack items.
267 SWAP9,
268 /// Exchange 1st and 11th stack items.
269 SWAP10,
270 /// Exchange 1st and 12th stack items.
271 SWAP11,
272 /// Exchange 1st and 13th stack items.
273 SWAP12,
274 /// Exchange 1st and 14th stack items.
275 SWAP13,
276 /// Exchange 1st and 15th stack items.
277 SWAP14,
278 /// Exchange 1st and 16th stack items.
279 SWAP15,
280 /// Exchange 1st and 17th stack items.
281 SWAP16,
282 // 0xa0 range - Logging Operations
283 //
284 /// Append log record with no topics.
285 LOG0,
286 /// Append log record with one topic.
287 LOG1,
288 /// Append log record with two topics.
289 LOG2,
290 /// Append log record with three topics.
291 LOG3,
292 /// Append log record with four topics.
293 LOG4,
294 // 0xf0 range - System operations
295 //
296 /// Create a new account with associated code.
297 CREATE,
298 /// Message-call into an account.
299 CALL,
300 /// Message-call into this account with an alternative account's code.
301 CALLCODE,
302 /// Halts execution returning output data.
303 RETURN,
304 /// Message-call into this account with an alternative account's code,
305 /// but with persistent state and code not being modified.
306 DELEGATECALL,
307 /// Create a new account without associated code.
308 CREATE2,
309 /// Static message-call into an account.
310 STATICCALL,
311 /// Halt execution and register account for later deletion.
312 REVERT,
313 /// Designated invalid instruction.
314 INVALID,
315 /// Halt execution and register account for later deletion, unless
316 /// already scheduled.
317 SELFDESTRUCT,
318}
319
320impl From<u8> for OpCode {
321 fn from(code: u8) -> Self {
322 match code {
323 0x00 => Self::STOP,
324 0x01 => Self::ADD,
325 0x02 => Self::MUL,
326 0x03 => Self::SUB,
327 0x04 => Self::DIV,
328 0x05 => Self::SDIV,
329 0x06 => Self::MOD,
330 0x07 => Self::SMOD,
331 0x08 => Self::ADDMOD,
332 0x09 => Self::MULMOD,
333 0x0a => Self::EXP,
334 0x0b => Self::SIGNEXTEND,
335 0x10 => Self::LT,
336 0x11 => Self::GT,
337 0x12 => Self::SLT,
338 0x13 => Self::SGT,
339 0x14 => Self::EQ,
340 0x15 => Self::ISZERO,
341 0x16 => Self::AND,
342 0x17 => Self::OR,
343 0x18 => Self::XOR,
344 0x19 => Self::NOT,
345 0x1a => Self::BYTE,
346 0x1b => Self::SHL,
347 0x1c => Self::SHR,
348 0x1d => Self::SAR,
349 0x20 => Self::SHA3,
350 0x30 => Self::ADDRESS,
351 0x31 => Self::BALANCE,
352 0x32 => Self::ORIGIN,
353 0x33 => Self::CALLER,
354 0x34 => Self::CALLVALUE,
355 0x35 => Self::CALLDATALOAD,
356 0x36 => Self::CALLDATASIZE,
357 0x37 => Self::CALLDATACOPY,
358 0x38 => Self::CODESIZE,
359 0x39 => Self::CODECOPY,
360 0x3a => Self::GASPRICE,
361 0x3b => Self::EXTCODESIZE,
362 0x3c => Self::EXTCODECOPY,
363 0x3d => Self::RETURNDATASIZE,
364 0x3e => Self::RETURNDATACOPY,
365 0x3f => Self::EXTCODEHASH,
366 0x40 => Self::BLOCKHASH,
367 0x41 => Self::COINBASE,
368 0x42 => Self::TIMESTAMP,
369 0x43 => Self::NUMBER,
370 0x44 => Self::DIFFICULTY,
371 0x45 => Self::GASLIMIT,
372 0x46 => Self::CHAINID,
373 0x47 => Self::SELFBALANCE,
374 0x48 => Self::BASEFEE,
375 0x50 => Self::POP,
376 0x51 => Self::MLOAD,
377 0x52 => Self::MSTORE,
378 0x53 => Self::MSTORE8,
379 0x54 => Self::SLOAD,
380 0x55 => Self::SSTORE,
381 0x56 => Self::JUMP,
382 0x57 => Self::JUMPI,
383 0x58 => Self::PC,
384 0x59 => Self::MSIZE,
385 0x5a => Self::GAS,
386 0x5b => Self::JUMPDEST,
387 0x5f => Self::PUSH0,
388 0x60 => Self::PUSH1,
389 0x61 => Self::PUSH2,
390 0x62 => Self::PUSH3,
391 0x63 => Self::PUSH4,
392 0x64 => Self::PUSH5,
393 0x65 => Self::PUSH6,
394 0x66 => Self::PUSH7,
395 0x67 => Self::PUSH8,
396 0x68 => Self::PUSH9,
397 0x69 => Self::PUSH10,
398 0x6a => Self::PUSH11,
399 0x6b => Self::PUSH12,
400 0x6c => Self::PUSH13,
401 0x6d => Self::PUSH14,
402 0x6e => Self::PUSH15,
403 0x6f => Self::PUSH16,
404 0x70 => Self::PUSH17,
405 0x71 => Self::PUSH18,
406 0x72 => Self::PUSH19,
407 0x73 => Self::PUSH20,
408 0x74 => Self::PUSH21,
409 0x75 => Self::PUSH22,
410 0x76 => Self::PUSH23,
411 0x77 => Self::PUSH24,
412 0x78 => Self::PUSH25,
413 0x79 => Self::PUSH26,
414 0x7a => Self::PUSH27,
415 0x7b => Self::PUSH28,
416 0x7c => Self::PUSH29,
417 0x7d => Self::PUSH30,
418 0x7e => Self::PUSH31,
419 0x7f => Self::PUSH32,
420 0x80 => Self::DUP1,
421 0x81 => Self::DUP2,
422 0x82 => Self::DUP3,
423 0x83 => Self::DUP4,
424 0x84 => Self::DUP5,
425 0x85 => Self::DUP6,
426 0x86 => Self::DUP7,
427 0x87 => Self::DUP8,
428 0x88 => Self::DUP9,
429 0x89 => Self::DUP10,
430 0x8a => Self::DUP11,
431 0x8b => Self::DUP12,
432 0x8c => Self::DUP13,
433 0x8d => Self::DUP14,
434 0x8e => Self::DUP15,
435 0x8f => Self::DUP16,
436 0x90 => Self::SWAP1,
437 0x91 => Self::SWAP2,
438 0x92 => Self::SWAP3,
439 0x93 => Self::SWAP4,
440 0x94 => Self::SWAP5,
441 0x95 => Self::SWAP6,
442 0x96 => Self::SWAP7,
443 0x97 => Self::SWAP8,
444 0x98 => Self::SWAP9,
445 0x99 => Self::SWAP10,
446 0x9a => Self::SWAP11,
447 0x9b => Self::SWAP12,
448 0x9c => Self::SWAP13,
449 0x9d => Self::SWAP14,
450 0x9e => Self::SWAP15,
451 0x9f => Self::SWAP16,
452 0xa0 => Self::LOG0,
453 0xa1 => Self::LOG1,
454 0xa2 => Self::LOG2,
455 0xa3 => Self::LOG3,
456 0xa4 => Self::LOG4,
457 0xf0 => Self::CREATE,
458 0xf1 => Self::CALL,
459 0xf2 => Self::CALLCODE,
460 0xf3 => Self::RETURN,
461 0xf4 => Self::DELEGATECALL,
462 0xf5 => Self::CREATE2,
463 0xfa => Self::STATICCALL,
464 0xfd => Self::REVERT,
465 0xfe => Self::INVALID,
466 0xff => Self::SELFDESTRUCT,
467 _ => Self::INVALID,
468 }
469 }
470}
471
472impl From<OpCode> for u16 {
473 fn from(opcode: OpCode) -> Self {
474 match opcode {
475 OpCode::STOP | OpCode::RETURN => 0,
476 OpCode::JUMPDEST => 1,
477 OpCode::ADDRESS
478 | OpCode::ORIGIN
479 | OpCode::CALLER
480 | OpCode::CALLVALUE
481 | OpCode::CODESIZE
482 | OpCode::GASPRICE
483 | OpCode::RETURNDATASIZE
484 | OpCode::COINBASE
485 | OpCode::TIMESTAMP
486 | OpCode::NUMBER
487 | OpCode::DIFFICULTY
488 | OpCode::GASLIMIT
489 | OpCode::CHAINID
490 | OpCode::BASEFEE
491 | OpCode::POP
492 | OpCode::PC
493 | OpCode::MSIZE
494 | OpCode::GAS
495 | OpCode::PUSH0 => 2,
496 OpCode::MUL
497 | OpCode::DIV
498 | OpCode::SDIV
499 | OpCode::MOD
500 | OpCode::SMOD
501 | OpCode::SIGNEXTEND
502 | OpCode::SELFBALANCE => 5,
503 OpCode::ADDMOD | OpCode::MULMOD | OpCode::JUMP => 8,
504 OpCode::EXP | OpCode::JUMPI => 10,
505 OpCode::BLOCKHASH => 20,
506 OpCode::SHA3 => 30,
507 OpCode::BALANCE
508 | OpCode::EXTCODESIZE
509 | OpCode::EXTCODECOPY
510 | OpCode::EXTCODEHASH
511 | OpCode::SLOAD
512 | OpCode::SSTORE
513 | OpCode::CALL
514 | OpCode::CALLCODE
515 | OpCode::DELEGATECALL
516 | OpCode::STATICCALL => 100,
517 OpCode::LOG0 => 375,
518 OpCode::LOG1 => 750,
519 OpCode::LOG2 => 1125,
520 OpCode::LOG3 => 1500,
521 OpCode::LOG4 => 1875,
522 OpCode::SELFDESTRUCT => 5000,
523 OpCode::CREATE | OpCode::CREATE2 => 32000,
524 _ => 3,
525 }
526 }
527}
528
529impl OpCode {
530 /// Returns the minimal gas cost of the opcode.
531 pub fn gas<T>(&self) -> T
532 where
533 T: From<u16>,
534 {
535 T::from(u16::from(*self))
536 }
537}