UNPKG

4.6 kBJavaScriptView Raw
1'use strict'
2
3var _ = require('./util/_')
4var $ = require('./util/preconditions')
5var JSUtil = require('./util/js')
6
7function Opcode (num) {
8 if (!(this instanceof Opcode)) {
9 return new Opcode(num)
10 }
11
12 var value
13
14 if (_.isNumber(num)) {
15 value = num
16 } else if (_.isString(num)) {
17 value = Opcode.map[num]
18 } else {
19 throw new TypeError('Unrecognized num type: "' + typeof (num) + '" for Opcode')
20 }
21
22 JSUtil.defineImmutable(this, {
23 num: value
24 })
25
26 return this
27}
28
29Opcode.fromBuffer = function (buf) {
30 $.checkArgument(Buffer.isBuffer(buf))
31 return new Opcode(Number('0x' + buf.toString('hex')))
32}
33
34Opcode.fromNumber = function (num) {
35 $.checkArgument(_.isNumber(num))
36 return new Opcode(num)
37}
38
39Opcode.fromString = function (str) {
40 $.checkArgument(_.isString(str))
41 var value = Opcode.map[str]
42 if (typeof value === 'undefined') {
43 throw new TypeError('Invalid opcodestr')
44 }
45 return new Opcode(value)
46}
47
48Opcode.prototype.toHex = function () {
49 return this.num.toString(16)
50}
51
52Opcode.prototype.toBuffer = function () {
53 return Buffer.from(this.toHex(), 'hex')
54}
55
56Opcode.prototype.toNumber = function () {
57 return this.num
58}
59
60Opcode.prototype.toString = function () {
61 var str = Opcode.reverseMap[this.num]
62 if (typeof str === 'undefined') {
63 throw new Error('Opcode does not have a string representation')
64 }
65 return str
66}
67
68Opcode.smallInt = function (n) {
69 $.checkArgument(_.isNumber(n), 'Invalid Argument: n should be number')
70 $.checkArgument(n >= 0 && n <= 16, 'Invalid Argument: n must be between 0 and 16')
71 if (n === 0) {
72 return Opcode('OP_0')
73 }
74 return new Opcode(Opcode.map.OP_1 + n - 1)
75}
76
77Opcode.map = {
78 // push value
79 OP_FALSE: 0,
80 OP_0: 0,
81 OP_PUSHDATA1: 76,
82 OP_PUSHDATA2: 77,
83 OP_PUSHDATA4: 78,
84 OP_1NEGATE: 79,
85 OP_RESERVED: 80,
86 OP_TRUE: 81,
87 OP_1: 81,
88 OP_2: 82,
89 OP_3: 83,
90 OP_4: 84,
91 OP_5: 85,
92 OP_6: 86,
93 OP_7: 87,
94 OP_8: 88,
95 OP_9: 89,
96 OP_10: 90,
97 OP_11: 91,
98 OP_12: 92,
99 OP_13: 93,
100 OP_14: 94,
101 OP_15: 95,
102 OP_16: 96,
103
104 // control
105 OP_NOP: 97,
106 OP_VER: 98,
107 OP_IF: 99,
108 OP_NOTIF: 100,
109 OP_VERIF: 101,
110 OP_VERNOTIF: 102,
111 OP_ELSE: 103,
112 OP_ENDIF: 104,
113 OP_VERIFY: 105,
114 OP_RETURN: 106,
115
116 // stack ops
117 OP_TOALTSTACK: 107,
118 OP_FROMALTSTACK: 108,
119 OP_2DROP: 109,
120 OP_2DUP: 110,
121 OP_3DUP: 111,
122 OP_2OVER: 112,
123 OP_2ROT: 113,
124 OP_2SWAP: 114,
125 OP_IFDUP: 115,
126 OP_DEPTH: 116,
127 OP_DROP: 117,
128 OP_DUP: 118,
129 OP_NIP: 119,
130 OP_OVER: 120,
131 OP_PICK: 121,
132 OP_ROLL: 122,
133 OP_ROT: 123,
134 OP_SWAP: 124,
135 OP_TUCK: 125,
136
137 // splice ops
138 OP_CAT: 126,
139 OP_SPLIT: 127,
140 OP_NUM2BIN: 128,
141 OP_BIN2NUM: 129,
142 OP_SIZE: 130,
143
144 // bit logic
145 OP_INVERT: 131,
146 OP_AND: 132,
147 OP_OR: 133,
148 OP_XOR: 134,
149 OP_EQUAL: 135,
150 OP_EQUALVERIFY: 136,
151 OP_RESERVED1: 137,
152 OP_RESERVED2: 138,
153
154 // numeric
155 OP_1ADD: 139,
156 OP_1SUB: 140,
157 OP_2MUL: 141,
158 OP_2DIV: 142,
159 OP_NEGATE: 143,
160 OP_ABS: 144,
161 OP_NOT: 145,
162 OP_0NOTEQUAL: 146,
163
164 OP_ADD: 147,
165 OP_SUB: 148,
166 OP_MUL: 149,
167 OP_DIV: 150,
168 OP_MOD: 151,
169 OP_LSHIFT: 152,
170 OP_RSHIFT: 153,
171
172 OP_BOOLAND: 154,
173 OP_BOOLOR: 155,
174 OP_NUMEQUAL: 156,
175 OP_NUMEQUALVERIFY: 157,
176 OP_NUMNOTEQUAL: 158,
177 OP_LESSTHAN: 159,
178 OP_GREATERTHAN: 160,
179 OP_LESSTHANOREQUAL: 161,
180 OP_GREATERTHANOREQUAL: 162,
181 OP_MIN: 163,
182 OP_MAX: 164,
183
184 OP_WITHIN: 165,
185
186 // crypto
187 OP_RIPEMD160: 166,
188 OP_SHA1: 167,
189 OP_SHA256: 168,
190 OP_HASH160: 169,
191 OP_HASH256: 170,
192 OP_CODESEPARATOR: 171,
193 OP_CHECKSIG: 172,
194 OP_CHECKSIGVERIFY: 173,
195 OP_CHECKMULTISIG: 174,
196 OP_CHECKMULTISIGVERIFY: 175,
197
198 OP_CHECKLOCKTIMEVERIFY: 177,
199 OP_CHECKSEQUENCEVERIFY: 178,
200
201 // expansion
202 OP_NOP1: 176,
203 OP_NOP2: 177,
204 OP_NOP3: 178,
205 OP_NOP4: 179,
206 OP_NOP5: 180,
207 OP_NOP6: 181,
208 OP_NOP7: 182,
209 OP_NOP8: 183,
210 OP_NOP9: 184,
211 OP_NOP10: 185,
212
213 // template matching params
214 OP_PUBKEYHASH: 253,
215 OP_PUBKEY: 254,
216 OP_INVALIDOPCODE: 255
217}
218
219Opcode.reverseMap = []
220
221for (var k in Opcode.map) {
222 Opcode.reverseMap[Opcode.map[k]] = k
223}
224
225// Easier access to opcodes
226_.extend(Opcode, Opcode.map)
227
228/**
229 * @returns true if opcode is one of OP_0, OP_1, ..., OP_16
230 */
231Opcode.isSmallIntOp = function (opcode) {
232 if (opcode instanceof Opcode) {
233 opcode = opcode.toNumber()
234 }
235 return ((opcode === Opcode.map.OP_0) ||
236 ((opcode >= Opcode.map.OP_1) && (opcode <= Opcode.map.OP_16)))
237}
238
239/**
240 * Will return a string formatted for the console
241 *
242 * @returns {string} Script opcode
243 */
244Opcode.prototype.inspect = function () {
245 return '<Opcode: ' + this.toString() + ', hex: ' + this.toHex() + ', decimal: ' + this.num + '>'
246}
247
248module.exports = Opcode