@exodus/bitcoinjs-lib-forks 0.0.5 → 0.0.6
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/package.json +1 -2
- package/src/ecsignature.js +23 -90
- package/src/index.js +4 -20
- package/src/transaction_builder.js +0 -92
- package/src/types.js +0 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/bitcoinjs-lib-forks",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "Client-side Bitcoin Forks JavaScript library",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"engines": {
|
|
@@ -35,7 +35,6 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@exodus/crypto": "^1.0.0-rc.27",
|
|
37
37
|
"bech32": "0.0.3",
|
|
38
|
-
"bigi": "^1.4.0",
|
|
39
38
|
"bip66": "^1.1.0",
|
|
40
39
|
"bitcoin-ops": "^1.3.0",
|
|
41
40
|
"pushdata-bitcoin": "^1.0.1",
|
package/src/ecsignature.js
CHANGED
|
@@ -2,99 +2,32 @@ var bip66 = require('bip66')
|
|
|
2
2
|
var typeforce = require('typeforce')
|
|
3
3
|
var types = require('./types')
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
function
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
var flagByte = buffer.readUInt8(0) - 27
|
|
18
|
-
if (flagByte !== (flagByte & 7)) throw new Error('Invalid signature parameter')
|
|
19
|
-
|
|
20
|
-
var compressed = !!(flagByte & 4)
|
|
21
|
-
var recoveryParam = flagByte & 3
|
|
22
|
-
var signature = ECSignature.fromRSBuffer(buffer.slice(1))
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
compressed: compressed,
|
|
26
|
-
i: recoveryParam,
|
|
27
|
-
signature: signature
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
ECSignature.fromRSBuffer = function (buffer) {
|
|
5
|
+
// Parses buffer as an unsigned integer and converts to DER
|
|
6
|
+
// minimum width but highest bit is 0 for unsigned
|
|
7
|
+
function toDer (buf) {
|
|
8
|
+
let start = 0
|
|
9
|
+
while (start < buf.length && buf[start] === 0) start++
|
|
10
|
+
if (start > 0) buf = buf.slice(start)
|
|
11
|
+
if (buf.length === 0) return Buffer.alloc(1)
|
|
12
|
+
const prefix = Buffer.alloc(buf[0] >= 0x80 ? 1 : 0)
|
|
13
|
+
return Buffer.concat([prefix, buf]) // copies
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports.fromRSBuffer = function (buffer) {
|
|
32
17
|
typeforce(types.BufferN(64), buffer)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
var s = BigInteger.fromBuffer(buffer.slice(32, 64))
|
|
36
|
-
return new ECSignature(r, s)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
ECSignature.fromDER = function (buffer) {
|
|
40
|
-
var decode = bip66.decode(buffer)
|
|
41
|
-
var r = BigInteger.fromDERInteger(decode.r)
|
|
42
|
-
var s = BigInteger.fromDERInteger(decode.s)
|
|
43
|
-
|
|
44
|
-
return new ECSignature(r, s)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// BIP62: 1 byte hashType flag (only 0x01, 0x02, 0x03, 0x81, 0x82 and 0x83 are allowed)
|
|
48
|
-
ECSignature.parseScriptSignature = function (buffer) {
|
|
49
|
-
var hashType = buffer.readUInt8(buffer.length - 1)
|
|
50
|
-
var hashTypeMod = hashType & ~0xc0
|
|
51
|
-
|
|
52
|
-
if (hashTypeMod <= 0x00 || hashTypeMod >= 0x04) throw new Error('Invalid hashType ' + hashType)
|
|
18
|
+
const r = toDer(buffer.slice(0, 32))
|
|
19
|
+
const s = toDer(buffer.slice(32, 64))
|
|
53
20
|
|
|
54
21
|
return {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
ECSignature.prototype.toCompact = function (i, compressed) {
|
|
61
|
-
if (compressed) {
|
|
62
|
-
i += 4
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
i += 27
|
|
66
|
-
|
|
67
|
-
var buffer = Buffer.alloc(65)
|
|
68
|
-
buffer.writeUInt8(i, 0)
|
|
69
|
-
this.toRSBuffer(buffer, 1)
|
|
70
|
-
return buffer
|
|
71
|
-
}
|
|
22
|
+
toScriptSignature (hashType) {
|
|
23
|
+
var hashTypeMod = hashType & ~0xc0
|
|
24
|
+
if (hashTypeMod <= 0 || hashTypeMod >= 4) throw new Error('Invalid hashType ' + hashType)
|
|
72
25
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
var s = Buffer.from(this.s.toDERInteger())
|
|
26
|
+
var hashTypeBuffer = Buffer.alloc(1)
|
|
27
|
+
hashTypeBuffer.writeUInt8(hashType, 0)
|
|
76
28
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
ECSignature.prototype.toRSBuffer = function (buffer, offset, { canonical } = {}) {
|
|
82
|
-
buffer = buffer || Buffer.alloc(64)
|
|
83
|
-
this.r.toBuffer(32).copy(buffer, offset)
|
|
84
|
-
let s = this.s
|
|
85
|
-
if (canonical && s.compareTo(N) >= 0) s = N.subtract(s)
|
|
86
|
-
s.toBuffer(32).copy(buffer, offset + 32)
|
|
87
|
-
return buffer
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
ECSignature.prototype.toScriptSignature = function (hashType) {
|
|
91
|
-
var hashTypeMod = hashType & ~0xc0
|
|
92
|
-
if (hashTypeMod <= 0 || hashTypeMod >= 4) throw new Error('Invalid hashType ' + hashType)
|
|
93
|
-
|
|
94
|
-
var hashTypeBuffer = Buffer.alloc(1)
|
|
95
|
-
hashTypeBuffer.writeUInt8(hashType, 0)
|
|
96
|
-
|
|
97
|
-
return Buffer.concat([this.toDER(), hashTypeBuffer])
|
|
29
|
+
const der = bip66.encode(r, s)
|
|
30
|
+
return Buffer.concat([der, hashTypeBuffer])
|
|
31
|
+
}
|
|
32
|
+
}
|
|
98
33
|
}
|
|
99
|
-
|
|
100
|
-
module.exports = ECSignature
|
package/src/index.js
CHANGED
|
@@ -1,20 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
script[key] = templates[key]
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
module.exports = {
|
|
9
|
-
bufferutils: require('./bufferutils'), // TODO: remove in 4.0.0
|
|
10
|
-
|
|
11
|
-
ECSignature: require('./ecsignature'),
|
|
12
|
-
Transaction: require('./transaction'),
|
|
13
|
-
TransactionBuilder: require('./transaction_builder'),
|
|
14
|
-
|
|
15
|
-
address: require('./address'),
|
|
16
|
-
crypto: require('./crypto'),
|
|
17
|
-
networks: require('./networks'),
|
|
18
|
-
opcodes: require('bitcoin-ops'),
|
|
19
|
-
script: script
|
|
20
|
-
}
|
|
1
|
+
exports.Transaction = require('./transaction')
|
|
2
|
+
exports.TransactionBuilder = require('./transaction_builder')
|
|
3
|
+
exports.address = require('./address')
|
|
4
|
+
exports.networks = require('./networks')
|
|
@@ -12,7 +12,6 @@ var P2SH = SIGNABLE.concat([btemplates.types.P2WPKH, btemplates.types.P2WSH])
|
|
|
12
12
|
|
|
13
13
|
var ECSignature = require('./ecsignature')
|
|
14
14
|
var Transaction = require('./transaction')
|
|
15
|
-
const { ecdsaVerifyHashSync } = require('@exodus/crypto/secp256k1')
|
|
16
15
|
|
|
17
16
|
function supportedType (type) {
|
|
18
17
|
return SIGNABLE.indexOf(type) !== -1
|
|
@@ -172,59 +171,6 @@ function expandInput (scriptSig, witnessStack) {
|
|
|
172
171
|
return result
|
|
173
172
|
}
|
|
174
173
|
|
|
175
|
-
// could be done in expandInput, but requires the original Transaction for hashForSignature
|
|
176
|
-
function fixMultisigOrder (input, transaction, vin, value, forkId) {
|
|
177
|
-
if (input.redeemScriptType !== scriptTypes.MULTISIG || !input.redeemScript) return
|
|
178
|
-
if (input.pubKeys.length === input.signatures.length) return
|
|
179
|
-
|
|
180
|
-
var unmatched = input.signatures.concat()
|
|
181
|
-
|
|
182
|
-
input.signatures = input.pubKeys.map(function (pubKey) {
|
|
183
|
-
var match
|
|
184
|
-
|
|
185
|
-
// check for a signature
|
|
186
|
-
unmatched.some(function (signature, i) {
|
|
187
|
-
// skip if undefined || OP_0
|
|
188
|
-
if (!signature) return false
|
|
189
|
-
|
|
190
|
-
// TODO: avoid O(n) hashForSignature
|
|
191
|
-
var parsed = ECSignature.parseScriptSignature(signature)
|
|
192
|
-
var hash
|
|
193
|
-
switch (forkId) {
|
|
194
|
-
case Transaction.FORKID_BCH:
|
|
195
|
-
hash = transaction.hashForCashSignature(vin, input.signScript, value, parsed.hashType)
|
|
196
|
-
break
|
|
197
|
-
case Transaction.FORKID_BTG:
|
|
198
|
-
hash = transaction.hashForGoldSignature(vin, input.signScript, value, parsed.hashType)
|
|
199
|
-
break
|
|
200
|
-
default:
|
|
201
|
-
if (input.witness) {
|
|
202
|
-
hash = transaction.hashForWitnessV0(vin, input.signScript, value, parsed.hashType)
|
|
203
|
-
} else {
|
|
204
|
-
hash = transaction.hashForSignature(vin, input.signScript, parsed.hashType)
|
|
205
|
-
}
|
|
206
|
-
break
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// skip if signature does not match pubKey
|
|
210
|
-
// Allow non-normalized though
|
|
211
|
-
if (!ecdsaVerifyHashSync({
|
|
212
|
-
signature: parsed.signature.toRSBuffer(null, 0, { canonical: true }),
|
|
213
|
-
hash,
|
|
214
|
-
publicKey: pubKey
|
|
215
|
-
})) return false
|
|
216
|
-
|
|
217
|
-
// remove matched signature from unmatched
|
|
218
|
-
unmatched[i] = undefined
|
|
219
|
-
match = signature
|
|
220
|
-
|
|
221
|
-
return true
|
|
222
|
-
})
|
|
223
|
-
|
|
224
|
-
return match
|
|
225
|
-
})
|
|
226
|
-
}
|
|
227
|
-
|
|
228
174
|
function expandOutput (script, scriptType, ourPubKey) {
|
|
229
175
|
typeforce(types.Buffer, script)
|
|
230
176
|
|
|
@@ -533,44 +479,6 @@ TransactionBuilder.prototype.setVersion = function (version) {
|
|
|
533
479
|
this.tx.version = version
|
|
534
480
|
}
|
|
535
481
|
|
|
536
|
-
TransactionBuilder.fromTransaction = function (transaction, network, forkId) {
|
|
537
|
-
var txb = new TransactionBuilder(network)
|
|
538
|
-
|
|
539
|
-
if (typeof forkId === 'number') {
|
|
540
|
-
if (forkId === Transaction.FORKID_BTG) {
|
|
541
|
-
txb.enableBitcoinGold(true)
|
|
542
|
-
} else if (forkId === Transaction.FORKID_BCH) {
|
|
543
|
-
txb.enableBitcoinCash(true)
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
// Copy transaction fields
|
|
548
|
-
txb.setVersion(transaction.version)
|
|
549
|
-
txb.setLockTime(transaction.locktime)
|
|
550
|
-
|
|
551
|
-
// Copy outputs (done first to avoid signature invalidation)
|
|
552
|
-
transaction.outs.forEach(function (txOut) {
|
|
553
|
-
txb.addOutput(txOut.script, txOut.value)
|
|
554
|
-
})
|
|
555
|
-
|
|
556
|
-
// Copy inputs
|
|
557
|
-
transaction.ins.forEach(function (txIn) {
|
|
558
|
-
txb.__addInputUnsafe(txIn.hash, txIn.index, {
|
|
559
|
-
sequence: txIn.sequence,
|
|
560
|
-
script: txIn.script,
|
|
561
|
-
witness: txIn.witness,
|
|
562
|
-
value: txIn.value
|
|
563
|
-
})
|
|
564
|
-
})
|
|
565
|
-
|
|
566
|
-
// fix some things not possible through the public API
|
|
567
|
-
txb.inputs.forEach(function (input, i) {
|
|
568
|
-
fixMultisigOrder(input, transaction, i, input.value, forkId)
|
|
569
|
-
})
|
|
570
|
-
|
|
571
|
-
return txb
|
|
572
|
-
}
|
|
573
|
-
|
|
574
482
|
TransactionBuilder.prototype.addInput = function (txHash, vout, sequence, prevOutScript) {
|
|
575
483
|
if (!this.__canModifyInputs()) {
|
|
576
484
|
throw new Error('No, this would invalidate signatures')
|
package/src/types.js
CHANGED
|
@@ -15,12 +15,7 @@ function Satoshi (value) {
|
|
|
15
15
|
return typeforce.UInt53(value) && value <= SATOSHI_MAX
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
// external dependent types
|
|
19
|
-
var BigInt = typeforce.quacksLike('BigInteger')
|
|
20
|
-
var ECPoint = typeforce.quacksLike('Point')
|
|
21
|
-
|
|
22
18
|
// exposed, external API
|
|
23
|
-
var ECSignature = typeforce.compile({ r: BigInt, s: BigInt })
|
|
24
19
|
var Network = typeforce.compile({
|
|
25
20
|
messagePrefix: typeforce.oneOf(typeforce.Buffer, typeforce.String),
|
|
26
21
|
bip32: {
|
|
@@ -34,11 +29,8 @@ var Network = typeforce.compile({
|
|
|
34
29
|
|
|
35
30
|
// extend typeforce types with ours
|
|
36
31
|
var types = {
|
|
37
|
-
BigInt: BigInt,
|
|
38
32
|
BIP32Path: BIP32Path,
|
|
39
33
|
Buffer256bit: typeforce.BufferN(32),
|
|
40
|
-
ECPoint: ECPoint,
|
|
41
|
-
ECSignature: ECSignature,
|
|
42
34
|
Hash160bit: typeforce.BufferN(20),
|
|
43
35
|
Hash256bit: typeforce.BufferN(32),
|
|
44
36
|
Network: Network,
|