1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
//! Script commands
#![allow(dead_code)]
// Code taken from https://github.com/brentongunning/rust-sv under the MIT license
// Thanks Brenton Gunning

// --------------------------------------------------------------------------------------------
// Constants
// --------------------------------------------------------------------------------------------

/// Pushes 0 onto the stack
pub const FALSE: u8 = 0;

/// Offset by n to push n bytes onto the stack, where n: [1-75]
pub const PUSH0: u8 = 0;
pub const PUSH75: u8 = 75; 

/// The next byte sets the number of bytes to push onto the stack
pub const PUSHDATA1: u8 = 76;
/// The next two bytes sets the number of bytes to push onto the stack
pub const PUSHDATA2: u8 = 77;
/// The next four bytes sets the number of bytes to push onto the stack
pub const PUSHDATA4: u8 = 78;

/// Pushes -1 onto the stack
pub const NEGATIVE1: u8 = 79;
/// Pushes 1 onto the stack
pub const NUM1: u8 = 81;
/// Pushes 1 onto the stack
pub const TRUE: u8 = 81;

/// Pushes 2 onto the stack
pub const NUM2: u8 = 82;
/// Pushes 3 onto the stack
pub const NUM3: u8 = 83;
/// Pushes 4 onto the stack
pub const NUM4: u8 = 84;
/// Pushes 5 onto the stack
pub const NUM5: u8 = 85;
/// Pushes 6 onto the stack
pub const NUM6: u8 = 86;
/// Pushes 7 onto the stack
pub const NUM7: u8 = 87;
/// Pushes 8 onto the stack
pub const NUM8: u8 = 88;
/// Pushes 9 onto the stack
pub const NUM9: u8 = 89;
/// Pushes 10 onto the stack
pub const NUM10: u8 = 90;
/// Pushes 11 onto the stack
pub const NUM11: u8 = 91;
/// Pushes 12 onto the stack
pub const NUM12: u8 = 92;
/// Pushes 13 onto the stack
pub const NUM13: u8 = 93;
/// Pushes 14 onto the stack
pub const NUM14: u8 = 94;
/// Pushes 15 onto the stack
pub const NUM15: u8 = 95;
/// Pushes 16 onto the stack
pub const NUM16: u8 = 96;

// --------------------------------------------------------------------------------------------
// Flow Control
// --------------------------------------------------------------------------------------------

/// Does nothing
pub const NOP: u8 = 97;
/// If the top stack is true, statements are executed. Top stack value is removed.
pub const IF: u8 = 99;
/// If the top stack is false, statements are executed. Top stack value is removed.
pub const NOTIF: u8 = 100;
/// If the preceding OP_IF or OP_NOTIF statemetns were not executed, then statements are executed.
pub const ELSE: u8 = 103;
/// Ends an if-else block
pub const ENDIF: u8 = 104;
/// Marks a statement as invalid if the top stack value is false. Top stack value is removed.
pub const VERIFY: u8 = 105;
/// Marks a statements as invalid
pub const RETURN: u8 = 106;

// --------------------------------------------------------------------------------------------
// Stack
// --------------------------------------------------------------------------------------------

/// Moves the top item on the main stack to the alt stack
pub const TOALTSTACK: u8 = 107;
/// Moves the top item on the alt stack to the main stack
pub const FROMALTSTACK: u8 = 108;
/// Duplicates the top stack value if it is not zero
pub const IFDUP: u8 = 115;
/// Puts the number of stack items onto the stack
pub const DEPTH: u8 = 116;
/// Drops the top stack value
pub const DROP: u8 = 117;
/// Duplicates the top stack item
pub const DUP: u8 = 118;
/// Removes the second-to-top stack item
pub const NIP: u8 = 119;
/// Copies the second-to-top stack item to the top
pub const OVER: u8 = 120;
/// The item n back in the stack is copied to the top
pub const PICK: u8 = 121;
/// The item n back in the stack is moved to the top
pub const ROLL: u8 = 122;
/// The top three items on the stack are rotated to the left
pub const ROT: u8 = 123;
/// The top two items on the stack are swapped
pub const SWAP: u8 = 124;
/// The item at the top of the stack is copied and inserted before the second-to-top item
pub const TUCK: u8 = 125;
/// Removes the top two items from the stack
pub const DROP2: u8 = 109;
/// Duplicates the top two stack items
pub const DUP2: u8 = 110;
/// Duplicates the top three stack items
pub const DUP3: u8 = 111;
/// Copies the pair of items two spaces back to the front
pub const OVER2: u8 = 112;
/// The fifth and sixth items back are moved to the top of the stack
pub const ROT2: u8 = 113;
/// Swaps the top two pairs of items
pub const SWAP2: u8 = 114;

