evm_core/
opcode.rs

1/// Opcode enum. One-to-one corresponding to an `u8` value.
2#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3#[cfg_attr(
4	feature = "with-codec",
5	derive(
6		scale_codec::Encode,
7		scale_codec::Decode,
8		scale_codec::DecodeWithMemTracking,
9		scale_info::TypeInfo
10	)
11)]
12#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct Opcode(pub u8);
14
15// Core opcodes.
16impl Opcode {
17	/// `STOP`
18	pub const STOP: Opcode = Opcode(0x00);
19	/// `ADD`
20	pub const ADD: Opcode = Opcode(0x01);
21	/// `MUL`
22	pub const MUL: Opcode = Opcode(0x02);
23	/// `SUB`
24	pub const SUB: Opcode = Opcode(0x03);
25	/// `DIV`
26	pub const DIV: Opcode = Opcode(0x04);
27	/// `SDIV`
28	pub const SDIV: Opcode = Opcode(0x05);
29	/// `MOD`
30	pub const MOD: Opcode = Opcode(0x06);
31	/// `SMOD`
32	pub const SMOD: Opcode = Opcode(0x07);
33	/// `ADDMOD`
34	pub const ADDMOD: Opcode = Opcode(0x08);
35	/// `MULMOD`
36	pub const MULMOD: Opcode = Opcode(0x09);
37	/// `EXP`
38	pub const EXP: Opcode = Opcode(0x0a);
39	/// `SIGNEXTEND`
40	pub const SIGNEXTEND: Opcode = Opcode(0x0b);
41
42	/// `LT`
43	pub const LT: Opcode = Opcode(0x10);
44	/// `GT`
45	pub const GT: Opcode = Opcode(0x11);
46	/// `SLT`
47	pub const SLT: Opcode = Opcode(0x12);
48	/// `SGT`
49	pub const SGT: Opcode = Opcode(0x13);
50	/// `EQ`
51	pub const EQ: Opcode = Opcode(0x14);
52	/// `ISZERO`
53	pub const ISZERO: Opcode = Opcode(0x15);
54	/// `AND`
55	pub const AND: Opcode = Opcode(0x16);
56	/// `OR`
57	pub const OR: Opcode = Opcode(0x17);
58	/// `XOR`
59	pub const XOR: Opcode = Opcode(0x18);
60	/// `NOT`
61	pub const NOT: Opcode = Opcode(0x19);
62	/// `BYTE`
63	pub const BYTE: Opcode = Opcode(0x1a);
64
65	/// `CALLDATALOAD`
66	pub const CALLDATALOAD: Opcode = Opcode(0x35);
67	/// `CALLDATASIZE`
68	pub const CALLDATASIZE: Opcode = Opcode(0x36);
69	/// `CALLDATACOPY`
70	pub const CALLDATACOPY: Opcode = Opcode(0x37);
71	/// `CODESIZE`
72	pub const CODESIZE: Opcode = Opcode(0x38);
73	/// `CODECOPY`
74	pub const CODECOPY: Opcode = Opcode(0x39);
75
76	/// `SHL`
77	pub const SHL: Opcode = Opcode(0x1b);
78	/// `SHR`
79	pub const SHR: Opcode = Opcode(0x1c);
80	/// `SAR`
81	pub const SAR: Opcode = Opcode(0x1d);
82
83	/// `POP`
84	pub const POP: Opcode = Opcode(0x50);
85	/// `MLOAD`
86	pub const MLOAD: Opcode = Opcode(0x51);
87	/// `MSTORE`
88	pub const MSTORE: Opcode = Opcode(0x52);
89	/// `MSTORE8`
90	pub const MSTORE8: Opcode = Opcode(0x53);
91	/// `JUMP`
92	pub const JUMP: Opcode = Opcode(0x56);
93	/// `JUMPI`
94	pub const JUMPI: Opcode = Opcode(0x57);
95	/// `PC`
96	pub const PC: Opcode = Opcode(0x58);
97	/// `MSIZE`
98	pub const MSIZE: Opcode = Opcode(0x59);
99	/// `JUMPDEST`
100	pub const JUMPDEST: Opcode = Opcode(0x5b);
101	/// `MCOPY`
102	pub const MCOPY: Opcode = Opcode(0x5e);
103
104	/// `PUSHn`
105	pub const PUSH0: Opcode = Opcode(0x5f);
106	pub const PUSH1: Opcode = Opcode(0x60);
107	pub const PUSH2: Opcode = Opcode(0x61);
108	pub const PUSH3: Opcode = Opcode(0x62);
109	pub const PUSH4: Opcode = Opcode(0x63);
110	pub const PUSH5: Opcode = Opcode(0x64);
111	pub const PUSH6: Opcode = Opcode(0x65);
112	pub const PUSH7: Opcode = Opcode(0x66);
113	pub const PUSH8: Opcode = Opcode(0x67);
114	pub const PUSH9: Opcode = Opcode(0x68);
115	pub const PUSH10: Opcode = Opcode(0x69);
116	pub const PUSH11: Opcode = Opcode(0x6a);
117	pub const PUSH12: Opcode = Opcode(0x6b);
118	pub const PUSH13: Opcode = Opcode(0x6c);
119	pub const PUSH14: Opcode = Opcode(0x6d);
120	pub const PUSH15: Opcode = Opcode(0x6e);
121	pub const PUSH16: Opcode = Opcode(0x6f);
122	pub const PUSH17: Opcode = Opcode(0x70);
123	pub const PUSH18: Opcode = Opcode(0x71);
124	pub const PUSH19: Opcode = Opcode(0x72);
125	pub const PUSH20: Opcode = Opcode(0x73);
126	pub const PUSH21: Opcode = Opcode(0x74);
127	pub const PUSH22: Opcode = Opcode(0x75);
128	pub const PUSH23: Opcode = Opcode(0x76);
129	pub const PUSH24: Opcode = Opcode(0x77);
130	pub const PUSH25: Opcode = Opcode(0x78);
131	pub const PUSH26: Opcode = Opcode(0x79);
132	pub const PUSH27: Opcode = Opcode(0x7a);
133	pub const PUSH28: Opcode = Opcode(0x7b);
134	pub const PUSH29: Opcode = Opcode(0x7c);
135	pub const PUSH30: Opcode = Opcode(0x7d);
136	pub const PUSH31: Opcode = Opcode(0x7e);
137	pub const PUSH32: Opcode = Opcode(0x7f);
138
139	/// `DUPn`
140	pub const DUP1: Opcode = Opcode(0x80);
141	pub const DUP2: Opcode = Opcode(0x81);
142	pub const DUP3: Opcode = Opcode(0x82);
143	pub const DUP4: Opcode = Opcode(0x83);
144	pub const DUP5: Opcode = Opcode(0x84);
145	pub const DUP6: Opcode = Opcode(0x85);
146	pub const DUP7: Opcode = Opcode(0x86);
147	pub const DUP8: Opcode = Opcode(0x87);
148	pub const DUP9: Opcode = Opcode(0x88);
149	pub const DUP10: Opcode = Opcode(0x89);
150	pub const DUP11: Opcode = Opcode(0x8a);
151	pub const DUP12: Opcode = Opcode(0x8b);
152	pub const DUP13: Opcode = Opcode(0x8c);
153	pub const DUP14: Opcode = Opcode(0x8d);
154	pub const DUP15: Opcode = Opcode(0x8e);
155	pub const DUP16: Opcode = Opcode(0x8f);
156
157	/// `SWAPn`
158	pub const SWAP1: Opcode = Opcode(0x90);
159	pub const SWAP2: Opcode = Opcode(0x91);
160	pub const SWAP3: Opcode = Opcode(0x92);
161	pub const SWAP4: Opcode = Opcode(0x93);
162	pub const SWAP5: Opcode = Opcode(0x94);
163	pub const SWAP6: Opcode = Opcode(0x95);
164	pub const SWAP7: Opcode = Opcode(0x96);
165	pub const SWAP8: Opcode = Opcode(0x97);
166	pub const SWAP9: Opcode = Opcode(0x98);
167	pub const SWAP10: Opcode = Opcode(0x99);
168	pub const SWAP11: Opcode = Opcode(0x9a);
169	pub const SWAP12: Opcode = Opcode(0x9b);
170	pub const SWAP13: Opcode = Opcode(0x9c);
171	pub const SWAP14: Opcode = Opcode(0x9d);
172	pub const SWAP15: Opcode = Opcode(0x9e);
173	pub const SWAP16: Opcode = Opcode(0x9f);
174
175	/// `RETURN`
176	pub const RETURN: Opcode = Opcode(0xf3);
177	/// `REVERT`
178	pub const REVERT: Opcode = Opcode(0xfd);
179
180	/// `INVALID`
181	pub const INVALID: Opcode = Opcode(0xfe);
182
183	/// See [EIP-3541](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3541.md)
184	pub const EOFMAGIC: Opcode = Opcode(0xef);
185}
186
187// External opcodes
188impl Opcode {
189	/// `SHA3`
190	pub const SHA3: Opcode = Opcode(0x20);
191	/// `ADDRESS`
192	pub const ADDRESS: Opcode = Opcode(0x30);
193	/// `BALANCE`
194	pub const BALANCE: Opcode = Opcode(0x31);
195	/// `SELFBALANCE`
196	pub const SELFBALANCE: Opcode = Opcode(0x47);
197	/// `BASEFEE`
198	pub const BASEFEE: Opcode = Opcode(0x48);
199	/// `ORIGIN`
200	pub const ORIGIN: Opcode = Opcode(0x32);
201	/// `CALLER`
202	pub const CALLER: Opcode = Opcode(0x33);
203	/// `CALLVALUE`
204	pub const CALLVALUE: Opcode = Opcode(0x34);
205	/// `GASPRICE`
206	pub const GASPRICE: Opcode = Opcode(0x3a);
207	/// `EXTCODESIZE`
208	pub const EXTCODESIZE: Opcode = Opcode(0x3b);
209	/// `EXTCODECOPY`
210	pub const EXTCODECOPY: Opcode = Opcode(0x3c);
211	/// `EXTCODEHASH`
212	pub const EXTCODEHASH: Opcode = Opcode(0x3f);
213	/// `RETURNDATASIZE`
214	pub const RETURNDATASIZE: Opcode = Opcode(0x3d);
215	/// `RETURNDATACOPY`
216	pub const RETURNDATACOPY: Opcode = Opcode(0x3e);
217	/// `BLOCKHASH`
218	pub const BLOCKHASH: Opcode = Opcode(0x40);
219	/// `COINBASE`
220	pub const COINBASE: Opcode = Opcode(0x41);
221	/// `TIMESTAMP`
222	pub const TIMESTAMP: Opcode = Opcode(0x42);
223	/// `NUMBER`
224	pub const NUMBER: Opcode = Opcode(0x43);
225	/// `DIFFICULTY`
226	pub const DIFFICULTY: Opcode = Opcode(0x44);
227	/// `GASLIMIT`
228	pub const GASLIMIT: Opcode = Opcode(0x45);
229	/// `SLOAD`
230	pub const SLOAD: Opcode = Opcode(0x54);
231	/// `SSTORE`
232	pub const SSTORE: Opcode = Opcode(0x55);
233	/// `GAS`
234	pub const GAS: Opcode = Opcode(0x5a);
235	/// `TLOAD`
236	pub const TLOAD: Opcode = Opcode(0x5c);
237	/// `TSTORE`
238	pub const TSTORE: Opcode = Opcode(0x5d);
239	/// `LOGn`
240	pub const LOG0: Opcode = Opcode(0xa0);
241	pub const LOG1: Opcode = Opcode(0xa1);
242	pub const LOG2: Opcode = Opcode(0xa2);
243	pub const LOG3: Opcode = Opcode(0xa3);
244	pub const LOG4: Opcode = Opcode(0xa4);
245	/// `CREATE`
246	pub const CREATE: Opcode = Opcode(0xf0);
247	/// `CREATE2`
248	pub const CREATE2: Opcode = Opcode(0xf5);
249	/// `CALL`
250	pub const CALL: Opcode = Opcode(0xf1);
251	/// `CALLCODE`
252	pub const CALLCODE: Opcode = Opcode(0xf2);
253	/// `DELEGATECALL`
254	pub const DELEGATECALL: Opcode = Opcode(0xf4);
255	/// `STATICCALL`
256	pub const STATICCALL: Opcode = Opcode(0xfa);
257	/// `SUICIDE`
258	pub const SUICIDE: Opcode = Opcode(0xff);
259	/// `CHAINID`
260	pub const CHAINID: Opcode = Opcode(0x46);
261}
262
263impl Opcode {
264	/// Whether the opcode is a push opcode.
265	pub fn is_push(&self) -> Option<u8> {
266		let value = self.0;
267		if (0x60..=0x7f).contains(&value) {
268			Some(value - 0x60 + 1)
269		} else {
270			None
271		}
272	}
273
274	#[inline]
275	pub const fn as_u8(&self) -> u8 {
276		self.0
277	}
278
279	#[inline]
280	pub const fn as_usize(&self) -> usize {
281		self.0 as usize
282	}
283}