UNPKG

3.98 kBJavaScriptView Raw
1/*
2 * OpCode
3 * ======
4 *
5 * An opCode is one of the operations in the bitcoin scripting language. Each
6 * operation is just a number from 0-255, and it has a corresponding string,
7 * e.g. "OP_RETURN", which comes from the name of that constant in the bitcoind
8 * source code. The way you probably want to use this is with
9 * new OpCode(str).toNumber() or new OpCode(num).toString()
10 */
11'use strict'
12
13import { Struct } from './struct'
14
15const map = {
16 // push value
17 OP_FALSE: 0x00,
18 OP_0: 0x00,
19 OP_PUSHDATA1: 0x4c,
20 OP_PUSHDATA2: 0x4d,
21 OP_PUSHDATA4: 0x4e,
22 OP_1NEGATE: 0x4f,
23 OP_RESERVED: 0x50,
24 OP_TRUE: 0x51,
25 OP_1: 0x51,
26 OP_2: 0x52,
27 OP_3: 0x53,
28 OP_4: 0x54,
29 OP_5: 0x55,
30 OP_6: 0x56,
31 OP_7: 0x57,
32 OP_8: 0x58,
33 OP_9: 0x59,
34 OP_10: 0x5a,
35 OP_11: 0x5b,
36 OP_12: 0x5c,
37 OP_13: 0x5d,
38 OP_14: 0x5e,
39 OP_15: 0x5f,
40 OP_16: 0x60,
41
42 // control
43 OP_NOP: 0x61,
44 OP_VER: 0x62,
45 OP_IF: 0x63,
46 OP_NOTIF: 0x64,
47 OP_VERIF: 0x65,
48 OP_VERNOTIF: 0x66,
49 OP_ELSE: 0x67,
50 OP_ENDIF: 0x68,
51 OP_VERIFY: 0x69,
52 OP_RETURN: 0x6a,
53
54 // stack ops
55 OP_TOALTSTACK: 0x6b,
56 OP_FROMALTSTACK: 0x6c,
57 OP_2DROP: 0x6d,
58 OP_2DUP: 0x6e,
59 OP_3DUP: 0x6f,
60 OP_2OVER: 0x70,
61 OP_2ROT: 0x71,
62 OP_2SWAP: 0x72,
63 OP_IFDUP: 0x73,
64 OP_DEPTH: 0x74,
65 OP_DROP: 0x75,
66 OP_DUP: 0x76,
67 OP_NIP: 0x77,
68 OP_OVER: 0x78,
69 OP_PICK: 0x79,
70 OP_ROLL: 0x7a,
71 OP_ROT: 0x7b,
72 OP_SWAP: 0x7c,
73 OP_TUCK: 0x7d,
74
75 // data manipulation ops
76 OP_CAT: 0x7e,
77 OP_SUBSTR: 0x7f, // Replaced in BSV
78 OP_SPLIT: 0x7f,
79 OP_LEFT: 0x80, // Replaced in BSV
80 OP_NUM2BIN: 0x80,
81 OP_RIGHT: 0x81, // Replaced in BSV
82 OP_BIN2NUM: 0x81,
83 OP_SIZE: 0x82,
84
85 // bit logic
86 OP_INVERT: 0x83,
87 OP_AND: 0x84,
88 OP_OR: 0x85,
89 OP_XOR: 0x86,
90 OP_EQUAL: 0x87,
91 OP_EQUALVERIFY: 0x88,
92 OP_RESERVED1: 0x89,
93 OP_RESERVED2: 0x8a,
94
95 // numeric
96 OP_1ADD: 0x8b,
97 OP_1SUB: 0x8c,
98 OP_2MUL: 0x8d,
99 OP_2DIV: 0x8e,
100 OP_NEGATE: 0x8f,
101 OP_ABS: 0x90,
102 OP_NOT: 0x91,
103 OP_0NOTEQUAL: 0x92,
104
105 OP_ADD: 0x93,
106 OP_SUB: 0x94,
107 OP_MUL: 0x95,
108 OP_DIV: 0x96,
109 OP_MOD: 0x97,
110 OP_LSHIFT: 0x98,
111 OP_RSHIFT: 0x99,
112
113 OP_BOOLAND: 0x9a,
114 OP_BOOLOR: 0x9b,
115 OP_NUMEQUAL: 0x9c,
116 OP_NUMEQUALVERIFY: 0x9d,
117 OP_NUMNOTEQUAL: 0x9e,
118 OP_LESSTHAN: 0x9f,
119 OP_GREATERTHAN: 0xa0,
120 OP_LESSTHANOREQUAL: 0xa1,
121 OP_GREATERTHANOREQUAL: 0xa2,
122 OP_MIN: 0xa3,
123 OP_MAX: 0xa4,
124
125 OP_WITHIN: 0xa5,
126
127 // crypto
128 OP_RIPEMD160: 0xa6,
129 OP_SHA1: 0xa7,
130 OP_SHA256: 0xa8,
131 OP_HASH160: 0xa9,
132 OP_HASH256: 0xaa,
133 OP_CODESEPARATOR: 0xab,
134 OP_CHECKSIG: 0xac,
135 OP_CHECKSIGVERIFY: 0xad,
136 OP_CHECKMULTISIG: 0xae,
137 OP_CHECKMULTISIGVERIFY: 0xaf,
138
139 // expansion
140 OP_NOP1: 0xb0,
141 OP_NOP2: 0xb1,
142 OP_CHECKLOCKTIMEVERIFY: 0xb1,
143 OP_NOP3: 0xb2,
144 OP_CHECKSEQUENCEVERIFY: 0xb2,
145 OP_NOP4: 0xb3,
146 OP_NOP5: 0xb4,
147 OP_NOP6: 0xb5,
148 OP_NOP7: 0xb6,
149 OP_NOP8: 0xb7,
150 OP_NOP9: 0xb8,
151 OP_NOP10: 0xb9,
152
153 // template matching params
154 OP_SMALLDATA: 0xf9,
155 OP_SMALLINTEGER: 0xfa,
156 OP_PUBKEYS: 0xfb,
157 OP_PUBKEYHASH: 0xfd,
158 OP_PUBKEY: 0xfe,
159
160 OP_INVALIDOPCODE: 0xff
161}
162
163class OpCode extends Struct {
164 constructor (num) {
165 super({ num })
166 }
167
168 fromNumber (num) {
169 this.num = num
170 return this
171 }
172
173 static fromNumber (num) {
174 return new this().fromNumber(num)
175 }
176
177 toNumber () {
178 return this.num
179 }
180
181 fromString (str) {
182 const num = map[str]
183 if (num === undefined) {
184 throw new Error('Invalid opCodeStr')
185 }
186 this.num = num
187 return this
188 }
189
190 static fromString (str) {
191 return new this().fromString(str)
192 }
193
194 toString () {
195 const str = OpCode.str[this.num]
196 if (str === undefined) {
197 if (this.num > 0 && this.num < OpCode.OP_PUSHDATA1) {
198 return this.num.toString()
199 }
200 throw new Error('OpCode does not have a string representation')
201 }
202 return str
203 }
204}
205
206OpCode.str = {}
207
208for (const opCodeStr in map) {
209 OpCode[opCodeStr] = map[opCodeStr]
210
211 if (Object.prototype.hasOwnProperty.call(map, opCodeStr)) {
212 OpCode.str[map[opCodeStr]] = opCodeStr
213 }
214}
215
216export { OpCode }