Skip to main content

tidecoin_primitives/
opcodes.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Tidecoin script opcodes.
4
5#![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/// A script opcode.
167#[derive(Copy, Clone, PartialEq, Eq, Hash)]
168pub struct Opcode {
169    code: u8,
170}
171
172impl Opcode {
173    /// Returns the raw opcode byte.
174    #[inline]
175    pub const fn to_u8(self) -> u8 {
176        self.code
177    }
178
179    /// Returns the opcode display name.
180    #[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    /// Classifies an opcode into a broad execution class.
302    #[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    /// Decodes a PUSHNUM opcode to its numeric value.
330    #[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
371/// Enables wildcard imports to bring into scope only opcode constants.
372pub 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/// Broad categories of opcodes with similar execution behavior.
688#[derive(Copy, Clone, PartialEq, Eq, Debug)]
689pub enum Class {
690    /// Pushes the given number onto the stack.
691    PushNum(i32),
692    /// Pushes the given number of bytes onto the stack.
693    PushBytes(u32),
694    /// Fails the script if executed.
695    ReturnOp,
696    /// Fails the script even if not executed.
697    IllegalOp,
698    /// Does nothing.
699    NoOp,
700    /// Any opcode not covered above.
701    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            /// Constructs an [`Ordinary`] opcode from a generic [`Opcode`].
730            pub fn from_opcode(opcode: Opcode) -> Option<Self> {
731                match opcode {
732                    $(all::$op => Some(Self::$op)),*,
733                    _ => None,
734                }
735            }
736
737            /// Encodes this opcode as a byte.
738            #[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
762/// Read the following byte as a pushdata length.
763pub const OP_PUSHDATA1: u8 = 0x4c;
764/// Read the following two bytes as a pushdata length.
765pub const OP_PUSHDATA2: u8 = 0x4d;
766/// Read the following four bytes as a pushdata length.
767pub const OP_PUSHDATA4: u8 = 0x4e;
768
769/// Format a byte as a script opcode.
770///
771/// # Errors
772///
773/// Returns any formatter error from `f`.
774pub 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}