1 | 'use strict';
|
2 | Object.defineProperty(exports, '__esModule', { value: true });
|
3 | exports.signature =
|
4 | exports.number =
|
5 | exports.isCanonicalScriptSignature =
|
6 | exports.isDefinedHashType =
|
7 | exports.isCanonicalPubKey =
|
8 | exports.toStack =
|
9 | exports.fromASM =
|
10 | exports.toASM =
|
11 | exports.decompile =
|
12 | exports.compile =
|
13 | exports.countNonPushOnlyOPs =
|
14 | exports.isPushOnly =
|
15 | exports.OPS =
|
16 | void 0;
|
17 | const bip66 = require('./bip66');
|
18 | const ops_1 = require('./ops');
|
19 | Object.defineProperty(exports, 'OPS', {
|
20 | enumerable: true,
|
21 | get: function () {
|
22 | return ops_1.OPS;
|
23 | },
|
24 | });
|
25 | const pushdata = require('./push_data');
|
26 | const scriptNumber = require('./script_number');
|
27 | const scriptSignature = require('./script_signature');
|
28 | const types = require('./types');
|
29 | const { typeforce } = types;
|
30 | const OP_INT_BASE = ops_1.OPS.OP_RESERVED;
|
31 | function isOPInt(value) {
|
32 | return (
|
33 | types.Number(value) &&
|
34 | (value === ops_1.OPS.OP_0 ||
|
35 | (value >= ops_1.OPS.OP_1 && value <= ops_1.OPS.OP_16) ||
|
36 | value === ops_1.OPS.OP_1NEGATE)
|
37 | );
|
38 | }
|
39 | function isPushOnlyChunk(value) {
|
40 | return types.Buffer(value) || isOPInt(value);
|
41 | }
|
42 | function isPushOnly(value) {
|
43 | return types.Array(value) && value.every(isPushOnlyChunk);
|
44 | }
|
45 | exports.isPushOnly = isPushOnly;
|
46 | function countNonPushOnlyOPs(value) {
|
47 | return value.length - value.filter(isPushOnlyChunk).length;
|
48 | }
|
49 | exports.countNonPushOnlyOPs = countNonPushOnlyOPs;
|
50 | function asMinimalOP(buffer) {
|
51 | if (buffer.length === 0) return ops_1.OPS.OP_0;
|
52 | if (buffer.length !== 1) return;
|
53 | if (buffer[0] >= 1 && buffer[0] <= 16) return OP_INT_BASE + buffer[0];
|
54 | if (buffer[0] === 0x81) return ops_1.OPS.OP_1NEGATE;
|
55 | }
|
56 | function chunksIsBuffer(buf) {
|
57 | return Buffer.isBuffer(buf);
|
58 | }
|
59 | function chunksIsArray(buf) {
|
60 | return types.Array(buf);
|
61 | }
|
62 | function singleChunkIsBuffer(buf) {
|
63 | return Buffer.isBuffer(buf);
|
64 | }
|
65 | function compile(chunks) {
|
66 |
|
67 | if (chunksIsBuffer(chunks)) return chunks;
|
68 | typeforce(types.Array, chunks);
|
69 | const bufferSize = chunks.reduce((accum, chunk) => {
|
70 |
|
71 | if (singleChunkIsBuffer(chunk)) {
|
72 |
|
73 | if (chunk.length === 1 && asMinimalOP(chunk) !== undefined) {
|
74 | return accum + 1;
|
75 | }
|
76 | return accum + pushdata.encodingLength(chunk.length) + chunk.length;
|
77 | }
|
78 |
|
79 | return accum + 1;
|
80 | }, 0.0);
|
81 | const buffer = Buffer.allocUnsafe(bufferSize);
|
82 | let offset = 0;
|
83 | chunks.forEach(chunk => {
|
84 |
|
85 | if (singleChunkIsBuffer(chunk)) {
|
86 |
|
87 | const opcode = asMinimalOP(chunk);
|
88 | if (opcode !== undefined) {
|
89 | buffer.writeUInt8(opcode, offset);
|
90 | offset += 1;
|
91 | return;
|
92 | }
|
93 | offset += pushdata.encode(buffer, chunk.length, offset);
|
94 | chunk.copy(buffer, offset);
|
95 | offset += chunk.length;
|
96 |
|
97 | } else {
|
98 | buffer.writeUInt8(chunk, offset);
|
99 | offset += 1;
|
100 | }
|
101 | });
|
102 | if (offset !== buffer.length) throw new Error('Could not decode chunks');
|
103 | return buffer;
|
104 | }
|
105 | exports.compile = compile;
|
106 | function decompile(buffer) {
|
107 |
|
108 | if (chunksIsArray(buffer)) return buffer;
|
109 | typeforce(types.Buffer, buffer);
|
110 | const chunks = [];
|
111 | let i = 0;
|
112 | while (i < buffer.length) {
|
113 | const opcode = buffer[i];
|
114 |
|
115 | if (opcode > ops_1.OPS.OP_0 && opcode <= ops_1.OPS.OP_PUSHDATA4) {
|
116 | const d = pushdata.decode(buffer, i);
|
117 |
|
118 | if (d === null) return null;
|
119 | i += d.size;
|
120 |
|
121 | if (i + d.number > buffer.length) return null;
|
122 | const data = buffer.slice(i, i + d.number);
|
123 | i += d.number;
|
124 |
|
125 | const op = asMinimalOP(data);
|
126 | if (op !== undefined) {
|
127 | chunks.push(op);
|
128 | } else {
|
129 | chunks.push(data);
|
130 | }
|
131 |
|
132 | } else {
|
133 | chunks.push(opcode);
|
134 | i += 1;
|
135 | }
|
136 | }
|
137 | return chunks;
|
138 | }
|
139 | exports.decompile = decompile;
|
140 | function toASM(chunks) {
|
141 | if (chunksIsBuffer(chunks)) {
|
142 | chunks = decompile(chunks);
|
143 | }
|
144 | return chunks
|
145 | .map(chunk => {
|
146 |
|
147 | if (singleChunkIsBuffer(chunk)) {
|
148 | const op = asMinimalOP(chunk);
|
149 | if (op === undefined) return chunk.toString('hex');
|
150 | chunk = op;
|
151 | }
|
152 |
|
153 | return ops_1.REVERSE_OPS[chunk];
|
154 | })
|
155 | .join(' ');
|
156 | }
|
157 | exports.toASM = toASM;
|
158 | function fromASM(asm) {
|
159 | typeforce(types.String, asm);
|
160 | return compile(
|
161 | asm.split(' ').map(chunkStr => {
|
162 |
|
163 | if (ops_1.OPS[chunkStr] !== undefined) return ops_1.OPS[chunkStr];
|
164 | typeforce(types.Hex, chunkStr);
|
165 |
|
166 | return Buffer.from(chunkStr, 'hex');
|
167 | }),
|
168 | );
|
169 | }
|
170 | exports.fromASM = fromASM;
|
171 | function toStack(chunks) {
|
172 | chunks = decompile(chunks);
|
173 | typeforce(isPushOnly, chunks);
|
174 | return chunks.map(op => {
|
175 | if (singleChunkIsBuffer(op)) return op;
|
176 | if (op === ops_1.OPS.OP_0) return Buffer.allocUnsafe(0);
|
177 | return scriptNumber.encode(op - OP_INT_BASE);
|
178 | });
|
179 | }
|
180 | exports.toStack = toStack;
|
181 | function isCanonicalPubKey(buffer) {
|
182 | return types.isPoint(buffer);
|
183 | }
|
184 | exports.isCanonicalPubKey = isCanonicalPubKey;
|
185 | function isDefinedHashType(hashType) {
|
186 | const hashTypeMod = hashType & ~0x80;
|
187 |
|
188 | return hashTypeMod > 0x00 && hashTypeMod < 0x04;
|
189 | }
|
190 | exports.isDefinedHashType = isDefinedHashType;
|
191 | function isCanonicalScriptSignature(buffer) {
|
192 | if (!Buffer.isBuffer(buffer)) return false;
|
193 | if (!isDefinedHashType(buffer[buffer.length - 1])) return false;
|
194 | return bip66.check(buffer.slice(0, -1));
|
195 | }
|
196 | exports.isCanonicalScriptSignature = isCanonicalScriptSignature;
|
197 | exports.number = scriptNumber;
|
198 | exports.signature = scriptSignature;
|