1#![allow(non_camel_case_types)]
6
7use core::fmt;
8
9use self::all::{
10 OP_1, OP_16, OP_1NEGATE, OP_2DIV, OP_2MUL, OP_AND, OP_CAT, OP_CHECKSIGADD, OP_DIV,
11 OP_INVALIDOPCODE, OP_INVERT, OP_LEFT, OP_LSHIFT, OP_MOD, OP_MUL, OP_NOP, OP_NOP1, OP_NOP10,
12 OP_OR, OP_PUSHBYTES_75, OP_RESERVED, OP_RESERVED1, OP_RESERVED2, OP_RETURN, OP_RIGHT,
13 OP_RSHIFT, OP_SUBSTR, OP_VER, OP_VERIF, OP_VERNOTIF, OP_XOR,
14};
15
16const PUSHBYTE_NAMES: [&str; 76] = [
17 "OP_PUSHBYTES_0",
18 "OP_PUSHBYTES_1",
19 "OP_PUSHBYTES_2",
20 "OP_PUSHBYTES_3",
21 "OP_PUSHBYTES_4",
22 "OP_PUSHBYTES_5",
23 "OP_PUSHBYTES_6",
24 "OP_PUSHBYTES_7",
25 "OP_PUSHBYTES_8",
26 "OP_PUSHBYTES_9",
27 "OP_PUSHBYTES_10",
28 "OP_PUSHBYTES_11",
29 "OP_PUSHBYTES_12",
30 "OP_PUSHBYTES_13",
31 "OP_PUSHBYTES_14",
32 "OP_PUSHBYTES_15",
33 "OP_PUSHBYTES_16",
34 "OP_PUSHBYTES_17",
35 "OP_PUSHBYTES_18",
36 "OP_PUSHBYTES_19",
37 "OP_PUSHBYTES_20",
38 "OP_PUSHBYTES_21",
39 "OP_PUSHBYTES_22",
40 "OP_PUSHBYTES_23",
41 "OP_PUSHBYTES_24",
42 "OP_PUSHBYTES_25",
43 "OP_PUSHBYTES_26",
44 "OP_PUSHBYTES_27",
45 "OP_PUSHBYTES_28",
46 "OP_PUSHBYTES_29",
47 "OP_PUSHBYTES_30",
48 "OP_PUSHBYTES_31",
49 "OP_PUSHBYTES_32",
50 "OP_PUSHBYTES_33",
51 "OP_PUSHBYTES_34",
52 "OP_PUSHBYTES_35",
53 "OP_PUSHBYTES_36",
54 "OP_PUSHBYTES_37",
55 "OP_PUSHBYTES_38",
56 "OP_PUSHBYTES_39",
57 "OP_PUSHBYTES_40",
58 "OP_PUSHBYTES_41",
59 "OP_PUSHBYTES_42",
60 "OP_PUSHBYTES_43",
61 "OP_PUSHBYTES_44",
62 "OP_PUSHBYTES_45",
63 "OP_PUSHBYTES_46",
64 "OP_PUSHBYTES_47",
65 "OP_PUSHBYTES_48",
66 "OP_PUSHBYTES_49",
67 "OP_PUSHBYTES_50",
68 "OP_PUSHBYTES_51",
69 "OP_PUSHBYTES_52",
70 "OP_PUSHBYTES_53",
71 "OP_PUSHBYTES_54",
72 "OP_PUSHBYTES_55",
73 "OP_PUSHBYTES_56",
74 "OP_PUSHBYTES_57",
75 "OP_PUSHBYTES_58",
76 "OP_PUSHBYTES_59",
77 "OP_PUSHBYTES_60",
78 "OP_PUSHBYTES_61",
79 "OP_PUSHBYTES_62",
80 "OP_PUSHBYTES_63",
81 "OP_PUSHBYTES_64",
82 "OP_PUSHBYTES_65",
83 "OP_PUSHBYTES_66",
84 "OP_PUSHBYTES_67",
85 "OP_PUSHBYTES_68",
86 "OP_PUSHBYTES_69",
87 "OP_PUSHBYTES_70",
88 "OP_PUSHBYTES_71",
89 "OP_PUSHBYTES_72",
90 "OP_PUSHBYTES_73",
91 "OP_PUSHBYTES_74",
92 "OP_PUSHBYTES_75",
93];
94
95const OP_RETURN_NAMES: [&str; 68] = [
96 "OP_RETURN_187",
97 "OP_RETURN_188",
98 "OP_RETURN_189",
99 "OP_RETURN_190",
100 "OP_RETURN_191",
101 "OP_RETURN_192",
102 "OP_RETURN_193",
103 "OP_RETURN_194",
104 "OP_RETURN_195",
105 "OP_RETURN_196",
106 "OP_RETURN_197",
107 "OP_RETURN_198",
108 "OP_RETURN_199",
109 "OP_RETURN_200",
110 "OP_RETURN_201",
111 "OP_RETURN_202",
112 "OP_RETURN_203",
113 "OP_RETURN_204",
114 "OP_RETURN_205",
115 "OP_RETURN_206",
116 "OP_RETURN_207",
117 "OP_RETURN_208",
118 "OP_RETURN_209",
119 "OP_RETURN_210",
120 "OP_RETURN_211",
121 "OP_RETURN_212",
122 "OP_RETURN_213",
123 "OP_RETURN_214",
124 "OP_RETURN_215",
125 "OP_RETURN_216",
126 "OP_RETURN_217",
127 "OP_RETURN_218",
128 "OP_RETURN_219",
129 "OP_RETURN_220",
130 "OP_RETURN_221",
131 "OP_RETURN_222",
132 "OP_RETURN_223",
133 "OP_RETURN_224",
134 "OP_RETURN_225",
135 "OP_RETURN_226",
136 "OP_RETURN_227",
137 "OP_RETURN_228",
138 "OP_RETURN_229",
139 "OP_RETURN_230",
140 "OP_RETURN_231",
141 "OP_RETURN_232",
142 "OP_RETURN_233",
143 "OP_RETURN_234",
144 "OP_RETURN_235",
145 "OP_RETURN_236",
146 "OP_RETURN_237",
147 "OP_RETURN_238",
148 "OP_RETURN_239",
149 "OP_RETURN_240",
150 "OP_RETURN_241",
151 "OP_RETURN_242",
152 "OP_RETURN_243",
153 "OP_RETURN_244",
154 "OP_RETURN_245",
155 "OP_RETURN_246",
156 "OP_RETURN_247",
157 "OP_RETURN_248",
158 "OP_RETURN_249",
159 "OP_RETURN_250",
160 "OP_RETURN_251",
161 "OP_RETURN_252",
162 "OP_RETURN_253",
163 "OP_RETURN_254",
164];
165
166#[derive(Copy, Clone, PartialEq, Eq, Hash)]
168pub struct Opcode {
169 code: u8,
170}
171
172impl Opcode {
173 #[inline]
175 pub const fn to_u8(self) -> u8 {
176 self.code
177 }
178
179 #[inline]
181 #[allow(clippy::too_many_lines)]
182 pub fn as_str(self) -> &'static str {
183 match self.code {
184 0x00..=0x4b => PUSHBYTE_NAMES[usize::from(self.code)],
185 0x4c => "OP_PUSHDATA1",
186 0x4d => "OP_PUSHDATA2",
187 0x4e => "OP_PUSHDATA4",
188 0x4f => "OP_1NEGATE",
189 0x50 => "OP_RESERVED",
190 0x51 => "OP_1",
191 0x52 => "OP_2",
192 0x53 => "OP_3",
193 0x54 => "OP_4",
194 0x55 => "OP_5",
195 0x56 => "OP_6",
196 0x57 => "OP_7",
197 0x58 => "OP_8",
198 0x59 => "OP_9",
199 0x5a => "OP_10",
200 0x5b => "OP_11",
201 0x5c => "OP_12",
202 0x5d => "OP_13",
203 0x5e => "OP_14",
204 0x5f => "OP_15",
205 0x60 => "OP_16",
206 0x61 => "OP_NOP",
207 0x62 => "OP_VER",
208 0x63 => "OP_IF",
209 0x64 => "OP_NOTIF",
210 0x65 => "OP_VERIF",
211 0x66 => "OP_VERNOTIF",
212 0x67 => "OP_ELSE",
213 0x68 => "OP_ENDIF",
214 0x69 => "OP_VERIFY",
215 0x6a => "OP_RETURN",
216 0x6b => "OP_TOALTSTACK",
217 0x6c => "OP_FROMALTSTACK",
218 0x6d => "OP_2DROP",
219 0x6e => "OP_2DUP",
220 0x6f => "OP_3DUP",
221 0x70 => "OP_2OVER",
222 0x71 => "OP_2ROT",
223 0x72 => "OP_2SWAP",
224 0x73 => "OP_IFDUP",
225 0x74 => "OP_DEPTH",
226 0x75 => "OP_DROP",
227 0x76 => "OP_DUP",
228 0x77 => "OP_NIP",
229 0x78 => "OP_OVER",
230 0x79 => "OP_PICK",
231 0x7a => "OP_ROLL",
232 0x7b => "OP_ROT",
233 0x7c => "OP_SWAP",
234 0x7d => "OP_TUCK",
235 0x7e => "OP_CAT",
236 0x7f => "OP_SUBSTR",
237 0x80 => "OP_LEFT",
238 0x81 => "OP_RIGHT",
239 0x82 => "OP_SIZE",
240 0x83 => "OP_INVERT",
241 0x84 => "OP_AND",
242 0x85 => "OP_OR",
243 0x86 => "OP_XOR",
244 0x87 => "OP_EQUAL",
245 0x88 => "OP_EQUALVERIFY",
246 0x89 => "OP_RESERVED1",
247 0x8a => "OP_RESERVED2",
248 0x8b => "OP_1ADD",
249 0x8c => "OP_1SUB",
250 0x8d => "OP_2MUL",
251 0x8e => "OP_2DIV",
252 0x8f => "OP_NEGATE",
253 0x90 => "OP_ABS",
254 0x91 => "OP_NOT",
255 0x92 => "OP_0NOTEQUAL",
256 0x93 => "OP_ADD",
257 0x94 => "OP_SUB",
258 0x95 => "OP_MUL",
259 0x96 => "OP_DIV",
260 0x97 => "OP_MOD",
261 0x98 => "OP_LSHIFT",
262 0x99 => "OP_RSHIFT",
263 0x9a => "OP_BOOLAND",
264 0x9b => "OP_BOOLOR",
265 0x9c => "OP_NUMEQUAL",
266 0x9d => "OP_NUMEQUALVERIFY",
267 0x9e => "OP_NUMNOTEQUAL",
268 0x9f => "OP_LESSTHAN",
269 0xa0 => "OP_GREATERTHAN",
270 0xa1 => "OP_LESSTHANOREQUAL",
271 0xa2 => "OP_GREATERTHANOREQUAL",
272 0xa3 => "OP_MIN",
273 0xa4 => "OP_MAX",
274 0xa5 => "OP_WITHIN",
275 0xa6 => "OP_RIPEMD160",
276 0xa7 => "OP_SHA1",
277 0xa8 => "OP_SHA256",
278 0xa9 => "OP_HASH160",
279 0xaa => "OP_HASH256",
280 0xab => "OP_CODESEPARATOR",
281 0xac => "OP_CHECKSIG",
282 0xad => "OP_CHECKSIGVERIFY",
283 0xae => "OP_CHECKMULTISIG",
284 0xaf => "OP_CHECKMULTISIGVERIFY",
285 0xb0 => "OP_NOP1",
286 0xb1 => "OP_CLTV",
287 0xb2 => "OP_CSV",
288 0xb3 => "OP_SHA512",
289 0xb4 => "OP_NOP5",
290 0xb5 => "OP_NOP6",
291 0xb6 => "OP_NOP7",
292 0xb7 => "OP_NOP8",
293 0xb8 => "OP_NOP9",
294 0xb9 => "OP_NOP10",
295 0xba => "OP_CHECKSIGADD",
296 0xbb..=0xfe => OP_RETURN_NAMES[usize::from(self.code - 0xbb)],
297 0xff => "OP_INVALIDOPCODE",
298 }
299 }
300
301 #[inline]
303 #[must_use]
304 pub fn classify(self) -> Class {
305 match self {
306 OP_VERIF | OP_VERNOTIF | OP_INVALIDOPCODE => Class::IllegalOp,
307 #[rustfmt::skip]
308 OP_CAT | OP_SUBSTR
309 | OP_LEFT | OP_RIGHT
310 | OP_INVERT
311 | OP_AND | OP_OR | OP_XOR
312 | OP_2MUL | OP_2DIV
313 | OP_MUL | OP_DIV | OP_MOD
314 | OP_LSHIFT | OP_RSHIFT => Class::IllegalOp,
315 OP_NOP => Class::NoOp,
316 op if op.code >= OP_NOP1.code && op.code <= OP_NOP10.code => Class::NoOp,
317 OP_RETURN => Class::ReturnOp,
318 OP_RESERVED | OP_RESERVED1 | OP_RESERVED2 | OP_VER => Class::ReturnOp,
319 op if op.code >= OP_CHECKSIGADD.code => Class::IllegalOp,
320 OP_1NEGATE => Class::PushNum(-1),
321 op if op.code >= OP_1.code && op.code <= OP_16.code => {
322 Class::PushNum(1 + i32::from(self.code) - i32::from(OP_1.code))
323 }
324 op if op.code <= OP_PUSHBYTES_75.code => Class::PushBytes(u32::from(self.code)),
325 _ => Class::Ordinary(Ordinary::with(self)),
326 }
327 }
328
329 #[inline]
331 #[must_use]
332 pub const fn decode_pushnum(self) -> Option<u8> {
333 const START: u8 = OP_1.code;
334 const END: u8 = OP_16.code;
335 match self.code {
336 START..=END => Some(self.code - START + 1),
337 _ => None,
338 }
339 }
340}
341
342impl From<u8> for Opcode {
343 #[inline]
344 fn from(code: u8) -> Self {
345 Self { code }
346 }
347}
348
349impl fmt::Display for Opcode {
350 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
351 f.write_str(self.as_str())
352 }
353}
354
355impl fmt::Debug for Opcode {
356 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
357 fmt::Display::fmt(self, f)
358 }
359}
360
361#[cfg(feature = "serde")]
362impl serde::Serialize for Opcode {
363 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
364 where
365 S: serde::Serializer,
366 {
367 serializer.serialize_str(self.as_str())
368 }
369}
370
371pub mod all {
373 use super::Opcode;
374
375 macro_rules! opcode {
376 ($name:ident, $code:expr) => {
377 #[doc = concat!("Opcode `", stringify!($name), "`.")]
378 pub const $name: Opcode = Opcode { code: $code };
379 };
380 }
381
382 opcode!(OP_PUSHBYTES_0, 0x00);
383 opcode!(OP_PUSHBYTES_1, 0x01);
384 opcode!(OP_PUSHBYTES_2, 0x02);
385 opcode!(OP_PUSHBYTES_3, 0x03);
386 opcode!(OP_PUSHBYTES_4, 0x04);
387 opcode!(OP_PUSHBYTES_5, 0x05);
388 opcode!(OP_PUSHBYTES_6, 0x06);
389 opcode!(OP_PUSHBYTES_7, 0x07);
390 opcode!(OP_PUSHBYTES_8, 0x08);
391 opcode!(OP_PUSHBYTES_9, 0x09);
392 opcode!(OP_PUSHBYTES_10, 0x0a);
393 opcode!(OP_PUSHBYTES_11, 0x0b);
394 opcode!(OP_PUSHBYTES_12, 0x0c);
395 opcode!(OP_PUSHBYTES_13, 0x0d);
396 opcode!(OP_PUSHBYTES_14, 0x0e);
397 opcode!(OP_PUSHBYTES_15, 0x0f);
398 opcode!(OP_PUSHBYTES_16, 0x10);
399 opcode!(OP_PUSHBYTES_17, 0x11);
400 opcode!(OP_PUSHBYTES_18, 0x12);
401 opcode!(OP_PUSHBYTES_19, 0x13);
402 opcode!(OP_PUSHBYTES_20, 0x14);
403 opcode!(OP_PUSHBYTES_21, 0x15);
404 opcode!(OP_PUSHBYTES_22, 0x16);
405 opcode!(OP_PUSHBYTES_23, 0x17);
406 opcode!(OP_PUSHBYTES_24, 0x18);
407 opcode!(OP_PUSHBYTES_25, 0x19);
408 opcode!(OP_PUSHBYTES_26, 0x1a);
409 opcode!(OP_PUSHBYTES_27, 0x1b);
410 opcode!(OP_PUSHBYTES_28, 0x1c);
411 opcode!(OP_PUSHBYTES_29, 0x1d);
412 opcode!(OP_PUSHBYTES_30, 0x1e);
413 opcode!(OP_PUSHBYTES_31, 0x1f);
414 opcode!(OP_PUSHBYTES_32, 0x20);
415 opcode!(OP_PUSHBYTES_33, 0x21);
416 opcode!(OP_PUSHBYTES_34, 0x22);
417 opcode!(OP_PUSHBYTES_35, 0x23);
418 opcode!(OP_PUSHBYTES_36, 0x24);
419 opcode!(OP_PUSHBYTES_37, 0x25);
420 opcode!(OP_PUSHBYTES_38, 0x26);
421 opcode!(OP_PUSHBYTES_39, 0x27);
422 opcode!(OP_PUSHBYTES_40, 0x28);
423 opcode!(OP_PUSHBYTES_41, 0x29);
424 opcode!(OP_PUSHBYTES_42, 0x2a);
425 opcode!(OP_PUSHBYTES_43, 0x2b);
426 opcode!(OP_PUSHBYTES_44, 0x2c);
427 opcode!(OP_PUSHBYTES_45, 0x2d);
428 opcode!(OP_PUSHBYTES_46, 0x2e);
429 opcode!(OP_PUSHBYTES_47, 0x2f);
430 opcode!(OP_PUSHBYTES_48, 0x30);
431 opcode!(OP_PUSHBYTES_49, 0x31);
432 opcode!(OP_PUSHBYTES_50, 0x32);
433 opcode!(OP_PUSHBYTES_51, 0x33);
434 opcode!(OP_PUSHBYTES_52, 0x34);
435 opcode!(OP_PUSHBYTES_53, 0x35);
436 opcode!(OP_PUSHBYTES_54, 0x36);
437 opcode!(OP_PUSHBYTES_55, 0x37);
438 opcode!(OP_PUSHBYTES_56, 0x38);
439 opcode!(OP_PUSHBYTES_57, 0x39);
440 opcode!(OP_PUSHBYTES_58, 0x3a);
441 opcode!(OP_PUSHBYTES_59, 0x3b);
442 opcode!(OP_PUSHBYTES_60, 0x3c);
443 opcode!(OP_PUSHBYTES_61, 0x3d);
444 opcode!(OP_PUSHBYTES_62, 0x3e);
445 opcode!(OP_PUSHBYTES_63, 0x3f);
446 opcode!(OP_PUSHBYTES_64, 0x40);
447 opcode!(OP_PUSHBYTES_65, 0x41);
448 opcode!(OP_PUSHBYTES_66, 0x42);
449 opcode!(OP_PUSHBYTES_67, 0x43);
450 opcode!(OP_PUSHBYTES_68, 0x44);
451 opcode!(OP_PUSHBYTES_69, 0x45);
452 opcode!(OP_PUSHBYTES_70, 0x46);
453 opcode!(OP_PUSHBYTES_71, 0x47);
454 opcode!(OP_PUSHBYTES_72, 0x48);
455 opcode!(OP_PUSHBYTES_73, 0x49);
456 opcode!(OP_PUSHBYTES_74, 0x4a);
457 opcode!(OP_PUSHBYTES_75, 0x4b);
458 opcode!(OP_PUSHDATA1, 0x4c);
459 opcode!(OP_PUSHDATA2, 0x4d);
460 opcode!(OP_PUSHDATA4, 0x4e);
461 opcode!(OP_1NEGATE, 0x4f);
462 opcode!(OP_RESERVED, 0x50);
463 opcode!(OP_1, 0x51);
464 opcode!(OP_2, 0x52);
465 opcode!(OP_3, 0x53);
466 opcode!(OP_4, 0x54);
467 opcode!(OP_5, 0x55);
468 opcode!(OP_6, 0x56);
469 opcode!(OP_7, 0x57);
470 opcode!(OP_8, 0x58);
471 opcode!(OP_9, 0x59);
472 opcode!(OP_10, 0x5a);
473 opcode!(OP_11, 0x5b);
474 opcode!(OP_12, 0x5c);
475 opcode!(OP_13, 0x5d);
476 opcode!(OP_14, 0x5e);
477 opcode!(OP_15, 0x5f);
478 opcode!(OP_16, 0x60);
479 opcode!(OP_NOP, 0x61);
480 opcode!(OP_VER, 0x62);
481 opcode!(OP_IF, 0x63);
482 opcode!(OP_NOTIF, 0x64);
483 opcode!(OP_VERIF, 0x65);
484 opcode!(OP_VERNOTIF, 0x66);
485 opcode!(OP_ELSE, 0x67);
486 opcode!(OP_ENDIF, 0x68);
487 opcode!(OP_VERIFY, 0x69);
488 opcode!(OP_RETURN, 0x6a);
489 opcode!(OP_TOALTSTACK, 0x6b);
490 opcode!(OP_FROMALTSTACK, 0x6c);
491 opcode!(OP_2DROP, 0x6d);
492 opcode!(OP_2DUP, 0x6e);
493 opcode!(OP_3DUP, 0x6f);
494 opcode!(OP_2OVER, 0x70);
495 opcode!(OP_2ROT, 0x71);
496 opcode!(OP_2SWAP, 0x72);
497 opcode!(OP_IFDUP, 0x73);
498 opcode!(OP_DEPTH, 0x74);
499 opcode!(OP_DROP, 0x75);
500 opcode!(OP_DUP, 0x76);
501 opcode!(OP_NIP, 0x77);
502 opcode!(OP_OVER, 0x78);
503 opcode!(OP_PICK, 0x79);
504 opcode!(OP_ROLL, 0x7a);
505 opcode!(OP_ROT, 0x7b);
506 opcode!(OP_SWAP, 0x7c);
507 opcode!(OP_TUCK, 0x7d);
508 opcode!(OP_CAT, 0x7e);
509 opcode!(OP_SUBSTR, 0x7f);
510 opcode!(OP_LEFT, 0x80);
511 opcode!(OP_RIGHT, 0x81);
512 opcode!(OP_SIZE, 0x82);
513 opcode!(OP_INVERT, 0x83);
514 opcode!(OP_AND, 0x84);
515 opcode!(OP_OR, 0x85);
516 opcode!(OP_XOR, 0x86);
517 opcode!(OP_EQUAL, 0x87);
518 opcode!(OP_EQUALVERIFY, 0x88);
519 opcode!(OP_RESERVED1, 0x89);
520 opcode!(OP_RESERVED2, 0x8a);
521 opcode!(OP_1ADD, 0x8b);
522 opcode!(OP_1SUB, 0x8c);
523 opcode!(OP_2MUL, 0x8d);
524 opcode!(OP_2DIV, 0x8e);
525 opcode!(OP_NEGATE, 0x8f);
526 opcode!(OP_ABS, 0x90);
527 opcode!(OP_NOT, 0x91);
528 opcode!(OP_0NOTEQUAL, 0x92);
529 opcode!(OP_ADD, 0x93);
530 opcode!(OP_SUB, 0x94);
531 opcode!(OP_MUL, 0x95);
532 opcode!(OP_DIV, 0x96);
533 opcode!(OP_MOD, 0x97);
534 opcode!(OP_LSHIFT, 0x98);
535 opcode!(OP_RSHIFT, 0x99);
536 opcode!(OP_BOOLAND, 0x9a);
537 opcode!(OP_BOOLOR, 0x9b);
538 opcode!(OP_NUMEQUAL, 0x9c);
539 opcode!(OP_NUMEQUALVERIFY, 0x9d);
540 opcode!(OP_NUMNOTEQUAL, 0x9e);
541 opcode!(OP_LESSTHAN, 0x9f);
542 opcode!(OP_GREATERTHAN, 0xa0);
543 opcode!(OP_LESSTHANOREQUAL, 0xa1);
544 opcode!(OP_GREATERTHANOREQUAL, 0xa2);
545 opcode!(OP_MIN, 0xa3);
546 opcode!(OP_MAX, 0xa4);
547 opcode!(OP_WITHIN, 0xa5);
548 opcode!(OP_RIPEMD160, 0xa6);
549 opcode!(OP_SHA1, 0xa7);
550 opcode!(OP_SHA256, 0xa8);
551 opcode!(OP_HASH160, 0xa9);
552 opcode!(OP_HASH256, 0xaa);
553 opcode!(OP_CODESEPARATOR, 0xab);
554 opcode!(OP_CHECKSIG, 0xac);
555 opcode!(OP_CHECKSIGVERIFY, 0xad);
556 opcode!(OP_CHECKMULTISIG, 0xae);
557 opcode!(OP_CHECKMULTISIGVERIFY, 0xaf);
558 opcode!(OP_NOP1, 0xb0);
559 opcode!(OP_CLTV, 0xb1);
560 opcode!(OP_CSV, 0xb2);
561 opcode!(OP_SHA512, 0xb3);
562 opcode!(OP_NOP5, 0xb4);
563 opcode!(OP_NOP6, 0xb5);
564 opcode!(OP_NOP7, 0xb6);
565 opcode!(OP_NOP8, 0xb7);
566 opcode!(OP_NOP9, 0xb8);
567 opcode!(OP_NOP10, 0xb9);
568 opcode!(OP_CHECKSIGADD, 0xba);
569 opcode!(OP_RETURN_187, 0xbb);
570 opcode!(OP_RETURN_188, 0xbc);
571 opcode!(OP_RETURN_189, 0xbd);
572 opcode!(OP_RETURN_190, 0xbe);
573 opcode!(OP_RETURN_191, 0xbf);
574 opcode!(OP_RETURN_192, 0xc0);
575 opcode!(OP_RETURN_193, 0xc1);
576 opcode!(OP_RETURN_194, 0xc2);
577 opcode!(OP_RETURN_195, 0xc3);
578 opcode!(OP_RETURN_196, 0xc4);
579 opcode!(OP_RETURN_197, 0xc5);
580 opcode!(OP_RETURN_198, 0xc6);
581 opcode!(OP_RETURN_199, 0xc7);
582 opcode!(OP_RETURN_200, 0xc8);
583 opcode!(OP_RETURN_201, 0xc9);
584 opcode!(OP_RETURN_202, 0xca);
585 opcode!(OP_RETURN_203, 0xcb);
586 opcode!(OP_RETURN_204, 0xcc);
587 opcode!(OP_RETURN_205, 0xcd);
588 opcode!(OP_RETURN_206, 0xce);
589 opcode!(OP_RETURN_207, 0xcf);
590 opcode!(OP_RETURN_208, 0xd0);
591 opcode!(OP_RETURN_209, 0xd1);
592 opcode!(OP_RETURN_210, 0xd2);
593 opcode!(OP_RETURN_211, 0xd3);
594 opcode!(OP_RETURN_212, 0xd4);
595 opcode!(OP_RETURN_213, 0xd5);
596 opcode!(OP_RETURN_214, 0xd6);
597 opcode!(OP_RETURN_215, 0xd7);
598 opcode!(OP_RETURN_216, 0xd8);
599 opcode!(OP_RETURN_217, 0xd9);
600 opcode!(OP_RETURN_218, 0xda);
601 opcode!(OP_RETURN_219, 0xdb);
602 opcode!(OP_RETURN_220, 0xdc);
603 opcode!(OP_RETURN_221, 0xdd);
604 opcode!(OP_RETURN_222, 0xde);
605 opcode!(OP_RETURN_223, 0xdf);
606 opcode!(OP_RETURN_224, 0xe0);
607 opcode!(OP_RETURN_225, 0xe1);
608 opcode!(OP_RETURN_226, 0xe2);
609 opcode!(OP_RETURN_227, 0xe3);
610 opcode!(OP_RETURN_228, 0xe4);
611 opcode!(OP_RETURN_229, 0xe5);
612 opcode!(OP_RETURN_230, 0xe6);
613 opcode!(OP_RETURN_231, 0xe7);
614 opcode!(OP_RETURN_232, 0xe8);
615 opcode!(OP_RETURN_233, 0xe9);
616 opcode!(OP_RETURN_234, 0xea);
617 opcode!(OP_RETURN_235, 0xeb);
618 opcode!(OP_RETURN_236, 0xec);
619 opcode!(OP_RETURN_237, 0xed);
620 opcode!(OP_RETURN_238, 0xee);
621 opcode!(OP_RETURN_239, 0xef);
622 opcode!(OP_RETURN_240, 0xf0);
623 opcode!(OP_RETURN_241, 0xf1);
624 opcode!(OP_RETURN_242, 0xf2);
625 opcode!(OP_RETURN_243, 0xf3);
626 opcode!(OP_RETURN_244, 0xf4);
627 opcode!(OP_RETURN_245, 0xf5);
628 opcode!(OP_RETURN_246, 0xf6);
629 opcode!(OP_RETURN_247, 0xf7);
630 opcode!(OP_RETURN_248, 0xf8);
631 opcode!(OP_RETURN_249, 0xf9);
632 opcode!(OP_RETURN_250, 0xfa);
633 opcode!(OP_RETURN_251, 0xfb);
634 opcode!(OP_RETURN_252, 0xfc);
635 opcode!(OP_RETURN_253, 0xfd);
636 opcode!(OP_RETURN_254, 0xfe);
637 opcode!(OP_INVALIDOPCODE, 0xff);
638
639 #[allow(missing_docs)]
640 pub const OP_0: Opcode = OP_PUSHBYTES_0;
641 #[allow(missing_docs)]
642 pub const OP_FALSE: Opcode = OP_PUSHBYTES_0;
643 #[allow(missing_docs)]
644 pub const OP_TRUE: Opcode = OP_1;
645 #[allow(missing_docs)]
646 pub const OP_NOP2: Opcode = OP_CLTV;
647 #[allow(missing_docs)]
648 pub const OP_NOP3: Opcode = OP_CSV;
649 #[allow(missing_docs)]
650 pub const OP_NOP4: Opcode = OP_SHA512;
651 #[allow(missing_docs)]
652 pub const OP_PUSHNUM_NEG1: Opcode = OP_1NEGATE;
653 #[allow(missing_docs)]
654 pub const OP_PUSHNUM_1: Opcode = OP_1;
655 #[allow(missing_docs)]
656 pub const OP_PUSHNUM_2: Opcode = OP_2;
657 #[allow(missing_docs)]
658 pub const OP_PUSHNUM_3: Opcode = OP_3;
659 #[allow(missing_docs)]
660 pub const OP_PUSHNUM_4: Opcode = OP_4;
661 #[allow(missing_docs)]
662 pub const OP_PUSHNUM_5: Opcode = OP_5;
663 #[allow(missing_docs)]
664 pub const OP_PUSHNUM_6: Opcode = OP_6;
665 #[allow(missing_docs)]
666 pub const OP_PUSHNUM_7: Opcode = OP_7;
667 #[allow(missing_docs)]
668 pub const OP_PUSHNUM_8: Opcode = OP_8;
669 #[allow(missing_docs)]
670 pub const OP_PUSHNUM_9: Opcode = OP_9;
671 #[allow(missing_docs)]
672 pub const OP_PUSHNUM_10: Opcode = OP_10;
673 #[allow(missing_docs)]
674 pub const OP_PUSHNUM_11: Opcode = OP_11;
675 #[allow(missing_docs)]
676 pub const OP_PUSHNUM_12: Opcode = OP_12;
677 #[allow(missing_docs)]
678 pub const OP_PUSHNUM_13: Opcode = OP_13;
679 #[allow(missing_docs)]
680 pub const OP_PUSHNUM_14: Opcode = OP_14;
681 #[allow(missing_docs)]
682 pub const OP_PUSHNUM_15: Opcode = OP_15;
683 #[allow(missing_docs)]
684 pub const OP_PUSHNUM_16: Opcode = OP_16;
685}
686
687#[derive(Copy, Clone, PartialEq, Eq, Debug)]
689pub enum Class {
690 PushNum(i32),
692 PushBytes(u32),
694 ReturnOp,
696 IllegalOp,
698 NoOp,
700 Ordinary(Ordinary),
702}
703
704macro_rules! ordinary_opcode {
705 ($($op:ident),* $(,)?) => {
706 #[repr(u8)]
707 #[doc(hidden)]
708 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
709 pub enum Ordinary {
710 $( $op = all::$op.code ),*
711 }
712
713 impl fmt::Display for Ordinary {
714 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
715 match *self {
716 $(Self::$op => f.pad(stringify!($op))),*
717 }
718 }
719 }
720
721 impl Ordinary {
722 fn with(opcode: Opcode) -> Self {
723 match opcode {
724 $(all::$op => Self::$op),*,
725 _ => unreachable!("construction of `Ordinary` from non-ordinary opcode {}", opcode),
726 }
727 }
728
729 pub fn from_opcode(opcode: Opcode) -> Option<Self> {
731 match opcode {
732 $(all::$op => Some(Self::$op)),*,
733 _ => None,
734 }
735 }
736
737 #[inline]
739 pub fn to_u8(self) -> u8 { self as u8 }
740 }
741 };
742}
743
744ordinary_opcode! {
745 OP_PUSHDATA1, OP_PUSHDATA2, OP_PUSHDATA4,
746 OP_IF, OP_NOTIF, OP_ELSE, OP_ENDIF, OP_VERIFY,
747 OP_TOALTSTACK, OP_FROMALTSTACK,
748 OP_2DROP, OP_2DUP, OP_3DUP, OP_2OVER, OP_2ROT, OP_2SWAP,
749 OP_DROP, OP_DUP, OP_NIP, OP_OVER, OP_PICK, OP_ROLL, OP_ROT, OP_SWAP, OP_TUCK,
750 OP_IFDUP, OP_DEPTH, OP_SIZE,
751 OP_EQUAL, OP_EQUALVERIFY,
752 OP_1ADD, OP_1SUB, OP_NEGATE, OP_ABS, OP_NOT, OP_0NOTEQUAL,
753 OP_ADD, OP_SUB, OP_BOOLAND, OP_BOOLOR,
754 OP_NUMEQUAL, OP_NUMEQUALVERIFY, OP_NUMNOTEQUAL, OP_LESSTHAN,
755 OP_GREATERTHAN, OP_LESSTHANOREQUAL, OP_GREATERTHANOREQUAL,
756 OP_MIN, OP_MAX, OP_WITHIN,
757 OP_RIPEMD160, OP_SHA1, OP_SHA256, OP_HASH160, OP_HASH256,
758 OP_CODESEPARATOR, OP_CHECKSIG, OP_CHECKSIGVERIFY,
759 OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY,
760}
761
762pub const OP_PUSHDATA1: u8 = 0x4c;
764pub const OP_PUSHDATA2: u8 = 0x4d;
766pub const OP_PUSHDATA4: u8 = 0x4e;
768
769pub fn fmt_opcode(op: u8, f: &mut fmt::Formatter<'_>) -> fmt::Result {
775 match op {
776 0x00 => f.write_str("OP_0"),
777 0x01..=0x4b => write!(f, "OP_PUSHBYTES_{}", op),
778 0x4c => f.write_str("OP_PUSHDATA1"),
779 0x4d => f.write_str("OP_PUSHDATA2"),
780 0x4e => f.write_str("OP_PUSHDATA4"),
781 0x4f => f.write_str("OP_1NEGATE"),
782 0x50 => f.write_str("OP_RESERVED"),
783 0x51..=0x60 => write!(f, "OP_{}", op - 0x50),
784 0xb3 => f.write_str("OP_SHA512"),
785 other => write!(f, "{}", Opcode::from(other)),
786 }
787}