Skip to main content

blvm_primitives/
opcodes.rs

1//! Bitcoin Script Opcode Constants
2//!
3//! Complete set of opcode constants for Bitcoin script execution.
4//! All opcodes are defined with their hex values and descriptive comments.
5//!
6//! Reference: BIP specifications and script/opcode definitions
7
8// ============================================================================
9// PUSH DATA OPCODES (0x00 - 0x4e)
10// ============================================================================
11
12/// OP_0 / OP_FALSE - Push empty array
13pub const OP_0: u8 = 0x00;
14pub const OP_FALSE: u8 = 0x00;
15
16/// OP_PUSHDATA1 - Push next byte as data length
17pub const OP_PUSHDATA1: u8 = 0x4c;
18
19/// OP_PUSHDATA2 - Push next 2 bytes (little-endian) as data length
20pub const OP_PUSHDATA2: u8 = 0x4d;
21
22/// OP_PUSHDATA4 - Push next 4 bytes (little-endian) as data length
23pub const OP_PUSHDATA4: u8 = 0x4e;
24
25// ============================================================================
26// PUSH VALUE OPCODES (0x4f - 0x60)
27// ============================================================================
28
29/// OP_1NEGATE - Push -1 onto stack
30pub const OP_1NEGATE: u8 = 0x4f;
31
32/// OP_RESERVED - Reserved opcode, transaction invalid if present
33pub const OP_RESERVED: u8 = 0x50;
34
35/// OP_1 / OP_TRUE - Push 1 onto stack
36pub const OP_1: u8 = 0x51;
37pub const OP_TRUE: u8 = 0x51;
38
39/// OP_2 - Push 2 onto stack
40pub const OP_2: u8 = 0x52;
41
42/// OP_3 - Push 3 onto stack
43pub const OP_3: u8 = 0x53;
44
45/// OP_4 - Push 4 onto stack
46pub const OP_4: u8 = 0x54;
47
48/// OP_5 - Push 5 onto stack
49pub const OP_5: u8 = 0x55;
50
51/// OP_6 - Push 6 onto stack
52pub const OP_6: u8 = 0x56;
53
54/// OP_7 - Push 7 onto stack
55pub const OP_7: u8 = 0x57;
56
57/// OP_8 - Push 8 onto stack
58pub const OP_8: u8 = 0x58;
59
60/// OP_9 - Push 9 onto stack
61pub const OP_9: u8 = 0x59;
62
63/// OP_10 - Push 10 onto stack
64pub const OP_10: u8 = 0x5a;
65
66/// OP_11 - Push 11 onto stack
67pub const OP_11: u8 = 0x5b;
68
69/// OP_12 - Push 12 onto stack
70pub const OP_12: u8 = 0x5c;
71
72/// OP_13 - Push 13 onto stack
73pub const OP_13: u8 = 0x5d;
74
75/// OP_14 - Push 14 onto stack
76pub const OP_14: u8 = 0x5e;
77
78/// OP_15 - Push 15 onto stack
79pub const OP_15: u8 = 0x5f;
80
81/// OP_16 - Push 16 onto stack
82pub const OP_16: u8 = 0x60;
83
84// ============================================================================
85// CONTROL FLOW OPCODES (0x61 - 0x6f)
86// ============================================================================
87
88/// OP_NOP - No operation
89pub const OP_NOP: u8 = 0x61;
90
91/// OP_VER - Reserved opcode, disabled
92pub const OP_VER: u8 = 0x62;
93
94/// OP_IF - If top stack value is true, statements are executed
95pub const OP_IF: u8 = 0x63;
96
97/// OP_NOTIF - If top stack value is false, statements are executed
98pub const OP_NOTIF: u8 = 0x64;
99
100/// OP_VERIF - Reserved opcode, disabled
101pub const OP_VERIF: u8 = 0x65;
102
103/// OP_VERNOTIF - Reserved opcode, disabled
104pub const OP_VERNOTIF: u8 = 0x66;
105
106/// OP_ELSE - If the preceding OP_IF or OP_NOTIF was not executed, these statements are
107pub const OP_ELSE: u8 = 0x67;
108
109/// OP_ENDIF - Ends an OP_IF/OP_NOTIF/OP_ELSE block
110pub const OP_ENDIF: u8 = 0x68;
111
112/// OP_VERIFY - Marks transaction as invalid if top stack value is not true
113pub const OP_VERIFY: u8 = 0x69;
114
115/// OP_RETURN - Marks transaction as invalid
116pub const OP_RETURN: u8 = 0x6a;
117
118// ============================================================================
119// STACK OPERATIONS (0x6b - 0x7d)
120// ============================================================================
121
122/// OP_TOALTSTACK - Puts the input onto the top of the alt stack. Removes it from the main stack
123pub const OP_TOALTSTACK: u8 = 0x6b;
124
125/// OP_FROMALTSTACK - Puts the input onto the top of the main stack. Removes it from the alt stack
126pub const OP_FROMALTSTACK: u8 = 0x6c;
127
128/// OP_2DROP - Removes the top two stack items
129pub const OP_2DROP: u8 = 0x6d;
130
131/// OP_2DUP - Duplicates the top two stack items
132pub const OP_2DUP: u8 = 0x6e;
133
134/// OP_3DUP - Duplicates the top three stack items
135pub const OP_3DUP: u8 = 0x6f;
136
137/// OP_2OVER - Copies the pair of items two spaces back in the stack to the front
138pub const OP_2OVER: u8 = 0x70;
139
140/// OP_2ROT - The fifth and sixth items back are moved to the top of the stack
141pub const OP_2ROT: u8 = 0x71;
142
143/// OP_2SWAP - Swaps the top two pairs of items
144pub const OP_2SWAP: u8 = 0x72;
145
146/// OP_IFDUP - If the top stack value is not 0, duplicate it
147pub const OP_IFDUP: u8 = 0x73;
148
149/// OP_DEPTH - Puts the number of stack items onto the stack
150pub const OP_DEPTH: u8 = 0x74;
151
152/// OP_DROP - Removes the top stack item
153pub const OP_DROP: u8 = 0x75;
154
155/// OP_DUP - Duplicates the top stack item
156pub const OP_DUP: u8 = 0x76;
157
158/// OP_NIP - Removes the second-to-top stack item
159pub const OP_NIP: u8 = 0x77;
160
161/// OP_OVER - Copies the second-to-top stack item to the top
162pub const OP_OVER: u8 = 0x78;
163
164/// OP_PICK - The item n back in the stack is copied to the top
165pub const OP_PICK: u8 = 0x79;
166
167/// OP_ROLL - The item n back in the stack is moved to the top
168pub const OP_ROLL: u8 = 0x7a;
169
170/// OP_ROT - The top three items on the stack are rotated to the left
171pub const OP_ROT: u8 = 0x7b;
172
173/// OP_SWAP - The top two items on the stack are swapped
174pub const OP_SWAP: u8 = 0x7c;
175
176/// OP_TUCK - The item at the top of the stack is copied and inserted before the second-to-top item
177pub const OP_TUCK: u8 = 0x7d;
178
179// ============================================================================
180// STRING OPERATIONS (0x7e - 0x8a)
181// ============================================================================
182
183/// OP_CAT - Concatenates two strings (disabled)
184pub const OP_CAT: u8 = 0x7e;
185
186/// OP_SUBSTR - Returns a section of a string (disabled)
187pub const OP_SUBSTR: u8 = 0x7f;
188
189/// OP_LEFT - Keeps only characters left of the specified point in a string (disabled)
190pub const OP_LEFT: u8 = 0x80;
191
192/// OP_RIGHT - Keeps only characters right of the specified point in a string (disabled)
193pub const OP_RIGHT: u8 = 0x81;
194
195/// OP_SIZE - Pushes the string length of the top element of the stack (without popping it)
196pub const OP_SIZE: u8 = 0x82;
197
198// ============================================================================
199// BITWISE LOGIC (0x83 - 0x8a)
200// ============================================================================
201
202/// OP_INVERT - Flips all of the bits in the input (disabled)
203pub const OP_INVERT: u8 = 0x83;
204
205/// OP_AND - Boolean AND between each bit in the inputs (disabled)
206pub const OP_AND: u8 = 0x84;
207
208/// OP_OR - Boolean OR between each bit in the inputs (disabled)
209pub const OP_OR: u8 = 0x85;
210
211/// OP_XOR - Boolean exclusive OR between each bit in the inputs (disabled)
212pub const OP_XOR: u8 = 0x86;
213
214/// OP_EQUAL - Returns 1 if the inputs are exactly equal, 0 otherwise
215pub const OP_EQUAL: u8 = 0x87;
216
217/// OP_EQUALVERIFY - Same as OP_EQUAL, but runs OP_VERIFY afterward
218pub const OP_EQUALVERIFY: u8 = 0x88;
219
220/// OP_RESERVED1 - Reserved opcode
221pub const OP_RESERVED1: u8 = 0x89;
222
223/// OP_RESERVED2 - Reserved opcode
224pub const OP_RESERVED2: u8 = 0x8a;
225
226// ============================================================================
227// NUMERIC OPERATIONS (0x8b - 0xa5)
228// ============================================================================
229
230/// OP_1ADD - 1 is added to the input
231pub const OP_1ADD: u8 = 0x8b;
232
233/// OP_1SUB - 1 is subtracted from the input
234pub const OP_1SUB: u8 = 0x8c;
235
236/// OP_2MUL - The input is multiplied by 2 (disabled)
237pub const OP_2MUL: u8 = 0x8d;
238
239/// OP_2DIV - The input is divided by 2 (disabled)
240pub const OP_2DIV: u8 = 0x8e;
241
242/// OP_NEGATE - The sign of the input is flipped
243pub const OP_NEGATE: u8 = 0x8f;
244
245/// OP_ABS - The input is made positive
246pub const OP_ABS: u8 = 0x90;
247
248/// OP_NOT - If the input is 0 or 1, it is flipped. Otherwise the output is 0
249pub const OP_NOT: u8 = 0x91;
250
251/// OP_0NOTEQUAL - Returns 0 if the input is 0. 1 otherwise
252pub const OP_0NOTEQUAL: u8 = 0x92;
253
254/// OP_ADD - a is added to b
255pub const OP_ADD: u8 = 0x93;
256
257/// OP_SUB - b is subtracted from a
258pub const OP_SUB: u8 = 0x94;
259
260/// OP_MUL - a is multiplied by b (disabled)
261pub const OP_MUL: u8 = 0x95;
262
263/// OP_DIV - a is divided by b (disabled)
264pub const OP_DIV: u8 = 0x96;
265
266/// OP_MOD - Returns the remainder after dividing a by b (disabled)
267pub const OP_MOD: u8 = 0x97;
268
269/// OP_LSHIFT - Shifts a left b bits, preserving sign (disabled)
270pub const OP_LSHIFT: u8 = 0x98;
271
272/// OP_RSHIFT - Shifts a right b bits, preserving sign (disabled)
273pub const OP_RSHIFT: u8 = 0x99;
274
275/// OP_BOOLAND - If both a and b are not 0, the output is 1. Otherwise 0
276pub const OP_BOOLAND: u8 = 0x9a;
277
278/// OP_BOOLOR - If a or b is not 0, the output is 1. Otherwise 0
279pub const OP_BOOLOR: u8 = 0x9b;
280
281/// OP_NUMEQUAL - Returns 1 if the numbers are equal, 0 otherwise
282pub const OP_NUMEQUAL: u8 = 0x9c;
283
284/// OP_NUMEQUALVERIFY - Same as OP_NUMEQUAL, but runs OP_VERIFY afterward
285pub const OP_NUMEQUALVERIFY: u8 = 0x9d;
286
287/// OP_NUMNOTEQUAL - Returns 1 if the numbers are not equal, 0 otherwise
288pub const OP_NUMNOTEQUAL: u8 = 0x9e;
289
290/// OP_LESSTHAN - Returns 1 if a is less than b, 0 otherwise
291pub const OP_LESSTHAN: u8 = 0x9f;
292
293/// OP_GREATERTHAN - Returns 1 if a is greater than b, 0 otherwise
294pub const OP_GREATERTHAN: u8 = 0xa0;
295
296/// OP_LESSTHANOREQUAL - Returns 1 if a is less than or equal to b, 0 otherwise
297pub const OP_LESSTHANOREQUAL: u8 = 0xa1;
298
299/// OP_GREATERTHANOREQUAL - Returns 1 if a is greater than or equal to b, 0 otherwise
300pub const OP_GREATERTHANOREQUAL: u8 = 0xa2;
301
302/// OP_MIN - Returns the smaller of a and b
303pub const OP_MIN: u8 = 0xa3;
304
305/// OP_MAX - Returns the larger of a and b
306pub const OP_MAX: u8 = 0xa4;
307
308/// OP_WITHIN - Returns 1 if x is within the specified range (left-inclusive), 0 otherwise
309pub const OP_WITHIN: u8 = 0xa5;
310
311// ============================================================================
312// CRYPTOGRAPHIC OPERATIONS (0xa6 - 0xab)
313// ============================================================================
314
315/// OP_RIPEMD160 - The input is hashed using RIPEMD-160
316pub const OP_RIPEMD160: u8 = 0xa6;
317
318/// OP_SHA1 - The input is hashed using SHA-1
319pub const OP_SHA1: u8 = 0xa7;
320
321/// OP_SHA256 - The input is hashed using SHA-256
322pub const OP_SHA256: u8 = 0xa8;
323
324/// OP_HASH160 - The input is hashed twice: first with SHA-256 and then with RIPEMD-160
325pub const OP_HASH160: u8 = 0xa9;
326
327/// OP_HASH256 - The input is hashed two times with SHA-256
328pub const OP_HASH256: u8 = 0xaa;
329
330/// OP_CODESEPARATOR - All of the signature checking words will only match signatures to the data after the most recently-executed OP_CODESEPARATOR
331pub const OP_CODESEPARATOR: u8 = 0xab;
332
333// ============================================================================
334// SIGNATURE OPERATIONS (0xac - 0xaf)
335// ============================================================================
336
337/// OP_CHECKSIG - The entire transaction's outputs, inputs, and script (from the most recently-executed OP_CODESEPARATOR to the end) are hashed. The signature used must match the transaction and the public key or script verification fails
338pub const OP_CHECKSIG: u8 = 0xac;
339
340/// OP_CHECKSIGVERIFY - Same as OP_CHECKSIG, but OP_VERIFY is executed afterward
341pub const OP_CHECKSIGVERIFY: u8 = 0xad;
342
343/// OP_CHECKMULTISIG - Compares the first signature against each public key until it finds an ECDSA match. Starting with the subsequent public key, it compares the second signature against each remaining public key until it finds an ECDSA match. The process is repeated until all signatures have been checked or not enough public keys remain to produce a successful result. All signatures need to match a public key. Because public keys are not checked again if they fail any signature comparison, signatures must be placed in the scriptSig using the same order as their corresponding public keys were placed in the scriptPubKey or script. If all signatures are valid, 1 is returned, 0 otherwise
344pub const OP_CHECKMULTISIG: u8 = 0xae;
345
346/// OP_CHECKMULTISIGVERIFY - Same as OP_CHECKMULTISIG, but OP_VERIFY is executed afterward
347pub const OP_CHECKMULTISIGVERIFY: u8 = 0xaf;
348
349// ============================================================================
350// NOP OPCODES (0xb0 - 0xb9)
351// ============================================================================
352
353/// OP_NOP1 - Reserved for future use (was OP_EVAL, disabled)
354pub const OP_NOP1: u8 = 0xb0;
355
356/// OP_CHECKLOCKTIMEVERIFY (BIP65) - Marks transaction as invalid if the top stack item is greater than the transaction's nLockTime field, otherwise script evaluation continues as if an OP_NOP was executed
357pub const OP_CHECKLOCKTIMEVERIFY: u8 = 0xb1;
358pub const OP_NOP2: u8 = 0xb1; // Alias for OP_CHECKLOCKTIMEVERIFY
359
360/// OP_CHECKSEQUENCEVERIFY (BIP112) - Marks transaction as invalid if the relative lock time of the input (enforced by BIP 68 with nSequence) is not equal to or longer than the value of the top stack item
361pub const OP_CHECKSEQUENCEVERIFY: u8 = 0xb2;
362pub const OP_NOP3: u8 = 0xb2; // Alias for OP_CHECKSEQUENCEVERIFY
363
364/// OP_CHECKTEMPLATEVERIFY (BIP119) - Verifies that the transaction matches a template hash
365pub const OP_CHECKTEMPLATEVERIFY: u8 = 0xb3;
366pub const OP_NOP4: u8 = 0xb3; // Alias for OP_CHECKTEMPLATEVERIFY
367
368/// OP_NOP5 - Reserved for future use
369pub const OP_NOP5: u8 = 0xb4;
370
371/// OP_NOP6 - Reserved for future use
372pub const OP_NOP6: u8 = 0xb5;
373
374/// OP_NOP7 - Reserved for future use
375pub const OP_NOP7: u8 = 0xb6;
376
377/// OP_NOP8 - Reserved for future use
378pub const OP_NOP8: u8 = 0xb7;
379
380/// OP_NOP9 - Reserved for future use
381pub const OP_NOP9: u8 = 0xb8;
382
383/// OP_NOP10 - Reserved for future use
384pub const OP_NOP10: u8 = 0xb9;
385
386// ============================================================================
387// TAPSCRIPT OPCODES (0xba - 0xcc)
388// ============================================================================
389
390/// OP_CHECKSIGADD (BIP342) - Tapscript opcode for signature aggregation
391pub const OP_CHECKSIGADD: u8 = 0xba;
392
393/// OP_CHECKSIGFROMSTACK (BIP348) - Verifies a BIP340 Schnorr signature against an arbitrary message
394pub const OP_CHECKSIGFROMSTACK: u8 = 0xcc;
395
396// ============================================================================
397// HELPER CONSTANTS
398// ============================================================================
399
400/// Base value for OP_1 through OP_16 (OP_1 = 0x50 + 1 = 0x51)
401pub const OP_N_BASE: u8 = 0x50;
402
403/// Range for OP_1 through OP_16
404pub const OP_1_RANGE_START: u8 = OP_1;
405pub const OP_1_RANGE_END: u8 = OP_16;
406
407/// Range for OP_NOP opcodes (0xb0 - 0xb9)
408pub const OP_NOP_RANGE_START: u8 = OP_NOP1;
409pub const OP_NOP_RANGE_END: u8 = OP_NOP10;
410
411/// Range for disabled opcodes (string operations)
412pub const OP_DISABLED_STRING_RANGE_START: u8 = OP_CAT;
413pub const OP_DISABLED_STRING_RANGE_END: u8 = OP_RIGHT;
414
415/// Range for disabled opcodes (bitwise operations)
416pub const OP_DISABLED_BITWISE_RANGE_START: u8 = OP_INVERT;
417pub const OP_DISABLED_BITWISE_RANGE_END: u8 = OP_XOR;
418
419/// Range for disabled opcodes (numeric operations)
420pub const OP_DISABLED_NUMERIC_RANGE_START: u8 = OP_2MUL;
421pub const OP_DISABLED_NUMERIC_RANGE_END: u8 = OP_RSHIFT;
422
423// ============================================================================
424// PUSH DATA HELPER CONSTANTS
425// ============================================================================
426
427/// Push 1 byte (direct push; opcodes 0x01-0x4b are push N bytes)
428pub const PUSH_1_BYTE: u8 = 0x01;
429
430/// Push 20 bytes (used in P2WPKH: OP_0 0x14 <20-byte-hash>)
431pub const PUSH_20_BYTES: u8 = 0x14;
432
433/// Push 32 bytes (used in P2WSH and P2TR: OP_0/OP_1 0x20 <32-byte-hash>)
434pub const PUSH_32_BYTES: u8 = 0x20;
435
436/// Push 33 bytes (used in P2PK compressed pubkey: 0x21 <33-byte-pubkey>)
437pub const PUSH_33_BYTES: u8 = 0x21;
438
439/// Push 36 bytes (used in tests / OP_RETURN outputs)
440pub const PUSH_36_BYTES: u8 = 0x24;
441
442/// Push 65 bytes (used in P2PK uncompressed pubkey: 0x41 <65-byte-pubkey>)
443pub const PUSH_65_BYTES: u8 = 0x41;
444
445// ============================================================================
446// PROTOCOL CONSTANTS
447// ============================================================================
448
449/// DER signature prefix (0x30 = SEQUENCE tag in DER encoding)
450pub const DER_SIGNATURE_PREFIX: u8 = 0x30;
451
452/// Maximum value for 1-byte varint encoding (< 0xfd)
453pub const VARINT_1BYTE_MAX: u8 = 0xfc;
454
455/// Prefix for 2-byte varint encoding (0xfd + 2 bytes)
456pub const VARINT_2BYTE_PREFIX: u8 = 0xfd;
457
458/// Prefix for 4-byte varint encoding (0xfe + 4 bytes)
459pub const VARINT_4BYTE_PREFIX: u8 = 0xfe;
460
461/// Prefix for 8-byte varint encoding (0xff + 8 bytes)
462pub const VARINT_8BYTE_PREFIX: u8 = 0xff;