Skip to main content

runar_compiler_rust/codegen/
opcodes.rs

1//! Complete BSV opcode table.
2//!
3//! This covers the full set of opcodes supported in Bitcoin SV, including
4//! opcodes that were disabled in BTC but re-enabled in BSV (OP_CAT, OP_SPLIT,
5//! OP_MUL, OP_DIV, OP_MOD, OP_LSHIFT, OP_RSHIFT, OP_AND, OP_OR, OP_XOR).
6
7use std::collections::HashMap;
8use std::sync::LazyLock;
9
10/// Map from opcode name to byte value.
11pub static OPCODES: LazyLock<HashMap<&'static str, u8>> = LazyLock::new(|| {
12    let mut m = HashMap::new();
13
14    // Push value
15    m.insert("OP_0", 0x00);
16    m.insert("OP_FALSE", 0x00);
17    m.insert("OP_PUSHDATA1", 0x4c);
18    m.insert("OP_PUSHDATA2", 0x4d);
19    m.insert("OP_PUSHDATA4", 0x4e);
20    m.insert("OP_1NEGATE", 0x4f);
21    m.insert("OP_1", 0x51);
22    m.insert("OP_TRUE", 0x51);
23    m.insert("OP_2", 0x52);
24    m.insert("OP_3", 0x53);
25    m.insert("OP_4", 0x54);
26    m.insert("OP_5", 0x55);
27    m.insert("OP_6", 0x56);
28    m.insert("OP_7", 0x57);
29    m.insert("OP_8", 0x58);
30    m.insert("OP_9", 0x59);
31    m.insert("OP_10", 0x5a);
32    m.insert("OP_11", 0x5b);
33    m.insert("OP_12", 0x5c);
34    m.insert("OP_13", 0x5d);
35    m.insert("OP_14", 0x5e);
36    m.insert("OP_15", 0x5f);
37    m.insert("OP_16", 0x60);
38
39    // Flow control
40    m.insert("OP_NOP", 0x61);
41    m.insert("OP_IF", 0x63);
42    m.insert("OP_NOTIF", 0x64);
43    m.insert("OP_ELSE", 0x67);
44    m.insert("OP_ENDIF", 0x68);
45    m.insert("OP_VERIFY", 0x69);
46    m.insert("OP_RETURN", 0x6a);
47
48    // Stack
49    m.insert("OP_TOALTSTACK", 0x6b);
50    m.insert("OP_FROMALTSTACK", 0x6c);
51    m.insert("OP_2DROP", 0x6d);
52    m.insert("OP_2DUP", 0x6e);
53    m.insert("OP_3DUP", 0x6f);
54    m.insert("OP_2OVER", 0x70);
55    m.insert("OP_2ROT", 0x71);
56    m.insert("OP_2SWAP", 0x72);
57    m.insert("OP_IFDUP", 0x73);
58    m.insert("OP_DEPTH", 0x74);
59    m.insert("OP_DROP", 0x75);
60    m.insert("OP_DUP", 0x76);
61    m.insert("OP_NIP", 0x77);
62    m.insert("OP_OVER", 0x78);
63    m.insert("OP_PICK", 0x79);
64    m.insert("OP_ROLL", 0x7a);
65    m.insert("OP_ROT", 0x7b);
66    m.insert("OP_SWAP", 0x7c);
67    m.insert("OP_TUCK", 0x7d);
68
69    // String / byte-string operations (BSV re-enabled)
70    m.insert("OP_CAT", 0x7e);
71    m.insert("OP_SPLIT", 0x7f);
72    m.insert("OP_NUM2BIN", 0x80);
73    m.insert("OP_BIN2NUM", 0x81);
74    m.insert("OP_SIZE", 0x82);
75
76    // Bitwise logic
77    m.insert("OP_INVERT", 0x83);
78    m.insert("OP_AND", 0x84);
79    m.insert("OP_OR", 0x85);
80    m.insert("OP_XOR", 0x86);
81    m.insert("OP_EQUAL", 0x87);
82    m.insert("OP_EQUALVERIFY", 0x88);
83
84    // Arithmetic
85    m.insert("OP_1ADD", 0x8b);
86    m.insert("OP_1SUB", 0x8c);
87    m.insert("OP_NEGATE", 0x8f);
88    m.insert("OP_ABS", 0x90);
89    m.insert("OP_NOT", 0x91);
90    m.insert("OP_0NOTEQUAL", 0x92);
91    m.insert("OP_ADD", 0x93);
92    m.insert("OP_SUB", 0x94);
93    m.insert("OP_MUL", 0x95);
94    m.insert("OP_DIV", 0x96);
95    m.insert("OP_MOD", 0x97);
96    m.insert("OP_LSHIFT", 0x98);
97    m.insert("OP_RSHIFT", 0x99);
98    m.insert("OP_BOOLAND", 0x9a);
99    m.insert("OP_BOOLOR", 0x9b);
100    m.insert("OP_NUMEQUAL", 0x9c);
101    m.insert("OP_NUMEQUALVERIFY", 0x9d);
102    m.insert("OP_NUMNOTEQUAL", 0x9e);
103    m.insert("OP_LESSTHAN", 0x9f);
104    m.insert("OP_GREATERTHAN", 0xa0);
105    m.insert("OP_LESSTHANOREQUAL", 0xa1);
106    m.insert("OP_GREATERTHANOREQUAL", 0xa2);
107    m.insert("OP_MIN", 0xa3);
108    m.insert("OP_MAX", 0xa4);
109    m.insert("OP_WITHIN", 0xa5);
110
111    // Crypto
112    m.insert("OP_RIPEMD160", 0xa6);
113    m.insert("OP_SHA1", 0xa7);
114    m.insert("OP_SHA256", 0xa8);
115    m.insert("OP_HASH160", 0xa9);
116    m.insert("OP_HASH256", 0xaa);
117    m.insert("OP_CODESEPARATOR", 0xab);
118    m.insert("OP_CHECKSIG", 0xac);
119    m.insert("OP_CHECKSIGVERIFY", 0xad);
120    m.insert("OP_CHECKMULTISIG", 0xae);
121    m.insert("OP_CHECKMULTISIGVERIFY", 0xaf);
122
123    m
124});
125
126/// Look up an opcode byte by name. Returns `None` if unknown.
127pub fn opcode_byte(name: &str) -> Option<u8> {
128    OPCODES.get(name).copied()
129}