// --------------------------------------------------------------------------------------------
// Splice
// --------------------------------------------------------------------------------------------

/// Concatenates two byte sequences
pub const CAT: u8 = 126;
/// Splits the byte sequence at position n
pub const SPLIT: u8 = 127;
/// Pushes the byte sequence length of the top stack item without popping it
pub const SIZE: u8 = 130;

// --------------------------------------------------------------------------------------------
// Bitwise Logic
// --------------------------------------------------------------------------------------------

/// Flips all of the bits in the input
pub const INVERT: u8 = 131;
/// Boolean and between each bit in the inputs
pub const AND: u8 = 132;
/// Boolean or between each bit in the inputs
pub const OR: u8 = 133;
/// Boolean exclusive or between each bit in the inputs
pub const XOR: u8 = 134;
/// Returns 1 if the inputs are exactly equal, 0 otherwise
pub const EQUAL: u8 = 135;
/// Same as OP_EQUAL, but runs OP_VERIFY afterward
pub const EQUALVERIFY: u8 = 136;

// --------------------------------------------------------------------------------------------
// Arithmetic
// --------------------------------------------------------------------------------------------

/// Adds 1 to the input
pub const ADD1: u8 = 139;
/// Subtracts 1 from the input
pub const SUB1: u8 = 140;
/// The sign of the input is flipped
pub const NEGATE: u8 = 143;
/// The input is made positive
pub const ABS: u8 = 144;
/// If the input is 0 or 1, it is flipped. Otherwise, the output will be 0.
pub const NOT: u8 = 145;
/// Returns 0 if the input is 0. 1 otherwise.
pub const NOTEQUAL0: u8 = 146;
/// Adds a to b
pub const ADD: u8 = 147;
/// Subtracts b from a
pub const SUB: u8 = 148;
/// Multiplies a by b
pub const MUL: u8 = 149;
/// Divides a by b
pub const DIV: u8 = 150;
/// Returns the remainder after dividing a by b
pub const MOD: u8 = 151;
/// Shifts a left b bits, preserving sign
pub const LSHIFT: u8 = 152;
/// Shifts a right b bits, preserving sign
pub const RSHIFT: u8 = 153;
/// If both a and b are not empty, the output is 1. Otherwise, 0.
pub const BOOLAND: u8 = 154;
/// If a or b is not empty, the output is 1. Otherwise, 0.
pub const BOOLOR: u8 = 155;
/// Returns 1 if the numbers are equal. Otherwise, 0.
pub const NUMEQUAL: u8 = 156;
/// Same as OP_NUMEQUAL, but runs OP_VERIFY afterward
pub const NUMEQUALVERIFY: u8 = 157;
/// Returns 1 if the numbers are not equal. Otherwise, 0.
pub const NUMNOTEQUAL: u8 = 158;
/// Returns 1 if a is less than b. Otherwise, 0.
pub const LESSTHAN: u8 = 159;
/// Returns 1 if a is greater than b. Otherwise, 0.
pub const GREATERTHAN: u8 = 160;
/// Returns 1 if a is less than or equal to b. Otherwise, 0.
pub const LESSTHANOREQUAL: u8 = 161;
/// Returns 1 if a is greater than or equal to b. Otherwise, 0.
pub const GREATERTHANOREQUAL: u8 = 162;
/// Returns the smaller of a and b
pub const MIN: u8 = 163;
/// Returns the larger of a and b
pub const MAX: u8 = 164;
/// Returns 1 if x is within the specified range, left inclusive. Otherwise, 0.
pub const WITHIN: u8 = 165;
/// Converts numeric value a into a byte sequence of length b
pub const NUM2BIN: u8 = 128;
/// Converts byte sequence x into a numeric value
pub const BIN2NUM: u8 = 129;

