@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
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
var Buffer = require('safe-buffer').Buffer
|
|
2
|
+
var bcrypto = require('./crypto')
|
|
3
|
+
var bscript = require('./script')
|
|
4
|
+
var bufferutils = require('./bufferutils')
|
|
5
|
+
var opcodes = require('bitcoin-ops')
|
|
6
|
+
var typeforce = require('typeforce')
|
|
7
|
+
var types = require('./types')
|
|
8
|
+
var varuint = require('varuint-bitcoin')
|
|
9
|
+
|
|
10
|
+
function varSliceSize (someScript) {
|
|
11
|
+
var length = someScript.length
|
|
12
|
+
|
|
13
|
+
return varuint.encodingLength(length) + length
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function vectorSize (someVector) {
|
|
17
|
+
var length = someVector.length
|
|
18
|
+
|
|
19
|
+
return varuint.encodingLength(length) + someVector.reduce(function (sum, witness) {
|
|
20
|
+
return sum + varSliceSize(witness)
|
|
21
|
+
}, 0)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function Transaction () {
|
|
25
|
+
this.version = 1
|
|
26
|
+
this.locktime = 0
|
|
27
|
+
this.ins = []
|
|
28
|
+
this.outs = []
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
Transaction.DEFAULT_SEQUENCE = 0xffffffff
|
|
32
|
+
Transaction.SIGHASH_ALL = 0x01
|
|
33
|
+
Transaction.SIGHASH_NONE = 0x02
|
|
34
|
+
Transaction.SIGHASH_SINGLE = 0x03
|
|
35
|
+
Transaction.SIGHASH_ANYONECANPAY = 0x80
|
|
36
|
+
Transaction.SIGHASH_BITCOINCASHBIP143 = 0x40
|
|
37
|
+
Transaction.ADVANCED_TRANSACTION_MARKER = 0x00
|
|
38
|
+
Transaction.ADVANCED_TRANSACTION_FLAG = 0x01
|
|
39
|
+
Transaction.FORKID_BTG = 0x4F // 79
|
|
40
|
+
Transaction.FORKID_BCH = 0xFF0001
|
|
41
|
+
|
|
42
|
+
var EMPTY_SCRIPT = Buffer.allocUnsafe(0)
|
|
43
|
+
var EMPTY_WITNESS = []
|
|
44
|
+
var ZERO = Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex')
|
|
45
|
+
var ONE = Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex')
|
|
46
|
+
var VALUE_UINT64_MAX = Buffer.from('ffffffffffffffff', 'hex')
|
|
47
|
+
var BLANK_OUTPUT = {
|
|
48
|
+
script: EMPTY_SCRIPT,
|
|
49
|
+
valueBuffer: VALUE_UINT64_MAX
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
Transaction.fromBuffer = function (buffer, __noStrict) {
|
|
53
|
+
var offset = 0
|
|
54
|
+
function readSlice (n) {
|
|
55
|
+
offset += n
|
|
56
|
+
return buffer.slice(offset - n, offset)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function readUInt32 () {
|
|
60
|
+
var i = buffer.readUInt32LE(offset)
|
|
61
|
+
offset += 4
|
|
62
|
+
return i
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function readInt32 () {
|
|
66
|
+
var i = buffer.readInt32LE(offset)
|
|
67
|
+
offset += 4
|
|
68
|
+
return i
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function readUInt64 () {
|
|
72
|
+
var i = bufferutils.readUInt64LE(buffer, offset)
|
|
73
|
+
offset += 8
|
|
74
|
+
return i
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function readVarInt () {
|
|
78
|
+
var vi = varuint.decode(buffer, offset)
|
|
79
|
+
offset += varuint.decode.bytes
|
|
80
|
+
return vi
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function readVarSlice () {
|
|
84
|
+
return readSlice(readVarInt())
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function readVector () {
|
|
88
|
+
var count = readVarInt()
|
|
89
|
+
var vector = []
|
|
90
|
+
for (var i = 0; i < count; i++) vector.push(readVarSlice())
|
|
91
|
+
return vector
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
var tx = new Transaction()
|
|
95
|
+
tx.version = readInt32()
|
|
96
|
+
|
|
97
|
+
var marker = buffer.readUInt8(offset)
|
|
98
|
+
var flag = buffer.readUInt8(offset + 1)
|
|
99
|
+
|
|
100
|
+
var hasWitnesses = false
|
|
101
|
+
if (marker === Transaction.ADVANCED_TRANSACTION_MARKER &&
|
|
102
|
+
flag === Transaction.ADVANCED_TRANSACTION_FLAG) {
|
|
103
|
+
offset += 2
|
|
104
|
+
hasWitnesses = true
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
var vinLen = readVarInt()
|
|
108
|
+
for (var i = 0; i < vinLen; ++i) {
|
|
109
|
+
tx.ins.push({
|
|
110
|
+
hash: readSlice(32),
|
|
111
|
+
index: readUInt32(),
|
|
112
|
+
script: readVarSlice(),
|
|
113
|
+
sequence: readUInt32(),
|
|
114
|
+
witness: EMPTY_WITNESS
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
var voutLen = readVarInt()
|
|
119
|
+
for (i = 0; i < voutLen; ++i) {
|
|
120
|
+
tx.outs.push({
|
|
121
|
+
value: readUInt64(),
|
|
122
|
+
script: readVarSlice()
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (hasWitnesses) {
|
|
127
|
+
for (i = 0; i < vinLen; ++i) {
|
|
128
|
+
tx.ins[i].witness = readVector()
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// was this pointless?
|
|
132
|
+
if (!tx.hasWitnesses()) throw new Error('Transaction has superfluous witness data')
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
tx.locktime = readUInt32()
|
|
136
|
+
|
|
137
|
+
if (__noStrict) return tx
|
|
138
|
+
if (offset !== buffer.length) throw new Error('Transaction has unexpected data')
|
|
139
|
+
|
|
140
|
+
return tx
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
Transaction.fromHex = function (hex) {
|
|
144
|
+
return Transaction.fromBuffer(Buffer.from(hex, 'hex'))
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
Transaction.isCoinbaseHash = function (buffer) {
|
|
148
|
+
typeforce(types.Hash256bit, buffer)
|
|
149
|
+
for (var i = 0; i < 32; ++i) {
|
|
150
|
+
if (buffer[i] !== 0) return false
|
|
151
|
+
}
|
|
152
|
+
return true
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
Transaction.prototype.isCoinbase = function () {
|
|
156
|
+
return this.ins.length === 1 && Transaction.isCoinbaseHash(this.ins[0].hash)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
Transaction.prototype.addInput = function (hash, index, sequence, scriptSig) {
|
|
160
|
+
typeforce(types.tuple(
|
|
161
|
+
types.Hash256bit,
|
|
162
|
+
types.UInt32,
|
|
163
|
+
types.maybe(types.UInt32),
|
|
164
|
+
types.maybe(types.Buffer)
|
|
165
|
+
), arguments)
|
|
166
|
+
|
|
167
|
+
if (types.Null(sequence)) {
|
|
168
|
+
sequence = Transaction.DEFAULT_SEQUENCE
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Add the input and return the input's index
|
|
172
|
+
return (this.ins.push({
|
|
173
|
+
hash: hash,
|
|
174
|
+
index: index,
|
|
175
|
+
script: scriptSig || EMPTY_SCRIPT,
|
|
176
|
+
sequence: sequence,
|
|
177
|
+
witness: EMPTY_WITNESS
|
|
178
|
+
}) - 1)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
Transaction.prototype.addOutput = function (scriptPubKey, value) {
|
|
182
|
+
typeforce(types.tuple(types.Buffer, types.Satoshi), arguments)
|
|
183
|
+
|
|
184
|
+
// Add the output and return the output's index
|
|
185
|
+
return (this.outs.push({
|
|
186
|
+
script: scriptPubKey,
|
|
187
|
+
value: value
|
|
188
|
+
}) - 1)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
Transaction.prototype.hasWitnesses = function () {
|
|
192
|
+
return this.ins.some(function (x) {
|
|
193
|
+
return x.witness.length !== 0
|
|
194
|
+
})
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
Transaction.prototype.weight = function () {
|
|
198
|
+
var base = this.__byteLength(false)
|
|
199
|
+
var total = this.__byteLength(true)
|
|
200
|
+
return base * 3 + total
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
Transaction.prototype.virtualSize = function () {
|
|
204
|
+
return Math.ceil(this.weight() / 4)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
Transaction.prototype.byteLength = function () {
|
|
208
|
+
return this.__byteLength(true)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
Transaction.prototype.__byteLength = function (__allowWitness) {
|
|
212
|
+
var hasWitnesses = __allowWitness && this.hasWitnesses()
|
|
213
|
+
|
|
214
|
+
return (
|
|
215
|
+
(hasWitnesses ? 10 : 8) +
|
|
216
|
+
varuint.encodingLength(this.ins.length) +
|
|
217
|
+
varuint.encodingLength(this.outs.length) +
|
|
218
|
+
this.ins.reduce(function (sum, input) { return sum + 40 + varSliceSize(input.script) }, 0) +
|
|
219
|
+
this.outs.reduce(function (sum, output) { return sum + 8 + varSliceSize(output.script) }, 0) +
|
|
220
|
+
(hasWitnesses ? this.ins.reduce(function (sum, input) { return sum + vectorSize(input.witness) }, 0) : 0)
|
|
221
|
+
)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
Transaction.prototype.clone = function () {
|
|
225
|
+
var newTx = new Transaction()
|
|
226
|
+
newTx.version = this.version
|
|
227
|
+
newTx.locktime = this.locktime
|
|
228
|
+
|
|
229
|
+
newTx.ins = this.ins.map(function (txIn) {
|
|
230
|
+
return {
|
|
231
|
+
hash: txIn.hash,
|
|
232
|
+
index: txIn.index,
|
|
233
|
+
script: txIn.script,
|
|
234
|
+
sequence: txIn.sequence,
|
|
235
|
+
witness: txIn.witness
|
|
236
|
+
}
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
newTx.outs = this.outs.map(function (txOut) {
|
|
240
|
+
return {
|
|
241
|
+
script: txOut.script,
|
|
242
|
+
value: txOut.value
|
|
243
|
+
}
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
return newTx
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Hash transaction for signing a specific input.
|
|
251
|
+
*
|
|
252
|
+
* Bitcoin uses a different hash for each signed transaction input.
|
|
253
|
+
* This method copies the transaction, makes the necessary changes based on the
|
|
254
|
+
* hashType, and then hashes the result.
|
|
255
|
+
* This hash can then be used to sign the provided transaction input.
|
|
256
|
+
*/
|
|
257
|
+
Transaction.prototype.hashForSignature = function (inIndex, prevOutScript, hashType) {
|
|
258
|
+
typeforce(types.tuple(types.UInt32, types.Buffer, /* types.UInt8 */ types.Number), arguments)
|
|
259
|
+
|
|
260
|
+
// https://github.com/bitcoin/bitcoin/blob/master/src/test/sighash_tests.cpp#L29
|
|
261
|
+
if (inIndex >= this.ins.length) return ONE
|
|
262
|
+
|
|
263
|
+
// ignore OP_CODESEPARATOR
|
|
264
|
+
var ourScript = bscript.compile(bscript.decompile(prevOutScript).filter(function (x) {
|
|
265
|
+
return x !== opcodes.OP_CODESEPARATOR
|
|
266
|
+
}))
|
|
267
|
+
|
|
268
|
+
var txTmp = this.clone()
|
|
269
|
+
|
|
270
|
+
// SIGHASH_NONE: ignore all outputs? (wildcard payee)
|
|
271
|
+
if ((hashType & 0x1f) === Transaction.SIGHASH_NONE) {
|
|
272
|
+
txTmp.outs = []
|
|
273
|
+
|
|
274
|
+
// ignore sequence numbers (except at inIndex)
|
|
275
|
+
txTmp.ins.forEach(function (input, i) {
|
|
276
|
+
if (i === inIndex) return
|
|
277
|
+
|
|
278
|
+
input.sequence = 0
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
// SIGHASH_SINGLE: ignore all outputs, except at the same index?
|
|
282
|
+
} else if ((hashType & 0x1f) === Transaction.SIGHASH_SINGLE) {
|
|
283
|
+
// https://github.com/bitcoin/bitcoin/blob/master/src/test/sighash_tests.cpp#L60
|
|
284
|
+
if (inIndex >= this.outs.length) return ONE
|
|
285
|
+
|
|
286
|
+
// truncate outputs after
|
|
287
|
+
txTmp.outs.length = inIndex + 1
|
|
288
|
+
|
|
289
|
+
// "blank" outputs before
|
|
290
|
+
for (var i = 0; i < inIndex; i++) {
|
|
291
|
+
txTmp.outs[i] = BLANK_OUTPUT
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// ignore sequence numbers (except at inIndex)
|
|
295
|
+
txTmp.ins.forEach(function (input, y) {
|
|
296
|
+
if (y === inIndex) return
|
|
297
|
+
|
|
298
|
+
input.sequence = 0
|
|
299
|
+
})
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// SIGHASH_ANYONECANPAY: ignore inputs entirely?
|
|
303
|
+
if (hashType & Transaction.SIGHASH_ANYONECANPAY) {
|
|
304
|
+
txTmp.ins = [txTmp.ins[inIndex]]
|
|
305
|
+
txTmp.ins[0].script = ourScript
|
|
306
|
+
|
|
307
|
+
// SIGHASH_ALL: only ignore input scripts
|
|
308
|
+
} else {
|
|
309
|
+
// "blank" others input scripts
|
|
310
|
+
txTmp.ins.forEach(function (input) { input.script = EMPTY_SCRIPT })
|
|
311
|
+
txTmp.ins[inIndex].script = ourScript
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// serialize and hash
|
|
315
|
+
var buffer = Buffer.allocUnsafe(txTmp.__byteLength(false) + 4)
|
|
316
|
+
buffer.writeInt32LE(hashType, buffer.length - 4)
|
|
317
|
+
txTmp.__toBuffer(buffer, 0, false)
|
|
318
|
+
|
|
319
|
+
return bcrypto.hash256(buffer)
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
Transaction.prototype.hashForWitnessV0 = function (inIndex, prevOutScript, value, hashType) {
|
|
323
|
+
typeforce(types.tuple(types.UInt32, types.Buffer, types.Satoshi, types.UInt32), arguments)
|
|
324
|
+
|
|
325
|
+
var tbuffer, toffset
|
|
326
|
+
function writeSlice (slice) { toffset += slice.copy(tbuffer, toffset) }
|
|
327
|
+
function writeUInt32 (i) { toffset = tbuffer.writeUInt32LE(i, toffset) }
|
|
328
|
+
function writeUInt64 (i) { toffset = bufferutils.writeUInt64LE(tbuffer, i, toffset) }
|
|
329
|
+
function writeVarInt (i) {
|
|
330
|
+
varuint.encode(i, tbuffer, toffset)
|
|
331
|
+
toffset += varuint.encode.bytes
|
|
332
|
+
}
|
|
333
|
+
function writeVarSlice (slice) { writeVarInt(slice.length); writeSlice(slice) }
|
|
334
|
+
|
|
335
|
+
var hashOutputs = ZERO
|
|
336
|
+
var hashPrevouts = ZERO
|
|
337
|
+
var hashSequence = ZERO
|
|
338
|
+
|
|
339
|
+
if (!(hashType & Transaction.SIGHASH_ANYONECANPAY)) {
|
|
340
|
+
tbuffer = Buffer.allocUnsafe(36 * this.ins.length)
|
|
341
|
+
toffset = 0
|
|
342
|
+
|
|
343
|
+
this.ins.forEach(function (txIn) {
|
|
344
|
+
writeSlice(txIn.hash)
|
|
345
|
+
writeUInt32(txIn.index)
|
|
346
|
+
})
|
|
347
|
+
|
|
348
|
+
hashPrevouts = bcrypto.hash256(tbuffer)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (!(hashType & Transaction.SIGHASH_ANYONECANPAY) &&
|
|
352
|
+
(hashType & 0x1f) !== Transaction.SIGHASH_SINGLE &&
|
|
353
|
+
(hashType & 0x1f) !== Transaction.SIGHASH_NONE) {
|
|
354
|
+
tbuffer = Buffer.allocUnsafe(4 * this.ins.length)
|
|
355
|
+
toffset = 0
|
|
356
|
+
|
|
357
|
+
this.ins.forEach(function (txIn) {
|
|
358
|
+
writeUInt32(txIn.sequence)
|
|
359
|
+
})
|
|
360
|
+
|
|
361
|
+
hashSequence = bcrypto.hash256(tbuffer)
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
if ((hashType & 0x1f) !== Transaction.SIGHASH_SINGLE &&
|
|
365
|
+
(hashType & 0x1f) !== Transaction.SIGHASH_NONE) {
|
|
366
|
+
var txOutsSize = this.outs.reduce(function (sum, output) {
|
|
367
|
+
return sum + 8 + varSliceSize(output.script)
|
|
368
|
+
}, 0)
|
|
369
|
+
|
|
370
|
+
tbuffer = Buffer.allocUnsafe(txOutsSize)
|
|
371
|
+
toffset = 0
|
|
372
|
+
|
|
373
|
+
this.outs.forEach(function (out) {
|
|
374
|
+
writeUInt64(out.value)
|
|
375
|
+
writeVarSlice(out.script)
|
|
376
|
+
})
|
|
377
|
+
|
|
378
|
+
hashOutputs = bcrypto.hash256(tbuffer)
|
|
379
|
+
} else if ((hashType & 0x1f) === Transaction.SIGHASH_SINGLE && inIndex < this.outs.length) {
|
|
380
|
+
var output = this.outs[inIndex]
|
|
381
|
+
|
|
382
|
+
tbuffer = Buffer.allocUnsafe(8 + varSliceSize(output.script))
|
|
383
|
+
toffset = 0
|
|
384
|
+
writeUInt64(output.value)
|
|
385
|
+
writeVarSlice(output.script)
|
|
386
|
+
|
|
387
|
+
hashOutputs = bcrypto.hash256(tbuffer)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
tbuffer = Buffer.allocUnsafe(156 + varSliceSize(prevOutScript))
|
|
391
|
+
toffset = 0
|
|
392
|
+
|
|
393
|
+
var input = this.ins[inIndex]
|
|
394
|
+
writeUInt32(this.version)
|
|
395
|
+
writeSlice(hashPrevouts)
|
|
396
|
+
writeSlice(hashSequence)
|
|
397
|
+
writeSlice(input.hash)
|
|
398
|
+
writeUInt32(input.index)
|
|
399
|
+
writeVarSlice(prevOutScript)
|
|
400
|
+
writeUInt64(value)
|
|
401
|
+
writeUInt32(input.sequence)
|
|
402
|
+
writeSlice(hashOutputs)
|
|
403
|
+
writeUInt32(this.locktime)
|
|
404
|
+
writeUInt32(hashType)
|
|
405
|
+
return bcrypto.hash256(tbuffer)
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Hash transaction for signing a specific input for Bitcoin Cash.
|
|
410
|
+
*/
|
|
411
|
+
Transaction.prototype.hashForCashSignature = function (inIndex, prevOutScript, inAmount, hashType) {
|
|
412
|
+
typeforce(types.tuple(types.UInt32, types.Buffer, /* types.UInt8 */ types.Number, types.maybe(types.UInt53)), arguments)
|
|
413
|
+
|
|
414
|
+
// This function works the way it does because Bitcoin Cash
|
|
415
|
+
// uses BIP143 as their replay protection, AND their algo
|
|
416
|
+
// includes `forkId | hashType`, AND since their forkId=0,
|
|
417
|
+
// this is a NOP, and has no difference to segwit. To support
|
|
418
|
+
// other forks, another parameter is required, and a new parameter
|
|
419
|
+
// would be required in the hashForWitnessV0 function, or
|
|
420
|
+
// it could be broken into two..
|
|
421
|
+
|
|
422
|
+
// BIP143 sighash activated in BitcoinCash via 0x40 bit
|
|
423
|
+
if (hashType & Transaction.SIGHASH_BITCOINCASHBIP143) {
|
|
424
|
+
if (types.Null(inAmount)) {
|
|
425
|
+
throw new Error('Bitcoin Cash sighash requires value of input to be signed.')
|
|
426
|
+
}
|
|
427
|
+
return this.hashForWitnessV0(inIndex, prevOutScript, inAmount, hashType)
|
|
428
|
+
} else {
|
|
429
|
+
return this.hashForSignature(inIndex, prevOutScript, hashType)
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Hash transaction for signing a specific input for Bitcoin Gold.
|
|
435
|
+
*/
|
|
436
|
+
Transaction.prototype.hashForGoldSignature = function (inIndex, prevOutScript, inAmount, hashType, sigVersion) {
|
|
437
|
+
typeforce(types.tuple(types.UInt32, types.Buffer, /* types.UInt8 */ types.Number, types.maybe(types.UInt53)), arguments)
|
|
438
|
+
|
|
439
|
+
// Bitcoin Gold also implements segregated witness
|
|
440
|
+
// therefore we can pull out the setting of nForkHashType
|
|
441
|
+
// and pass it into the functions.
|
|
442
|
+
|
|
443
|
+
var nForkHashType = hashType
|
|
444
|
+
var fUseForkId = (hashType & Transaction.SIGHASH_BITCOINCASHBIP143) > 0
|
|
445
|
+
if (fUseForkId) {
|
|
446
|
+
nForkHashType |= Transaction.FORKID_BTG << 8
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// BIP143 sighash activated in BitcoinCash via 0x40 bit
|
|
450
|
+
if (sigVersion || fUseForkId) {
|
|
451
|
+
if (types.Null(inAmount)) {
|
|
452
|
+
throw new Error('Bitcoin Cash sighash requires value of input to be signed.')
|
|
453
|
+
}
|
|
454
|
+
return this.hashForWitnessV0(inIndex, prevOutScript, inAmount, nForkHashType)
|
|
455
|
+
} else {
|
|
456
|
+
return this.hashForSignature(inIndex, prevOutScript, nForkHashType)
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
Transaction.prototype.getHash = function () {
|
|
461
|
+
return bcrypto.hash256(this.__toBuffer(undefined, undefined, false))
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
Transaction.prototype.getId = function () {
|
|
465
|
+
// transaction hash's are displayed in reverse order
|
|
466
|
+
return this.getHash().reverse().toString('hex')
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
Transaction.prototype.toBuffer = function (buffer, initialOffset) {
|
|
470
|
+
return this.__toBuffer(buffer, initialOffset, true)
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
Transaction.prototype.__toBuffer = function (buffer, initialOffset, __allowWitness) {
|
|
474
|
+
if (!buffer) buffer = Buffer.allocUnsafe(this.__byteLength(__allowWitness))
|
|
475
|
+
|
|
476
|
+
var offset = initialOffset || 0
|
|
477
|
+
function writeSlice (slice) { offset += slice.copy(buffer, offset) }
|
|
478
|
+
function writeUInt8 (i) { offset = buffer.writeUInt8(i, offset) }
|
|
479
|
+
function writeUInt32 (i) { offset = buffer.writeUInt32LE(i, offset) }
|
|
480
|
+
function writeInt32 (i) { offset = buffer.writeInt32LE(i, offset) }
|
|
481
|
+
function writeUInt64 (i) { offset = bufferutils.writeUInt64LE(buffer, i, offset) }
|
|
482
|
+
function writeVarInt (i) {
|
|
483
|
+
varuint.encode(i, buffer, offset)
|
|
484
|
+
offset += varuint.encode.bytes
|
|
485
|
+
}
|
|
486
|
+
function writeVarSlice (slice) { writeVarInt(slice.length); writeSlice(slice) }
|
|
487
|
+
function writeVector (vector) { writeVarInt(vector.length); vector.forEach(writeVarSlice) }
|
|
488
|
+
|
|
489
|
+
writeInt32(this.version)
|
|
490
|
+
|
|
491
|
+
var hasWitnesses = __allowWitness && this.hasWitnesses()
|
|
492
|
+
|
|
493
|
+
if (hasWitnesses) {
|
|
494
|
+
writeUInt8(Transaction.ADVANCED_TRANSACTION_MARKER)
|
|
495
|
+
writeUInt8(Transaction.ADVANCED_TRANSACTION_FLAG)
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
writeVarInt(this.ins.length)
|
|
499
|
+
|
|
500
|
+
this.ins.forEach(function (txIn) {
|
|
501
|
+
writeSlice(txIn.hash)
|
|
502
|
+
writeUInt32(txIn.index)
|
|
503
|
+
writeVarSlice(txIn.script)
|
|
504
|
+
writeUInt32(txIn.sequence)
|
|
505
|
+
})
|
|
506
|
+
|
|
507
|
+
writeVarInt(this.outs.length)
|
|
508
|
+
this.outs.forEach(function (txOut) {
|
|
509
|
+
if (!txOut.valueBuffer) {
|
|
510
|
+
writeUInt64(txOut.value)
|
|
511
|
+
} else {
|
|
512
|
+
writeSlice(txOut.valueBuffer)
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
writeVarSlice(txOut.script)
|
|
516
|
+
})
|
|
517
|
+
|
|
518
|
+
if (hasWitnesses) {
|
|
519
|
+
this.ins.forEach(function (input) {
|
|
520
|
+
writeVector(input.witness)
|
|
521
|
+
})
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
writeUInt32(this.locktime)
|
|
525
|
+
|
|
526
|
+
// avoid slicing unless necessary
|
|
527
|
+
if (initialOffset !== undefined) return buffer.slice(initialOffset, offset)
|
|
528
|
+
return buffer
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
Transaction.prototype.toHex = function () {
|
|
532
|
+
return this.toBuffer().toString('hex')
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
Transaction.prototype.setInputScript = function (index, scriptSig) {
|
|
536
|
+
typeforce(types.tuple(types.Number, types.Buffer), arguments)
|
|
537
|
+
|
|
538
|
+
this.ins[index].script = scriptSig
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
Transaction.prototype.setWitness = function (index, witness) {
|
|
542
|
+
typeforce(types.tuple(types.Number, [types.Buffer]), arguments)
|
|
543
|
+
|
|
544
|
+
this.ins[index].witness = witness
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
module.exports = Transaction
|