1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10#[repr(u8)]
11#[allow(non_camel_case_types)]
12pub enum Op {
13 Op0 = 0x00,
15 OpPushData1 = 0x4c,
16 OpPushData2 = 0x4d,
17 OpPushData4 = 0x4e,
18 Op1Negate = 0x4f,
19 OpReserved = 0x50,
20 Op1 = 0x51,
21 Op2 = 0x52,
22 Op3 = 0x53,
23 Op4 = 0x54,
24 Op5 = 0x55,
25 Op6 = 0x56,
26 Op7 = 0x57,
27 Op8 = 0x58,
28 Op9 = 0x59,
29 Op10 = 0x5a,
30 Op11 = 0x5b,
31 Op12 = 0x5c,
32 Op13 = 0x5d,
33 Op14 = 0x5e,
34 Op15 = 0x5f,
35 Op16 = 0x60,
36
37 OpNop = 0x61,
39 OpVer = 0x62,
40 OpIf = 0x63,
41 OpNotIf = 0x64,
42 OpVerIf = 0x65,
43 OpVerNotIf = 0x66,
44 OpElse = 0x67,
45 OpEndIf = 0x68,
46 OpVerify = 0x69,
47 OpReturn = 0x6a,
48
49 OpToAltStack = 0x6b,
51 OpFromAltStack = 0x6c,
52 Op2Drop = 0x6d,
53 Op2Dup = 0x6e,
54 Op3Dup = 0x6f,
55 Op2Over = 0x70,
56 Op2Rot = 0x71,
57 Op2Swap = 0x72,
58 OpIfDup = 0x73,
59 OpDepth = 0x74,
60 OpDrop = 0x75,
61 OpDup = 0x76,
62 OpNip = 0x77,
63 OpOver = 0x78,
64 OpPick = 0x79,
65 OpRoll = 0x7a,
66 OpRot = 0x7b,
67 OpSwap = 0x7c,
68 OpTuck = 0x7d,
69
70 OpCat = 0x7e,
72 OpSplit = 0x7f,
73 OpNum2Bin = 0x80,
74 OpBin2Num = 0x81,
75 OpSize = 0x82,
76
77 OpInvert = 0x83,
79 OpAnd = 0x84,
80 OpOr = 0x85,
81 OpXor = 0x86,
82 OpEqual = 0x87,
83 OpEqualVerify = 0x88,
84 OpReserved1 = 0x89,
85 OpReserved2 = 0x8a,
86
87 Op1Add = 0x8b,
89 Op1Sub = 0x8c,
90 Op2Mul = 0x8d,
91 Op2Div = 0x8e,
92 OpNegate = 0x8f,
93 OpAbs = 0x90,
94 OpNot = 0x91,
95 Op0NotEqual = 0x92,
96 OpAdd = 0x93,
97 OpSub = 0x94,
98 OpMul = 0x95,
99 OpDiv = 0x96,
100 OpMod = 0x97,
101 OpLShift = 0x98,
102 OpRShift = 0x99,
103 OpBoolAnd = 0x9a,
104 OpBoolOr = 0x9b,
105 OpNumEqual = 0x9c,
106 OpNumEqualVerify = 0x9d,
107 OpNumNotEqual = 0x9e,
108 OpLessThan = 0x9f,
109 OpGreaterThan = 0xa0,
110 OpLessThanOrEqual = 0xa1,
111 OpGreaterThanOrEqual = 0xa2,
112 OpMin = 0xa3,
113 OpMax = 0xa4,
114 OpWithin = 0xa5,
115
116 OpRipemd160 = 0xa6,
118 OpSha1 = 0xa7,
119 OpSha256 = 0xa8,
120 OpHash160 = 0xa9,
121 OpHash256 = 0xaa,
122 OpCodeSeparator = 0xab,
123 OpCheckSig = 0xac,
124 OpCheckSigVerify = 0xad,
125 OpCheckMultiSig = 0xae,
126 OpCheckMultiSigVerify = 0xaf,
127
128 OpNop1 = 0xb0,
130 OpNop2 = 0xb1,
131 OpNop3 = 0xb2,
132 OpSubstr = 0xb3,
134 OpLeft = 0xb4,
135 OpRight = 0xb5,
136 OpLShiftNum = 0xb6,
137 OpRShiftNum = 0xb7,
138 OpNop9 = 0xb8,
139 OpNop10 = 0xb9,
140 OpNop11 = 0xba,
141 OpNop12 = 0xbb,
142 OpNop13 = 0xbc,
143 OpNop14 = 0xbd,
144 OpNop15 = 0xbe,
145 OpNop16 = 0xbf,
146 OpNop17 = 0xc0,
147 OpNop18 = 0xc1,
148 OpNop19 = 0xc2,
149 OpNop20 = 0xc3,
150 OpNop21 = 0xc4,
151 OpNop22 = 0xc5,
152 OpNop23 = 0xc6,
153 OpNop24 = 0xc7,
154 OpNop25 = 0xc8,
155 OpNop26 = 0xc9,
156 OpNop27 = 0xca,
157 OpNop28 = 0xcb,
158 OpNop29 = 0xcc,
159 OpNop30 = 0xcd,
160 OpNop31 = 0xce,
161 OpNop32 = 0xcf,
162 OpNop33 = 0xd0,
163 OpNop34 = 0xd1,
164 OpNop35 = 0xd2,
165 OpNop36 = 0xd3,
166 OpNop37 = 0xd4,
167 OpNop38 = 0xd5,
168 OpNop39 = 0xd6,
169 OpNop40 = 0xd7,
170 OpNop41 = 0xd8,
171 OpNop42 = 0xd9,
172 OpNop43 = 0xda,
173 OpNop44 = 0xdb,
174 OpNop45 = 0xdc,
175 OpNop46 = 0xdd,
176 OpNop47 = 0xde,
177 OpNop48 = 0xdf,
178 OpNop49 = 0xe0,
179 OpNop50 = 0xe1,
180 OpNop51 = 0xe2,
181 OpNop52 = 0xe3,
182 OpNop53 = 0xe4,
183 OpNop54 = 0xe5,
184 OpNop55 = 0xe6,
185 OpNop56 = 0xe7,
186 OpNop57 = 0xe8,
187 OpNop58 = 0xe9,
188 OpNop59 = 0xea,
189 OpNop60 = 0xeb,
190 OpNop61 = 0xec,
191 OpNop62 = 0xed,
192 OpNop63 = 0xee,
193 OpNop64 = 0xef,
194 OpNop65 = 0xf0,
195 OpNop66 = 0xf1,
196 OpNop67 = 0xf2,
197 OpNop68 = 0xf3,
198 OpNop69 = 0xf4,
199 OpNop70 = 0xf5,
200 OpNop71 = 0xf6,
201 OpNop72 = 0xf7,
202 OpNop73 = 0xf8,
203
204 OpSmallData = 0xf9,
206 OpSmallInteger = 0xfa,
207 OpPubKeys = 0xfb,
208 OpNop77 = 0xfc,
209 OpPubKeyHash = 0xfd,
210 OpPubKey = 0xfe,
211
212 OpInvalidOpcode = 0xff,
213}
214
215impl Op {
216 pub fn to_name(&self) -> &'static str {
218 match self {
219 Op::Op0 => "OP_0",
220 Op::OpPushData1 => "OP_PUSHDATA1",
221 Op::OpPushData2 => "OP_PUSHDATA2",
222 Op::OpPushData4 => "OP_PUSHDATA4",
223 Op::Op1Negate => "OP_1NEGATE",
224 Op::OpReserved => "OP_RESERVED",
225 Op::Op1 => "OP_1",
226 Op::Op2 => "OP_2",
227 Op::Op3 => "OP_3",
228 Op::Op4 => "OP_4",
229 Op::Op5 => "OP_5",
230 Op::Op6 => "OP_6",
231 Op::Op7 => "OP_7",
232 Op::Op8 => "OP_8",
233 Op::Op9 => "OP_9",
234 Op::Op10 => "OP_10",
235 Op::Op11 => "OP_11",
236 Op::Op12 => "OP_12",
237 Op::Op13 => "OP_13",
238 Op::Op14 => "OP_14",
239 Op::Op15 => "OP_15",
240 Op::Op16 => "OP_16",
241 Op::OpNop => "OP_NOP",
242 Op::OpVer => "OP_VER",
243 Op::OpIf => "OP_IF",
244 Op::OpNotIf => "OP_NOTIF",
245 Op::OpVerIf => "OP_VERIF",
246 Op::OpVerNotIf => "OP_VERNOTIF",
247 Op::OpElse => "OP_ELSE",
248 Op::OpEndIf => "OP_ENDIF",
249 Op::OpVerify => "OP_VERIFY",
250 Op::OpReturn => "OP_RETURN",
251 Op::OpToAltStack => "OP_TOALTSTACK",
252 Op::OpFromAltStack => "OP_FROMALTSTACK",
253 Op::Op2Drop => "OP_2DROP",
254 Op::Op2Dup => "OP_2DUP",
255 Op::Op3Dup => "OP_3DUP",
256 Op::Op2Over => "OP_2OVER",
257 Op::Op2Rot => "OP_2ROT",
258 Op::Op2Swap => "OP_2SWAP",
259 Op::OpIfDup => "OP_IFDUP",
260 Op::OpDepth => "OP_DEPTH",
261 Op::OpDrop => "OP_DROP",
262 Op::OpDup => "OP_DUP",
263 Op::OpNip => "OP_NIP",
264 Op::OpOver => "OP_OVER",
265 Op::OpPick => "OP_PICK",
266 Op::OpRoll => "OP_ROLL",
267 Op::OpRot => "OP_ROT",
268 Op::OpSwap => "OP_SWAP",
269 Op::OpTuck => "OP_TUCK",
270 Op::OpCat => "OP_CAT",
271 Op::OpSplit => "OP_SPLIT",
272 Op::OpNum2Bin => "OP_NUM2BIN",
273 Op::OpBin2Num => "OP_BIN2NUM",
274 Op::OpSize => "OP_SIZE",
275 Op::OpInvert => "OP_INVERT",
276 Op::OpAnd => "OP_AND",
277 Op::OpOr => "OP_OR",
278 Op::OpXor => "OP_XOR",
279 Op::OpEqual => "OP_EQUAL",
280 Op::OpEqualVerify => "OP_EQUALVERIFY",
281 Op::OpReserved1 => "OP_RESERVED1",
282 Op::OpReserved2 => "OP_RESERVED2",
283 Op::Op1Add => "OP_1ADD",
284 Op::Op1Sub => "OP_1SUB",
285 Op::Op2Mul => "OP_2MUL",
286 Op::Op2Div => "OP_2DIV",
287 Op::OpNegate => "OP_NEGATE",
288 Op::OpAbs => "OP_ABS",
289 Op::OpNot => "OP_NOT",
290 Op::Op0NotEqual => "OP_0NOTEQUAL",
291 Op::OpAdd => "OP_ADD",
292 Op::OpSub => "OP_SUB",
293 Op::OpMul => "OP_MUL",
294 Op::OpDiv => "OP_DIV",
295 Op::OpMod => "OP_MOD",
296 Op::OpLShift => "OP_LSHIFT",
297 Op::OpRShift => "OP_RSHIFT",
298 Op::OpBoolAnd => "OP_BOOLAND",
299 Op::OpBoolOr => "OP_BOOLOR",
300 Op::OpNumEqual => "OP_NUMEQUAL",
301 Op::OpNumEqualVerify => "OP_NUMEQUALVERIFY",
302 Op::OpNumNotEqual => "OP_NUMNOTEQUAL",
303 Op::OpLessThan => "OP_LESSTHAN",
304 Op::OpGreaterThan => "OP_GREATERTHAN",
305 Op::OpLessThanOrEqual => "OP_LESSTHANOREQUAL",
306 Op::OpGreaterThanOrEqual => "OP_GREATERTHANOREQUAL",
307 Op::OpMin => "OP_MIN",
308 Op::OpMax => "OP_MAX",
309 Op::OpWithin => "OP_WITHIN",
310 Op::OpRipemd160 => "OP_RIPEMD160",
311 Op::OpSha1 => "OP_SHA1",
312 Op::OpSha256 => "OP_SHA256",
313 Op::OpHash160 => "OP_HASH160",
314 Op::OpHash256 => "OP_HASH256",
315 Op::OpCodeSeparator => "OP_CODESEPARATOR",
316 Op::OpCheckSig => "OP_CHECKSIG",
317 Op::OpCheckSigVerify => "OP_CHECKSIGVERIFY",
318 Op::OpCheckMultiSig => "OP_CHECKMULTISIG",
319 Op::OpCheckMultiSigVerify => "OP_CHECKMULTISIGVERIFY",
320 Op::OpNop1 => "OP_NOP1",
321 Op::OpNop2 => "OP_NOP2",
322 Op::OpNop3 => "OP_NOP3",
323 Op::OpSubstr => "OP_SUBSTR",
324 Op::OpLeft => "OP_LEFT",
325 Op::OpRight => "OP_RIGHT",
326 Op::OpLShiftNum => "OP_LSHIFTNUM",
327 Op::OpRShiftNum => "OP_RSHIFTNUM",
328 Op::OpNop9 => "OP_NOP9",
329 Op::OpNop10 => "OP_NOP10",
330 Op::OpNop11 => "OP_NOP11",
331 Op::OpNop12 => "OP_NOP12",
332 Op::OpNop13 => "OP_NOP13",
333 Op::OpNop14 => "OP_NOP14",
334 Op::OpNop15 => "OP_NOP15",
335 Op::OpNop16 => "OP_NOP16",
336 Op::OpNop17 => "OP_NOP17",
337 Op::OpNop18 => "OP_NOP18",
338 Op::OpNop19 => "OP_NOP19",
339 Op::OpNop20 => "OP_NOP20",
340 Op::OpNop21 => "OP_NOP21",
341 Op::OpNop22 => "OP_NOP22",
342 Op::OpNop23 => "OP_NOP23",
343 Op::OpNop24 => "OP_NOP24",
344 Op::OpNop25 => "OP_NOP25",
345 Op::OpNop26 => "OP_NOP26",
346 Op::OpNop27 => "OP_NOP27",
347 Op::OpNop28 => "OP_NOP28",
348 Op::OpNop29 => "OP_NOP29",
349 Op::OpNop30 => "OP_NOP30",
350 Op::OpNop31 => "OP_NOP31",
351 Op::OpNop32 => "OP_NOP32",
352 Op::OpNop33 => "OP_NOP33",
353 Op::OpNop34 => "OP_NOP34",
354 Op::OpNop35 => "OP_NOP35",
355 Op::OpNop36 => "OP_NOP36",
356 Op::OpNop37 => "OP_NOP37",
357 Op::OpNop38 => "OP_NOP38",
358 Op::OpNop39 => "OP_NOP39",
359 Op::OpNop40 => "OP_NOP40",
360 Op::OpNop41 => "OP_NOP41",
361 Op::OpNop42 => "OP_NOP42",
362 Op::OpNop43 => "OP_NOP43",
363 Op::OpNop44 => "OP_NOP44",
364 Op::OpNop45 => "OP_NOP45",
365 Op::OpNop46 => "OP_NOP46",
366 Op::OpNop47 => "OP_NOP47",
367 Op::OpNop48 => "OP_NOP48",
368 Op::OpNop49 => "OP_NOP49",
369 Op::OpNop50 => "OP_NOP50",
370 Op::OpNop51 => "OP_NOP51",
371 Op::OpNop52 => "OP_NOP52",
372 Op::OpNop53 => "OP_NOP53",
373 Op::OpNop54 => "OP_NOP54",
374 Op::OpNop55 => "OP_NOP55",
375 Op::OpNop56 => "OP_NOP56",
376 Op::OpNop57 => "OP_NOP57",
377 Op::OpNop58 => "OP_NOP58",
378 Op::OpNop59 => "OP_NOP59",
379 Op::OpNop60 => "OP_NOP60",
380 Op::OpNop61 => "OP_NOP61",
381 Op::OpNop62 => "OP_NOP62",
382 Op::OpNop63 => "OP_NOP63",
383 Op::OpNop64 => "OP_NOP64",
384 Op::OpNop65 => "OP_NOP65",
385 Op::OpNop66 => "OP_NOP66",
386 Op::OpNop67 => "OP_NOP67",
387 Op::OpNop68 => "OP_NOP68",
388 Op::OpNop69 => "OP_NOP69",
389 Op::OpNop70 => "OP_NOP70",
390 Op::OpNop71 => "OP_NOP71",
391 Op::OpNop72 => "OP_NOP72",
392 Op::OpNop73 => "OP_NOP73",
393 Op::OpSmallData => "OP_SMALLDATA",
394 Op::OpSmallInteger => "OP_SMALLINTEGER",
395 Op::OpPubKeys => "OP_PUBKEYS",
396 Op::OpNop77 => "OP_NOP77",
397 Op::OpPubKeyHash => "OP_PUBKEYHASH",
398 Op::OpPubKey => "OP_PUBKEY",
399 Op::OpInvalidOpcode => "OP_INVALIDOPCODE",
400 }
401 }
402
403 pub fn to_byte(&self) -> u8 {
405 *self as u8
406 }
407
408 pub fn from_name(name: &str) -> Option<Op> {
412 match name {
413 "OP_0" | "OP_FALSE" => Some(Op::Op0),
414 "OP_PUSHDATA1" => Some(Op::OpPushData1),
415 "OP_PUSHDATA2" => Some(Op::OpPushData2),
416 "OP_PUSHDATA4" => Some(Op::OpPushData4),
417 "OP_1NEGATE" => Some(Op::Op1Negate),
418 "OP_RESERVED" => Some(Op::OpReserved),
419 "OP_1" | "OP_TRUE" => Some(Op::Op1),
420 "OP_2" => Some(Op::Op2),
421 "OP_3" => Some(Op::Op3),
422 "OP_4" => Some(Op::Op4),
423 "OP_5" => Some(Op::Op5),
424 "OP_6" => Some(Op::Op6),
425 "OP_7" => Some(Op::Op7),
426 "OP_8" => Some(Op::Op8),
427 "OP_9" => Some(Op::Op9),
428 "OP_10" => Some(Op::Op10),
429 "OP_11" => Some(Op::Op11),
430 "OP_12" => Some(Op::Op12),
431 "OP_13" => Some(Op::Op13),
432 "OP_14" => Some(Op::Op14),
433 "OP_15" => Some(Op::Op15),
434 "OP_16" => Some(Op::Op16),
435 "OP_NOP" => Some(Op::OpNop),
436 "OP_VER" => Some(Op::OpVer),
437 "OP_IF" => Some(Op::OpIf),
438 "OP_NOTIF" => Some(Op::OpNotIf),
439 "OP_VERIF" => Some(Op::OpVerIf),
440 "OP_VERNOTIF" => Some(Op::OpVerNotIf),
441 "OP_ELSE" => Some(Op::OpElse),
442 "OP_ENDIF" => Some(Op::OpEndIf),
443 "OP_VERIFY" => Some(Op::OpVerify),
444 "OP_RETURN" => Some(Op::OpReturn),
445 "OP_TOALTSTACK" => Some(Op::OpToAltStack),
446 "OP_FROMALTSTACK" => Some(Op::OpFromAltStack),
447 "OP_2DROP" => Some(Op::Op2Drop),
448 "OP_2DUP" => Some(Op::Op2Dup),
449 "OP_3DUP" => Some(Op::Op3Dup),
450 "OP_2OVER" => Some(Op::Op2Over),
451 "OP_2ROT" => Some(Op::Op2Rot),
452 "OP_2SWAP" => Some(Op::Op2Swap),
453 "OP_IFDUP" => Some(Op::OpIfDup),
454 "OP_DEPTH" => Some(Op::OpDepth),
455 "OP_DROP" => Some(Op::OpDrop),
456 "OP_DUP" => Some(Op::OpDup),
457 "OP_NIP" => Some(Op::OpNip),
458 "OP_OVER" => Some(Op::OpOver),
459 "OP_PICK" => Some(Op::OpPick),
460 "OP_ROLL" => Some(Op::OpRoll),
461 "OP_ROT" => Some(Op::OpRot),
462 "OP_SWAP" => Some(Op::OpSwap),
463 "OP_TUCK" => Some(Op::OpTuck),
464 "OP_CAT" => Some(Op::OpCat),
465 "OP_SPLIT" => Some(Op::OpSplit),
466 "OP_NUM2BIN" => Some(Op::OpNum2Bin),
467 "OP_BIN2NUM" => Some(Op::OpBin2Num),
468 "OP_SIZE" => Some(Op::OpSize),
469 "OP_INVERT" => Some(Op::OpInvert),
470 "OP_AND" => Some(Op::OpAnd),
471 "OP_OR" => Some(Op::OpOr),
472 "OP_XOR" => Some(Op::OpXor),
473 "OP_EQUAL" => Some(Op::OpEqual),
474 "OP_EQUALVERIFY" => Some(Op::OpEqualVerify),
475 "OP_RESERVED1" => Some(Op::OpReserved1),
476 "OP_RESERVED2" => Some(Op::OpReserved2),
477 "OP_1ADD" => Some(Op::Op1Add),
478 "OP_1SUB" => Some(Op::Op1Sub),
479 "OP_2MUL" => Some(Op::Op2Mul),
480 "OP_2DIV" => Some(Op::Op2Div),
481 "OP_NEGATE" => Some(Op::OpNegate),
482 "OP_ABS" => Some(Op::OpAbs),
483 "OP_NOT" => Some(Op::OpNot),
484 "OP_0NOTEQUAL" => Some(Op::Op0NotEqual),
485 "OP_ADD" => Some(Op::OpAdd),
486 "OP_SUB" => Some(Op::OpSub),
487 "OP_MUL" => Some(Op::OpMul),
488 "OP_DIV" => Some(Op::OpDiv),
489 "OP_MOD" => Some(Op::OpMod),
490 "OP_LSHIFT" => Some(Op::OpLShift),
491 "OP_RSHIFT" => Some(Op::OpRShift),
492 "OP_BOOLAND" => Some(Op::OpBoolAnd),
493 "OP_BOOLOR" => Some(Op::OpBoolOr),
494 "OP_NUMEQUAL" => Some(Op::OpNumEqual),
495 "OP_NUMEQUALVERIFY" => Some(Op::OpNumEqualVerify),
496 "OP_NUMNOTEQUAL" => Some(Op::OpNumNotEqual),
497 "OP_LESSTHAN" => Some(Op::OpLessThan),
498 "OP_GREATERTHAN" => Some(Op::OpGreaterThan),
499 "OP_LESSTHANOREQUAL" => Some(Op::OpLessThanOrEqual),
500 "OP_GREATERTHANOREQUAL" => Some(Op::OpGreaterThanOrEqual),
501 "OP_MIN" => Some(Op::OpMin),
502 "OP_MAX" => Some(Op::OpMax),
503 "OP_WITHIN" => Some(Op::OpWithin),
504 "OP_RIPEMD160" => Some(Op::OpRipemd160),
505 "OP_SHA1" => Some(Op::OpSha1),
506 "OP_SHA256" => Some(Op::OpSha256),
507 "OP_HASH160" => Some(Op::OpHash160),
508 "OP_HASH256" => Some(Op::OpHash256),
509 "OP_CODESEPARATOR" => Some(Op::OpCodeSeparator),
510 "OP_CHECKSIG" => Some(Op::OpCheckSig),
511 "OP_CHECKSIGVERIFY" => Some(Op::OpCheckSigVerify),
512 "OP_CHECKMULTISIG" => Some(Op::OpCheckMultiSig),
513 "OP_CHECKMULTISIGVERIFY" => Some(Op::OpCheckMultiSigVerify),
514 "OP_NOP1" => Some(Op::OpNop1),
515 "OP_NOP2" => Some(Op::OpNop2),
516 "OP_NOP3" => Some(Op::OpNop3),
517 "OP_NOP4" | "OP_SUBSTR" => Some(Op::OpSubstr),
518 "OP_NOP5" | "OP_LEFT" => Some(Op::OpLeft),
519 "OP_NOP6" | "OP_RIGHT" => Some(Op::OpRight),
520 "OP_NOP7" | "OP_LSHIFTNUM" => Some(Op::OpLShiftNum),
521 "OP_NOP8" | "OP_RSHIFTNUM" => Some(Op::OpRShiftNum),
522 "OP_INVALIDOPCODE" => Some(Op::OpInvalidOpcode),
523 _ => {
524 if let Some(suffix) = name.strip_prefix("OP_NOP") {
526 if let Ok(n) = suffix.parse::<u8>() {
527 return Some(Op::from(0xb8 + n.saturating_sub(9)));
528 }
529 }
530 None
531 }
532 }
533 }
534}
535
536impl From<u8> for Op {
537 fn from(byte: u8) -> Self {
538 match byte {
539 0x00 => Op::Op0,
540 0x4c => Op::OpPushData1,
545 0x4d => Op::OpPushData2,
546 0x4e => Op::OpPushData4,
547 0x4f => Op::Op1Negate,
548 0x50 => Op::OpReserved,
549 0x51 => Op::Op1,
550 0x52 => Op::Op2,
551 0x53 => Op::Op3,
552 0x54 => Op::Op4,
553 0x55 => Op::Op5,
554 0x56 => Op::Op6,
555 0x57 => Op::Op7,
556 0x58 => Op::Op8,
557 0x59 => Op::Op9,
558 0x5a => Op::Op10,
559 0x5b => Op::Op11,
560 0x5c => Op::Op12,
561 0x5d => Op::Op13,
562 0x5e => Op::Op14,
563 0x5f => Op::Op15,
564 0x60 => Op::Op16,
565 0x61 => Op::OpNop,
566 0x62 => Op::OpVer,
567 0x63 => Op::OpIf,
568 0x64 => Op::OpNotIf,
569 0x65 => Op::OpVerIf,
570 0x66 => Op::OpVerNotIf,
571 0x67 => Op::OpElse,
572 0x68 => Op::OpEndIf,
573 0x69 => Op::OpVerify,
574 0x6a => Op::OpReturn,
575 0x6b => Op::OpToAltStack,
576 0x6c => Op::OpFromAltStack,
577 0x6d => Op::Op2Drop,
578 0x6e => Op::Op2Dup,
579 0x6f => Op::Op3Dup,
580 0x70 => Op::Op2Over,
581 0x71 => Op::Op2Rot,
582 0x72 => Op::Op2Swap,
583 0x73 => Op::OpIfDup,
584 0x74 => Op::OpDepth,
585 0x75 => Op::OpDrop,
586 0x76 => Op::OpDup,
587 0x77 => Op::OpNip,
588 0x78 => Op::OpOver,
589 0x79 => Op::OpPick,
590 0x7a => Op::OpRoll,
591 0x7b => Op::OpRot,
592 0x7c => Op::OpSwap,
593 0x7d => Op::OpTuck,
594 0x7e => Op::OpCat,
595 0x7f => Op::OpSplit,
596 0x80 => Op::OpNum2Bin,
597 0x81 => Op::OpBin2Num,
598 0x82 => Op::OpSize,
599 0x83 => Op::OpInvert,
600 0x84 => Op::OpAnd,
601 0x85 => Op::OpOr,
602 0x86 => Op::OpXor,
603 0x87 => Op::OpEqual,
604 0x88 => Op::OpEqualVerify,
605 0x89 => Op::OpReserved1,
606 0x8a => Op::OpReserved2,
607 0x8b => Op::Op1Add,
608 0x8c => Op::Op1Sub,
609 0x8d => Op::Op2Mul,
610 0x8e => Op::Op2Div,
611 0x8f => Op::OpNegate,
612 0x90 => Op::OpAbs,
613 0x91 => Op::OpNot,
614 0x92 => Op::Op0NotEqual,
615 0x93 => Op::OpAdd,
616 0x94 => Op::OpSub,
617 0x95 => Op::OpMul,
618 0x96 => Op::OpDiv,
619 0x97 => Op::OpMod,
620 0x98 => Op::OpLShift,
621 0x99 => Op::OpRShift,
622 0x9a => Op::OpBoolAnd,
623 0x9b => Op::OpBoolOr,
624 0x9c => Op::OpNumEqual,
625 0x9d => Op::OpNumEqualVerify,
626 0x9e => Op::OpNumNotEqual,
627 0x9f => Op::OpLessThan,
628 0xa0 => Op::OpGreaterThan,
629 0xa1 => Op::OpLessThanOrEqual,
630 0xa2 => Op::OpGreaterThanOrEqual,
631 0xa3 => Op::OpMin,
632 0xa4 => Op::OpMax,
633 0xa5 => Op::OpWithin,
634 0xa6 => Op::OpRipemd160,
635 0xa7 => Op::OpSha1,
636 0xa8 => Op::OpSha256,
637 0xa9 => Op::OpHash160,
638 0xaa => Op::OpHash256,
639 0xab => Op::OpCodeSeparator,
640 0xac => Op::OpCheckSig,
641 0xad => Op::OpCheckSigVerify,
642 0xae => Op::OpCheckMultiSig,
643 0xaf => Op::OpCheckMultiSigVerify,
644 0xb0 => Op::OpNop1,
645 0xb1 => Op::OpNop2,
646 0xb2 => Op::OpNop3,
647 0xb3 => Op::OpSubstr,
648 0xb4 => Op::OpLeft,
649 0xb5 => Op::OpRight,
650 0xb6 => Op::OpLShiftNum,
651 0xb7 => Op::OpRShiftNum,
652 0xb8 => Op::OpNop9,
653 0xb9 => Op::OpNop10,
654 0xba => Op::OpNop11,
655 0xbb => Op::OpNop12,
656 0xbc => Op::OpNop13,
657 0xbd => Op::OpNop14,
658 0xbe => Op::OpNop15,
659 0xbf => Op::OpNop16,
660 0xc0 => Op::OpNop17,
661 0xc1 => Op::OpNop18,
662 0xc2 => Op::OpNop19,
663 0xc3 => Op::OpNop20,
664 0xc4 => Op::OpNop21,
665 0xc5 => Op::OpNop22,
666 0xc6 => Op::OpNop23,
667 0xc7 => Op::OpNop24,
668 0xc8 => Op::OpNop25,
669 0xc9 => Op::OpNop26,
670 0xca => Op::OpNop27,
671 0xcb => Op::OpNop28,
672 0xcc => Op::OpNop29,
673 0xcd => Op::OpNop30,
674 0xce => Op::OpNop31,
675 0xcf => Op::OpNop32,
676 0xd0 => Op::OpNop33,
677 0xd1 => Op::OpNop34,
678 0xd2 => Op::OpNop35,
679 0xd3 => Op::OpNop36,
680 0xd4 => Op::OpNop37,
681 0xd5 => Op::OpNop38,
682 0xd6 => Op::OpNop39,
683 0xd7 => Op::OpNop40,
684 0xd8 => Op::OpNop41,
685 0xd9 => Op::OpNop42,
686 0xda => Op::OpNop43,
687 0xdb => Op::OpNop44,
688 0xdc => Op::OpNop45,
689 0xdd => Op::OpNop46,
690 0xde => Op::OpNop47,
691 0xdf => Op::OpNop48,
692 0xe0 => Op::OpNop49,
693 0xe1 => Op::OpNop50,
694 0xe2 => Op::OpNop51,
695 0xe3 => Op::OpNop52,
696 0xe4 => Op::OpNop53,
697 0xe5 => Op::OpNop54,
698 0xe6 => Op::OpNop55,
699 0xe7 => Op::OpNop56,
700 0xe8 => Op::OpNop57,
701 0xe9 => Op::OpNop58,
702 0xea => Op::OpNop59,
703 0xeb => Op::OpNop60,
704 0xec => Op::OpNop61,
705 0xed => Op::OpNop62,
706 0xee => Op::OpNop63,
707 0xef => Op::OpNop64,
708 0xf0 => Op::OpNop65,
709 0xf1 => Op::OpNop66,
710 0xf2 => Op::OpNop67,
711 0xf3 => Op::OpNop68,
712 0xf4 => Op::OpNop69,
713 0xf5 => Op::OpNop70,
714 0xf6 => Op::OpNop71,
715 0xf7 => Op::OpNop72,
716 0xf8 => Op::OpNop73,
717 0xf9 => Op::OpSmallData,
718 0xfa => Op::OpSmallInteger,
719 0xfb => Op::OpPubKeys,
720 0xfc => Op::OpNop77,
721 0xfd => Op::OpPubKeyHash,
722 0xfe => Op::OpPubKey,
723 0xff => Op::OpInvalidOpcode,
724 _ => Op::OpInvalidOpcode,
727 }
728 }
729}
730
731#[cfg(test)]
732mod tests {
733 use super::*;
734
735 #[test]
736 fn test_from_u8_roundtrip_known_opcodes() {
737 let known: Vec<(u8, Op)> = vec![
739 (0x00, Op::Op0),
740 (0x4c, Op::OpPushData1),
741 (0x4d, Op::OpPushData2),
742 (0x4e, Op::OpPushData4),
743 (0x4f, Op::Op1Negate),
744 (0x50, Op::OpReserved),
745 (0x51, Op::Op1),
746 (0x60, Op::Op16),
747 (0x61, Op::OpNop),
748 (0x63, Op::OpIf),
749 (0x68, Op::OpEndIf),
750 (0x6a, Op::OpReturn),
751 (0x76, Op::OpDup),
752 (0x7e, Op::OpCat),
753 (0x7f, Op::OpSplit),
754 (0x80, Op::OpNum2Bin),
755 (0x81, Op::OpBin2Num),
756 (0x87, Op::OpEqual),
757 (0x88, Op::OpEqualVerify),
758 (0x93, Op::OpAdd),
759 (0x95, Op::OpMul),
760 (0x96, Op::OpDiv),
761 (0x97, Op::OpMod),
762 (0x98, Op::OpLShift),
763 (0x99, Op::OpRShift),
764 (0xa9, Op::OpHash160),
765 (0xac, Op::OpCheckSig),
766 (0xae, Op::OpCheckMultiSig),
767 (0xb0, Op::OpNop1),
768 (0xb3, Op::OpSubstr),
769 (0xb4, Op::OpLeft),
770 (0xb5, Op::OpRight),
771 (0xb6, Op::OpLShiftNum),
772 (0xb7, Op::OpRShiftNum),
773 (0xff, Op::OpInvalidOpcode),
774 ];
775
776 for (byte, expected) in known {
777 let op = Op::from(byte);
778 assert_eq!(op, expected, "From<u8> for byte {:#04x} failed", byte);
779 assert_eq!(op.to_byte(), byte, "to_byte for {:#04x} failed", byte);
780 }
781 }
782
783 #[test]
784 fn test_unknown_bytes_map_to_invalid() {
785 for byte in 0x01..=0x4bu8 {
787 assert_eq!(
788 Op::from(byte),
789 Op::OpInvalidOpcode,
790 "Direct-push byte {:#04x} should map to OpInvalidOpcode",
791 byte
792 );
793 }
794 }
795
796 #[test]
797 fn test_to_name_common_opcodes() {
798 assert_eq!(Op::Op0.to_name(), "OP_0");
799 assert_eq!(Op::OpDup.to_name(), "OP_DUP");
800 assert_eq!(Op::OpCheckSig.to_name(), "OP_CHECKSIG");
801 assert_eq!(Op::OpReturn.to_name(), "OP_RETURN");
802 assert_eq!(Op::OpHash160.to_name(), "OP_HASH160");
803 assert_eq!(Op::OpEqualVerify.to_name(), "OP_EQUALVERIFY");
804 assert_eq!(Op::Op1.to_name(), "OP_1");
805 assert_eq!(Op::Op16.to_name(), "OP_16");
806 assert_eq!(Op::OpCat.to_name(), "OP_CAT");
807 assert_eq!(Op::OpMul.to_name(), "OP_MUL");
808 assert_eq!(Op::OpSubstr.to_name(), "OP_SUBSTR");
809 assert_eq!(Op::OpInvalidOpcode.to_name(), "OP_INVALIDOPCODE");
810 }
811
812 #[test]
813 fn test_from_name_roundtrip() {
814 let names = [
815 "OP_0",
816 "OP_DUP",
817 "OP_CHECKSIG",
818 "OP_RETURN",
819 "OP_HASH160",
820 "OP_EQUALVERIFY",
821 "OP_1",
822 "OP_16",
823 "OP_CAT",
824 "OP_MUL",
825 "OP_SUBSTR",
826 "OP_INVALIDOPCODE",
827 "OP_FALSE",
828 "OP_TRUE",
829 ];
830 for name in &names {
831 let op = Op::from_name(name).unwrap_or_else(|| panic!("from_name failed for {}", name));
832 let canonical = op.to_name();
834 let op2 = Op::from_name(canonical)
835 .unwrap_or_else(|| panic!("from_name failed for canonical {}", canonical));
836 assert_eq!(op, op2);
837 }
838 }
839
840 #[test]
841 fn test_all_nop_variants_exist() {
842 for byte in 0xb8..=0xf8u8 {
844 let op = Op::from(byte);
845 assert_ne!(
846 op,
847 Op::OpInvalidOpcode,
848 "Byte {:#04x} should not be OpInvalidOpcode",
849 byte
850 );
851 }
852 }
853
854 #[test]
855 fn test_opcode_count() {
856 let mut count = 0u32;
858 for byte in 0x00..=0xffu16 {
859 let op = Op::from(byte as u8);
860 if op != Op::OpInvalidOpcode || byte == 0xff {
861 count += 1;
862 }
863 }
864 assert!(
868 count >= 130,
869 "Expected at least 130 named opcodes, got {}",
870 count
871 );
872 }
873}