// --------------------------------------------------------------------------------------------
// Cryptography
// --------------------------------------------------------------------------------------------

/// The input is hashed using RIPEMD-160
pub const RIPEMD160: u8 = 166;
/// The input is hashed using SHA-1
pub const SHA1: u8 = 167;
/// The input is hashed using SHA-256
pub const SHA256: u8 = 168;
/// The input is hashed twice: first with SHA-256 and then with RIPEMD-160
pub const HASH160: u8 = 169;
/// The input is hashed two times with SHA-256
pub const HASH256: u8 = 170;
/// Marks the part of the script after which the signature will begin matching
pub const CODESEPARATOR: u8 = 171;
/// Puts 1 on the stack if the signature authorizes the public key and transaction hash. Otherwise 0.
pub const CHECKSIG: u8 = 172;
/// Same as OP_CHECKSIG, but OP_VERIFY is executed afterward
pub const CHECKSIGVERIFY: u8 = 173;
/// Puts 1 on the stack if m of n signatures authorize the public key and transaction hash. Otherwise 0.
pub const CHECKMULTISIG: u8 = 174;
/// Same as OP_CHECKMULTISIG, but OP_VERIFY is executed afterward
pub const CHECKMULTISIGVERIFY: u8 = 175;

// --------------------------------------------------------------------------------------------
// Locktime
// --------------------------------------------------------------------------------------------

/// Marks transaction as invalid if the top stack item is greater than the transaction's lock_time
pub const CHECKLOCKTIMEVERIFY: u8 = 177;
/// Marks transaction as invalid if the top stack item is less than the transaction's sequence used for relative lock time
pub const CHECKSEQUENCEVERIFY: u8 = 178;

// --------------------------------------------------------------------------------------------
// Pseudo-words
// --------------------------------------------------------------------------------------------

/// Represents a public key hashed with OP_HASH160
pub const PUBKEYHASH: u8 = 253;
/// Represents a public key compatible with OP_CHECKSIG
pub const PUBKEY: u8 = 254;
/// Matches any opcode that is not yet assigned
pub const INVALIDOPCODE: u8 = 255;

// --------------------------------------------------------------------------------------------
// Reserved words
// --------------------------------------------------------------------------------------------

/// Transaction is invalid unless occuring in an unexecuted OP_IF branch
pub const RESERVED: u8 = 80;
/// Transaction is invalid unless occuring in an unexecuted OP_IF branch
pub const VER: u8 = 98;
/// Transaction is invalid even when occuring in an unexecuted OP_IF branch
pub const VERIF: u8 = 101;
/// Transaction is invalid even when occuring in an unexecuted OP_IF branch
pub const VERNOTIF: u8 = 102;
/// Transaction is invalid unless occuring in an unexecuted OP_IF branch
pub const RESERVED1: u8 = 137;
/// Transaction is invalid unless occuring in an unexecuted OP_IF branch
pub const RESERVED2: u8 = 138;
/// The word is ignored. Does not mark transaction as invalid.
pub const NOP1: u8 = 176;
/// The word is ignored. Does not mark transaction as invalid.
pub const NOP4: u8 = 179;
/// The word is ignored. Does not mark transaction as invalid.
pub const NOP5: u8 = 180;
/// The word is ignored. Does not mark transaction as invalid.
pub const NOP6: u8 = 181;
/// The word is ignored. Does not mark transaction as invalid.
pub const NOP7: u8 = 182;
/// The word is ignored. Does not mark transaction as invalid.
pub const NOP8: u8 = 183;
/// The word is ignored. Does not mark transaction as invalid.
pub const NOP9: u8 = 184;
/// The word is ignored. Does not mark transaction as invalid.
pub const NOP10: u8 = 185;

/// Words at or above this number are invalid
pub const INVALID_ABOVE: u8 = 186;

// --------------------------------------------------------------------------------------------
// Disabled words
// --------------------------------------------------------------------------------------------

/// The input is multiplied by 2
pub const MUL2: u8 = 141;
/// The input is divided by 2
pub const DIV2: u8 = 142;