@exodus/bitcoinjs-lib-forks 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -0
- package/LICENSE +21 -0
- package/README.md +207 -0
- package/package.json +67 -0
- package/src/address.js +97 -0
- package/src/block.js +177 -0
- package/src/bufferutils.js +56 -0
- package/src/crypto.js +29 -0
- package/src/ecdsa.js +161 -0
- package/src/ecpair.js +131 -0
- package/src/ecsignature.js +97 -0
- package/src/hdnode.js +316 -0
- package/src/index.js +23 -0
- package/src/networks.js +47 -0
- package/src/script.js +214 -0
- package/src/script_number.js +68 -0
- package/src/templates/index.js +74 -0
- package/src/templates/multisig/index.js +4 -0
- package/src/templates/multisig/input.js +71 -0
- package/src/templates/multisig/output.js +64 -0
- package/src/templates/nulldata.js +34 -0
- package/src/templates/pubkey/index.js +4 -0
- package/src/templates/pubkey/input.js +39 -0
- package/src/templates/pubkey/output.js +33 -0
- package/src/templates/pubkeyhash/index.js +4 -0
- package/src/templates/pubkeyhash/input.js +51 -0
- package/src/templates/pubkeyhash/output.js +42 -0
- package/src/templates/scripthash/index.js +4 -0
- package/src/templates/scripthash/input.js +84 -0
- package/src/templates/scripthash/output.js +34 -0
- package/src/templates/witnesscommitment/index.js +3 -0
- package/src/templates/witnesscommitment/output.js +42 -0
- package/src/templates/witnesspubkeyhash/index.js +4 -0
- package/src/templates/witnesspubkeyhash/input.js +44 -0
- package/src/templates/witnesspubkeyhash/output.js +33 -0
- package/src/templates/witnessscripthash/index.js +4 -0
- package/src/templates/witnessscripthash/input.js +63 -0
- package/src/templates/witnessscripthash/output.js +33 -0
- package/src/transaction.js +547 -0
- package/src/transaction_builder.js +825 -0
- package/src/types.js +53 -0
package/src/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
var script = require('./script')
|
|
2
|
+
|
|
3
|
+
var templates = require('./templates')
|
|
4
|
+
for (var key in templates) {
|
|
5
|
+
script[key] = templates[key]
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
bufferutils: require('./bufferutils'), // TODO: remove in 4.0.0
|
|
10
|
+
|
|
11
|
+
Block: require('./block'),
|
|
12
|
+
ECPair: require('./ecpair'),
|
|
13
|
+
ECSignature: require('./ecsignature'),
|
|
14
|
+
HDNode: require('./hdnode'),
|
|
15
|
+
Transaction: require('./transaction'),
|
|
16
|
+
TransactionBuilder: require('./transaction_builder'),
|
|
17
|
+
|
|
18
|
+
address: require('./address'),
|
|
19
|
+
crypto: require('./crypto'),
|
|
20
|
+
networks: require('./networks'),
|
|
21
|
+
opcodes: require('bitcoin-ops'),
|
|
22
|
+
script: script
|
|
23
|
+
}
|
package/src/networks.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// https://en.bitcoin.it/wiki/List_of_address_prefixes
|
|
2
|
+
// Dogecoin BIP32 is a proposed standard: https://bitcointalk.org/index.php?topic=409731
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
bitcoingold: {
|
|
6
|
+
messagePrefix: '\x18Bitcoin Gold Signed Message:\n',
|
|
7
|
+
bip32: {
|
|
8
|
+
public: 0x0488b21e,
|
|
9
|
+
private: 0x0488ade4
|
|
10
|
+
},
|
|
11
|
+
pubKeyHash: 0x26,
|
|
12
|
+
scriptHash: 0x17,
|
|
13
|
+
wif: 0x80
|
|
14
|
+
},
|
|
15
|
+
bitcoin: {
|
|
16
|
+
messagePrefix: '\x18Bitcoin Signed Message:\n',
|
|
17
|
+
bech32: 'bc',
|
|
18
|
+
bip32: {
|
|
19
|
+
public: 0x0488b21e,
|
|
20
|
+
private: 0x0488ade4
|
|
21
|
+
},
|
|
22
|
+
pubKeyHash: 0x00,
|
|
23
|
+
scriptHash: 0x05,
|
|
24
|
+
wif: 0x80
|
|
25
|
+
},
|
|
26
|
+
testnet: {
|
|
27
|
+
messagePrefix: '\x18Bitcoin Signed Message:\n',
|
|
28
|
+
bech32: 'tb',
|
|
29
|
+
bip32: {
|
|
30
|
+
public: 0x043587cf,
|
|
31
|
+
private: 0x04358394
|
|
32
|
+
},
|
|
33
|
+
pubKeyHash: 0x6f,
|
|
34
|
+
scriptHash: 0xc4,
|
|
35
|
+
wif: 0xef
|
|
36
|
+
},
|
|
37
|
+
litecoin: {
|
|
38
|
+
messagePrefix: '\x19Litecoin Signed Message:\n',
|
|
39
|
+
bip32: {
|
|
40
|
+
public: 0x019da462,
|
|
41
|
+
private: 0x019d9cfe
|
|
42
|
+
},
|
|
43
|
+
pubKeyHash: 0x30,
|
|
44
|
+
scriptHash: 0x32,
|
|
45
|
+
wif: 0xb0
|
|
46
|
+
}
|
|
47
|
+
}
|
package/src/script.js
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
var Buffer = require('safe-buffer').Buffer
|
|
2
|
+
var bip66 = require('bip66')
|
|
3
|
+
var pushdata = require('pushdata-bitcoin')
|
|
4
|
+
var typeforce = require('typeforce')
|
|
5
|
+
var types = require('./types')
|
|
6
|
+
var scriptNumber = require('./script_number')
|
|
7
|
+
|
|
8
|
+
var OPS = require('bitcoin-ops')
|
|
9
|
+
var REVERSE_OPS = require('bitcoin-ops/map')
|
|
10
|
+
var OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1
|
|
11
|
+
|
|
12
|
+
function isOPInt (value) {
|
|
13
|
+
return types.Number(value) &&
|
|
14
|
+
((value === OPS.OP_0) ||
|
|
15
|
+
(value >= OPS.OP_1 && value <= OPS.OP_16) ||
|
|
16
|
+
(value === OPS.OP_1NEGATE))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function isPushOnlyChunk (value) {
|
|
20
|
+
return types.Buffer(value) || isOPInt(value)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isPushOnly (value) {
|
|
24
|
+
return types.Array(value) && value.every(isPushOnlyChunk)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function asMinimalOP (buffer) {
|
|
28
|
+
if (buffer.length === 0) return OPS.OP_0
|
|
29
|
+
if (buffer.length !== 1) return
|
|
30
|
+
if (buffer[0] >= 1 && buffer[0] <= 16) return OP_INT_BASE + buffer[0]
|
|
31
|
+
if (buffer[0] === 0x81) return OPS.OP_1NEGATE
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function compile (chunks) {
|
|
35
|
+
// TODO: remove me
|
|
36
|
+
if (Buffer.isBuffer(chunks)) return chunks
|
|
37
|
+
|
|
38
|
+
typeforce(types.Array, chunks)
|
|
39
|
+
|
|
40
|
+
var bufferSize = chunks.reduce(function (accum, chunk) {
|
|
41
|
+
// data chunk
|
|
42
|
+
if (Buffer.isBuffer(chunk)) {
|
|
43
|
+
// adhere to BIP62.3, minimal push policy
|
|
44
|
+
if (chunk.length === 1 && asMinimalOP(chunk) !== undefined) {
|
|
45
|
+
return accum + 1
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return accum + pushdata.encodingLength(chunk.length) + chunk.length
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// opcode
|
|
52
|
+
return accum + 1
|
|
53
|
+
}, 0.0)
|
|
54
|
+
|
|
55
|
+
var buffer = Buffer.allocUnsafe(bufferSize)
|
|
56
|
+
var offset = 0
|
|
57
|
+
|
|
58
|
+
chunks.forEach(function (chunk) {
|
|
59
|
+
// data chunk
|
|
60
|
+
if (Buffer.isBuffer(chunk)) {
|
|
61
|
+
// adhere to BIP62.3, minimal push policy
|
|
62
|
+
var opcode = asMinimalOP(chunk)
|
|
63
|
+
if (opcode !== undefined) {
|
|
64
|
+
buffer.writeUInt8(opcode, offset)
|
|
65
|
+
offset += 1
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
offset += pushdata.encode(buffer, chunk.length, offset)
|
|
70
|
+
chunk.copy(buffer, offset)
|
|
71
|
+
offset += chunk.length
|
|
72
|
+
|
|
73
|
+
// opcode
|
|
74
|
+
} else {
|
|
75
|
+
buffer.writeUInt8(chunk, offset)
|
|
76
|
+
offset += 1
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
if (offset !== buffer.length) throw new Error('Could not decode chunks')
|
|
81
|
+
return buffer
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function decompile (buffer) {
|
|
85
|
+
// TODO: remove me
|
|
86
|
+
if (types.Array(buffer)) return buffer
|
|
87
|
+
|
|
88
|
+
typeforce(types.Buffer, buffer)
|
|
89
|
+
|
|
90
|
+
var chunks = []
|
|
91
|
+
var i = 0
|
|
92
|
+
|
|
93
|
+
while (i < buffer.length) {
|
|
94
|
+
var opcode = buffer[i]
|
|
95
|
+
|
|
96
|
+
// data chunk
|
|
97
|
+
if ((opcode > OPS.OP_0) && (opcode <= OPS.OP_PUSHDATA4)) {
|
|
98
|
+
var d = pushdata.decode(buffer, i)
|
|
99
|
+
|
|
100
|
+
// did reading a pushDataInt fail? empty script
|
|
101
|
+
if (d === null) return []
|
|
102
|
+
i += d.size
|
|
103
|
+
|
|
104
|
+
// attempt to read too much data? empty script
|
|
105
|
+
if (i + d.number > buffer.length) return []
|
|
106
|
+
|
|
107
|
+
var data = buffer.slice(i, i + d.number)
|
|
108
|
+
i += d.number
|
|
109
|
+
|
|
110
|
+
// decompile minimally
|
|
111
|
+
var op = asMinimalOP(data)
|
|
112
|
+
if (op !== undefined) {
|
|
113
|
+
chunks.push(op)
|
|
114
|
+
} else {
|
|
115
|
+
chunks.push(data)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// opcode
|
|
119
|
+
} else {
|
|
120
|
+
chunks.push(opcode)
|
|
121
|
+
|
|
122
|
+
i += 1
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return chunks
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function toASM (chunks) {
|
|
130
|
+
if (Buffer.isBuffer(chunks)) {
|
|
131
|
+
chunks = decompile(chunks)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return chunks.map(function (chunk) {
|
|
135
|
+
// data?
|
|
136
|
+
if (Buffer.isBuffer(chunk)) {
|
|
137
|
+
var op = asMinimalOP(chunk)
|
|
138
|
+
if (op === undefined) return chunk.toString('hex')
|
|
139
|
+
chunk = op
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// opcode!
|
|
143
|
+
return REVERSE_OPS[chunk]
|
|
144
|
+
}).join(' ')
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function fromASM (asm) {
|
|
148
|
+
typeforce(types.String, asm)
|
|
149
|
+
|
|
150
|
+
return compile(asm.split(' ').map(function (chunkStr) {
|
|
151
|
+
// opcode?
|
|
152
|
+
if (OPS[chunkStr] !== undefined) return OPS[chunkStr]
|
|
153
|
+
typeforce(types.Hex, chunkStr)
|
|
154
|
+
|
|
155
|
+
// data!
|
|
156
|
+
return Buffer.from(chunkStr, 'hex')
|
|
157
|
+
}))
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function toStack (chunks) {
|
|
161
|
+
chunks = decompile(chunks)
|
|
162
|
+
typeforce(isPushOnly, chunks)
|
|
163
|
+
|
|
164
|
+
return chunks.map(function (op) {
|
|
165
|
+
if (Buffer.isBuffer(op)) return op
|
|
166
|
+
if (op === OPS.OP_0) return Buffer.allocUnsafe(0)
|
|
167
|
+
|
|
168
|
+
return scriptNumber.encode(op - OP_INT_BASE)
|
|
169
|
+
})
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function isCanonicalPubKey (buffer) {
|
|
173
|
+
if (!Buffer.isBuffer(buffer)) return false
|
|
174
|
+
if (buffer.length < 33) return false
|
|
175
|
+
|
|
176
|
+
switch (buffer[0]) {
|
|
177
|
+
case 0x02:
|
|
178
|
+
case 0x03:
|
|
179
|
+
return buffer.length === 33
|
|
180
|
+
case 0x04:
|
|
181
|
+
return buffer.length === 65
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return false
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function isDefinedHashType (hashType) {
|
|
188
|
+
var hashTypeMod = hashType & ~0xc0
|
|
189
|
+
|
|
190
|
+
// return hashTypeMod > SIGHASH_ALL && hashTypeMod < SIGHASH_SINGLE
|
|
191
|
+
return hashTypeMod > 0x00 && hashTypeMod < 0x04
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function isCanonicalSignature (buffer) {
|
|
195
|
+
if (!Buffer.isBuffer(buffer)) return false
|
|
196
|
+
if (!isDefinedHashType(buffer[buffer.length - 1])) return false
|
|
197
|
+
|
|
198
|
+
return bip66.check(buffer.slice(0, -1))
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
module.exports = {
|
|
202
|
+
compile: compile,
|
|
203
|
+
decompile: decompile,
|
|
204
|
+
fromASM: fromASM,
|
|
205
|
+
toASM: toASM,
|
|
206
|
+
toStack: toStack,
|
|
207
|
+
|
|
208
|
+
number: require('./script_number'),
|
|
209
|
+
|
|
210
|
+
isCanonicalPubKey: isCanonicalPubKey,
|
|
211
|
+
isCanonicalSignature: isCanonicalSignature,
|
|
212
|
+
isPushOnly: isPushOnly,
|
|
213
|
+
isDefinedHashType: isDefinedHashType
|
|
214
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
var Buffer = require('safe-buffer').Buffer
|
|
2
|
+
|
|
3
|
+
function decode (buffer, maxLength, minimal) {
|
|
4
|
+
maxLength = maxLength || 4
|
|
5
|
+
minimal = minimal === undefined ? true : minimal
|
|
6
|
+
|
|
7
|
+
var length = buffer.length
|
|
8
|
+
if (length === 0) return 0
|
|
9
|
+
if (length > maxLength) throw new TypeError('Script number overflow')
|
|
10
|
+
if (minimal) {
|
|
11
|
+
if ((buffer[length - 1] & 0x7f) === 0) {
|
|
12
|
+
if (length <= 1 || (buffer[length - 2] & 0x80) === 0) throw new Error('Non-minimally encoded script number')
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// 40-bit
|
|
17
|
+
if (length === 5) {
|
|
18
|
+
var a = buffer.readUInt32LE(0)
|
|
19
|
+
var b = buffer.readUInt8(4)
|
|
20
|
+
|
|
21
|
+
if (b & 0x80) return -(((b & ~0x80) * 0x100000000) + a)
|
|
22
|
+
return (b * 0x100000000) + a
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
var result = 0
|
|
26
|
+
|
|
27
|
+
// 32-bit / 24-bit / 16-bit / 8-bit
|
|
28
|
+
for (var i = 0; i < length; ++i) {
|
|
29
|
+
result |= buffer[i] << (8 * i)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (buffer[length - 1] & 0x80) return -(result & ~(0x80 << (8 * (length - 1))))
|
|
33
|
+
return result
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function scriptNumSize (i) {
|
|
37
|
+
return i > 0x7fffffff ? 5
|
|
38
|
+
: i > 0x7fffff ? 4
|
|
39
|
+
: i > 0x7fff ? 3
|
|
40
|
+
: i > 0x7f ? 2
|
|
41
|
+
: i > 0x00 ? 1
|
|
42
|
+
: 0
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function encode (number) {
|
|
46
|
+
var value = Math.abs(number)
|
|
47
|
+
var size = scriptNumSize(value)
|
|
48
|
+
var buffer = Buffer.allocUnsafe(size)
|
|
49
|
+
var negative = number < 0
|
|
50
|
+
|
|
51
|
+
for (var i = 0; i < size; ++i) {
|
|
52
|
+
buffer.writeUInt8(value & 0xff, i)
|
|
53
|
+
value >>= 8
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (buffer[size - 1] & 0x80) {
|
|
57
|
+
buffer.writeUInt8(negative ? 0x80 : 0x00, size - 1)
|
|
58
|
+
} else if (negative) {
|
|
59
|
+
buffer[size - 1] |= 0x80
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return buffer
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = {
|
|
66
|
+
decode: decode,
|
|
67
|
+
encode: encode
|
|
68
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
var decompile = require('../script').decompile
|
|
2
|
+
var multisig = require('./multisig')
|
|
3
|
+
var nullData = require('./nulldata')
|
|
4
|
+
var pubKey = require('./pubkey')
|
|
5
|
+
var pubKeyHash = require('./pubkeyhash')
|
|
6
|
+
var scriptHash = require('./scripthash')
|
|
7
|
+
var witnessPubKeyHash = require('./witnesspubkeyhash')
|
|
8
|
+
var witnessScriptHash = require('./witnessscripthash')
|
|
9
|
+
var witnessCommitment = require('./witnesscommitment')
|
|
10
|
+
|
|
11
|
+
var types = {
|
|
12
|
+
MULTISIG: 'multisig',
|
|
13
|
+
NONSTANDARD: 'nonstandard',
|
|
14
|
+
NULLDATA: 'nulldata',
|
|
15
|
+
P2PK: 'pubkey',
|
|
16
|
+
P2PKH: 'pubkeyhash',
|
|
17
|
+
P2SH: 'scripthash',
|
|
18
|
+
P2WPKH: 'witnesspubkeyhash',
|
|
19
|
+
P2WSH: 'witnessscripthash',
|
|
20
|
+
WITNESS_COMMITMENT: 'witnesscommitment'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function classifyOutput (script) {
|
|
24
|
+
if (witnessPubKeyHash.output.check(script)) return types.P2WPKH
|
|
25
|
+
if (witnessScriptHash.output.check(script)) return types.P2WSH
|
|
26
|
+
if (pubKeyHash.output.check(script)) return types.P2PKH
|
|
27
|
+
if (scriptHash.output.check(script)) return types.P2SH
|
|
28
|
+
|
|
29
|
+
// XXX: optimization, below functions .decompile before use
|
|
30
|
+
var chunks = decompile(script)
|
|
31
|
+
if (multisig.output.check(chunks)) return types.MULTISIG
|
|
32
|
+
if (pubKey.output.check(chunks)) return types.P2PK
|
|
33
|
+
if (witnessCommitment.output.check(chunks)) return types.WITNESS_COMMITMENT
|
|
34
|
+
if (nullData.output.check(chunks)) return types.NULLDATA
|
|
35
|
+
|
|
36
|
+
return types.NONSTANDARD
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function classifyInput (script, allowIncomplete) {
|
|
40
|
+
// XXX: optimization, below functions .decompile before use
|
|
41
|
+
var chunks = decompile(script)
|
|
42
|
+
|
|
43
|
+
if (pubKeyHash.input.check(chunks)) return types.P2PKH
|
|
44
|
+
if (scriptHash.input.check(chunks, allowIncomplete)) return types.P2SH
|
|
45
|
+
if (multisig.input.check(chunks, allowIncomplete)) return types.MULTISIG
|
|
46
|
+
if (pubKey.input.check(chunks)) return types.P2PK
|
|
47
|
+
|
|
48
|
+
return types.NONSTANDARD
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function classifyWitness (script, allowIncomplete) {
|
|
52
|
+
// XXX: optimization, below functions .decompile before use
|
|
53
|
+
var chunks = decompile(script)
|
|
54
|
+
|
|
55
|
+
if (witnessPubKeyHash.input.check(chunks)) return types.P2WPKH
|
|
56
|
+
if (witnessScriptHash.input.check(chunks, allowIncomplete)) return types.P2WSH
|
|
57
|
+
|
|
58
|
+
return types.NONSTANDARD
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = {
|
|
62
|
+
classifyInput: classifyInput,
|
|
63
|
+
classifyOutput: classifyOutput,
|
|
64
|
+
classifyWitness: classifyWitness,
|
|
65
|
+
multisig: multisig,
|
|
66
|
+
nullData: nullData,
|
|
67
|
+
pubKey: pubKey,
|
|
68
|
+
pubKeyHash: pubKeyHash,
|
|
69
|
+
scriptHash: scriptHash,
|
|
70
|
+
witnessPubKeyHash: witnessPubKeyHash,
|
|
71
|
+
witnessScriptHash: witnessScriptHash,
|
|
72
|
+
witnessCommitment: witnessCommitment,
|
|
73
|
+
types: types
|
|
74
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// OP_0 [signatures ...]
|
|
2
|
+
|
|
3
|
+
var Buffer = require('safe-buffer').Buffer
|
|
4
|
+
var bscript = require('../../script')
|
|
5
|
+
var p2mso = require('./output')
|
|
6
|
+
var typeforce = require('typeforce')
|
|
7
|
+
var OPS = require('bitcoin-ops')
|
|
8
|
+
|
|
9
|
+
function partialSignature (value) {
|
|
10
|
+
return value === OPS.OP_0 || bscript.isCanonicalSignature(value)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function check (script, allowIncomplete) {
|
|
14
|
+
var chunks = bscript.decompile(script)
|
|
15
|
+
if (chunks.length < 2) return false
|
|
16
|
+
if (chunks[0] !== OPS.OP_0) return false
|
|
17
|
+
|
|
18
|
+
if (allowIncomplete) {
|
|
19
|
+
return chunks.slice(1).every(partialSignature)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return chunks.slice(1).every(bscript.isCanonicalSignature)
|
|
23
|
+
}
|
|
24
|
+
check.toJSON = function () { return 'multisig input' }
|
|
25
|
+
|
|
26
|
+
var EMPTY_BUFFER = Buffer.allocUnsafe(0)
|
|
27
|
+
|
|
28
|
+
function encodeStack (signatures, scriptPubKey) {
|
|
29
|
+
typeforce([partialSignature], signatures)
|
|
30
|
+
|
|
31
|
+
if (scriptPubKey) {
|
|
32
|
+
var scriptData = p2mso.decode(scriptPubKey)
|
|
33
|
+
|
|
34
|
+
if (signatures.length < scriptData.m) {
|
|
35
|
+
throw new TypeError('Not enough signatures provided')
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (signatures.length > scriptData.pubKeys.length) {
|
|
39
|
+
throw new TypeError('Too many signatures provided')
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return [].concat(EMPTY_BUFFER, signatures.map(function (sig) {
|
|
44
|
+
if (sig === OPS.OP_0) {
|
|
45
|
+
return EMPTY_BUFFER
|
|
46
|
+
}
|
|
47
|
+
return sig
|
|
48
|
+
}))
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function encode (signatures, scriptPubKey) {
|
|
52
|
+
return bscript.compile(encodeStack(signatures, scriptPubKey))
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function decodeStack (stack, allowIncomplete) {
|
|
56
|
+
typeforce(check, stack, allowIncomplete)
|
|
57
|
+
return stack.slice(1)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function decode (buffer, allowIncomplete) {
|
|
61
|
+
var stack = bscript.decompile(buffer)
|
|
62
|
+
return decodeStack(stack, allowIncomplete)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = {
|
|
66
|
+
check: check,
|
|
67
|
+
decode: decode,
|
|
68
|
+
decodeStack: decodeStack,
|
|
69
|
+
encode: encode,
|
|
70
|
+
encodeStack: encodeStack
|
|
71
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// m [pubKeys ...] n OP_CHECKMULTISIG
|
|
2
|
+
|
|
3
|
+
var bscript = require('../../script')
|
|
4
|
+
var types = require('../../types')
|
|
5
|
+
var typeforce = require('typeforce')
|
|
6
|
+
var OPS = require('bitcoin-ops')
|
|
7
|
+
var OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1
|
|
8
|
+
|
|
9
|
+
function check (script, allowIncomplete) {
|
|
10
|
+
var chunks = bscript.decompile(script)
|
|
11
|
+
|
|
12
|
+
if (chunks.length < 4) return false
|
|
13
|
+
if (chunks[chunks.length - 1] !== OPS.OP_CHECKMULTISIG) return false
|
|
14
|
+
if (!types.Number(chunks[0])) return false
|
|
15
|
+
if (!types.Number(chunks[chunks.length - 2])) return false
|
|
16
|
+
var m = chunks[0] - OP_INT_BASE
|
|
17
|
+
var n = chunks[chunks.length - 2] - OP_INT_BASE
|
|
18
|
+
|
|
19
|
+
if (m <= 0) return false
|
|
20
|
+
if (n > 16) return false
|
|
21
|
+
if (m > n) return false
|
|
22
|
+
if (n !== chunks.length - 3) return false
|
|
23
|
+
if (allowIncomplete) return true
|
|
24
|
+
|
|
25
|
+
var keys = chunks.slice(1, -2)
|
|
26
|
+
return keys.every(bscript.isCanonicalPubKey)
|
|
27
|
+
}
|
|
28
|
+
check.toJSON = function () { return 'multi-sig output' }
|
|
29
|
+
|
|
30
|
+
function encode (m, pubKeys) {
|
|
31
|
+
typeforce({
|
|
32
|
+
m: types.Number,
|
|
33
|
+
pubKeys: [bscript.isCanonicalPubKey]
|
|
34
|
+
}, {
|
|
35
|
+
m: m,
|
|
36
|
+
pubKeys: pubKeys
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
var n = pubKeys.length
|
|
40
|
+
if (n < m) throw new TypeError('Not enough pubKeys provided')
|
|
41
|
+
|
|
42
|
+
return bscript.compile([].concat(
|
|
43
|
+
OP_INT_BASE + m,
|
|
44
|
+
pubKeys,
|
|
45
|
+
OP_INT_BASE + n,
|
|
46
|
+
OPS.OP_CHECKMULTISIG
|
|
47
|
+
))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function decode (buffer, allowIncomplete) {
|
|
51
|
+
var chunks = bscript.decompile(buffer)
|
|
52
|
+
typeforce(check, chunks, allowIncomplete)
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
m: chunks[0] - OP_INT_BASE,
|
|
56
|
+
pubKeys: chunks.slice(1, -2)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = {
|
|
61
|
+
check: check,
|
|
62
|
+
decode: decode,
|
|
63
|
+
encode: encode
|
|
64
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// OP_RETURN {data}
|
|
2
|
+
|
|
3
|
+
var bscript = require('../script')
|
|
4
|
+
var types = require('../types')
|
|
5
|
+
var typeforce = require('typeforce')
|
|
6
|
+
var OPS = require('bitcoin-ops')
|
|
7
|
+
|
|
8
|
+
function check (script) {
|
|
9
|
+
var buffer = bscript.compile(script)
|
|
10
|
+
|
|
11
|
+
return buffer.length > 1 &&
|
|
12
|
+
buffer[0] === OPS.OP_RETURN
|
|
13
|
+
}
|
|
14
|
+
check.toJSON = function () { return 'null data output' }
|
|
15
|
+
|
|
16
|
+
function encode (data) {
|
|
17
|
+
typeforce(types.Buffer, data)
|
|
18
|
+
|
|
19
|
+
return bscript.compile([OPS.OP_RETURN, data])
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function decode (buffer) {
|
|
23
|
+
typeforce(check, buffer)
|
|
24
|
+
|
|
25
|
+
return buffer.slice(2)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = {
|
|
29
|
+
output: {
|
|
30
|
+
check: check,
|
|
31
|
+
decode: decode,
|
|
32
|
+
encode: encode
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// {signature}
|
|
2
|
+
|
|
3
|
+
var bscript = require('../../script')
|
|
4
|
+
var typeforce = require('typeforce')
|
|
5
|
+
|
|
6
|
+
function check (script) {
|
|
7
|
+
var chunks = bscript.decompile(script)
|
|
8
|
+
|
|
9
|
+
return chunks.length === 1 &&
|
|
10
|
+
bscript.isCanonicalSignature(chunks[0])
|
|
11
|
+
}
|
|
12
|
+
check.toJSON = function () { return 'pubKey input' }
|
|
13
|
+
|
|
14
|
+
function encodeStack (signature) {
|
|
15
|
+
typeforce(bscript.isCanonicalSignature, signature)
|
|
16
|
+
return [signature]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function encode (signature) {
|
|
20
|
+
return bscript.compile(encodeStack(signature))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function decodeStack (stack) {
|
|
24
|
+
typeforce(check, stack)
|
|
25
|
+
return stack[0]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function decode (buffer) {
|
|
29
|
+
var stack = bscript.decompile(buffer)
|
|
30
|
+
return decodeStack(stack)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = {
|
|
34
|
+
check: check,
|
|
35
|
+
decode: decode,
|
|
36
|
+
decodeStack: decodeStack,
|
|
37
|
+
encode: encode,
|
|
38
|
+
encodeStack: encodeStack
|
|
39
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// {pubKey} OP_CHECKSIG
|
|
2
|
+
|
|
3
|
+
var bscript = require('../../script')
|
|
4
|
+
var typeforce = require('typeforce')
|
|
5
|
+
var OPS = require('bitcoin-ops')
|
|
6
|
+
|
|
7
|
+
function check (script) {
|
|
8
|
+
var chunks = bscript.decompile(script)
|
|
9
|
+
|
|
10
|
+
return chunks.length === 2 &&
|
|
11
|
+
bscript.isCanonicalPubKey(chunks[0]) &&
|
|
12
|
+
chunks[1] === OPS.OP_CHECKSIG
|
|
13
|
+
}
|
|
14
|
+
check.toJSON = function () { return 'pubKey output' }
|
|
15
|
+
|
|
16
|
+
function encode (pubKey) {
|
|
17
|
+
typeforce(bscript.isCanonicalPubKey, pubKey)
|
|
18
|
+
|
|
19
|
+
return bscript.compile([pubKey, OPS.OP_CHECKSIG])
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function decode (buffer) {
|
|
23
|
+
var chunks = bscript.decompile(buffer)
|
|
24
|
+
typeforce(check, chunks)
|
|
25
|
+
|
|
26
|
+
return chunks[0]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = {
|
|
30
|
+
check: check,
|
|
31
|
+
decode: decode,
|
|
32
|
+
encode: encode
|
|
33
|
+
}
|