1 | 'use strict'
|
2 |
|
3 | var _ = require('./util/_')
|
4 | var $ = require('./util/preconditions')
|
5 | var JSUtil = require('./util/js')
|
6 |
|
7 | function 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 |
|
29 | Opcode.fromBuffer = function (buf) {
|
30 | $.checkArgument(Buffer.isBuffer(buf))
|
31 | return new Opcode(Number('0x' + buf.toString('hex')))
|
32 | }
|
33 |
|
34 | Opcode.fromNumber = function (num) {
|
35 | $.checkArgument(_.isNumber(num))
|
36 | return new Opcode(num)
|
37 | }
|
38 |
|
39 | Opcode.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 |
|
48 | Opcode.prototype.toHex = function () {
|
49 | return this.num.toString(16)
|
50 | }
|
51 |
|
52 | Opcode.prototype.toBuffer = function () {
|
53 | return Buffer.from(this.toHex(), 'hex')
|
54 | }
|
55 |
|
56 | Opcode.prototype.toNumber = function () {
|
57 | return this.num
|
58 | }
|
59 |
|
60 | Opcode.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 |
|
68 | Opcode.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 |
|
77 | Opcode.map = {
|
78 |
|
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 |
|
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 |
|
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 |
|
138 | OP_CAT: 126,
|
139 | OP_SPLIT: 127,
|
140 | OP_NUM2BIN: 128,
|
141 | OP_BIN2NUM: 129,
|
142 | OP_SIZE: 130,
|
143 |
|
144 |
|
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 |
|
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 |
|
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 |
|
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 |
|
214 | OP_PUBKEYHASH: 253,
|
215 | OP_PUBKEY: 254,
|
216 | OP_INVALIDOPCODE: 255
|
217 | }
|
218 |
|
219 | Opcode.reverseMap = []
|
220 |
|
221 | for (var k in Opcode.map) {
|
222 | Opcode.reverseMap[Opcode.map[k]] = k
|
223 | }
|
224 |
|
225 |
|
226 | _.extend(Opcode, Opcode.map)
|
227 |
|
228 |
|
229 |
|
230 |
|
231 | Opcode.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 |
|
241 |
|
242 |
|
243 |
|
244 | Opcode.prototype.inspect = function () {
|
245 | return '<Opcode: ' + this.toString() + ', hex: ' + this.toHex() + ', decimal: ' + this.num + '>'
|
246 | }
|
247 |
|
248 | module.exports = Opcode
|