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}