TransactionBuilder: extract internal signature invalidation functions for individual testing
This commit is contained in:
parent
ccde09fdc3
commit
1aab317dad
1 changed files with 34 additions and 25 deletions
|
@ -322,14 +322,7 @@ TransactionBuilder.fromTransaction = function (transaction, network) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionBuilder.prototype.addInput = function (txHash, vout, sequence, prevOutScript) {
|
TransactionBuilder.prototype.addInput = function (txHash, vout, sequence, prevOutScript) {
|
||||||
// if signatures exist, adding inputs is only acceptable if SIGHASH_ANYONECANPAY is used
|
if (!this.__canModifyInputs()) {
|
||||||
// throw if any signatures *didn't* use SIGHASH_ANYONECANPAY
|
|
||||||
if (!this.inputs.every(function (otherInput) {
|
|
||||||
// no signature
|
|
||||||
if (otherInput.hashType === undefined) return true
|
|
||||||
|
|
||||||
return otherInput.hashType & Transaction.SIGHASH_ANYONECANPAY
|
|
||||||
})) {
|
|
||||||
throw new Error('No, this would invalidate signatures')
|
throw new Error('No, this would invalidate signatures')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,23 +380,7 @@ TransactionBuilder.prototype.__addInputUnsafe = function (txHash, vout, sequence
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionBuilder.prototype.addOutput = function (scriptPubKey, value) {
|
TransactionBuilder.prototype.addOutput = function (scriptPubKey, value) {
|
||||||
var nOutputs = this.tx.outs.length
|
if (!this.__canModifyOutputs()) {
|
||||||
|
|
||||||
// if signatures exist, adding outputs is only acceptable if SIGHASH_NONE or SIGHASH_SINGLE is used
|
|
||||||
// throws if any signatures didn't use SIGHASH_NONE|SIGHASH_SINGLE
|
|
||||||
if (!this.inputs.every(function (input, i) {
|
|
||||||
// no signature
|
|
||||||
if (input.hashType === undefined) return true
|
|
||||||
|
|
||||||
var hashTypeMod = input.hashType & 0x1f
|
|
||||||
if (hashTypeMod === Transaction.SIGHASH_NONE) return true
|
|
||||||
if (hashTypeMod === Transaction.SIGHASH_SINGLE) {
|
|
||||||
// account for SIGHASH_SINGLE signing of a non-existing output, aka the "SIGHASH_SINGLE" bug
|
|
||||||
return i < nOutputs
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
})) {
|
|
||||||
throw new Error('No, this would invalidate signatures')
|
throw new Error('No, this would invalidate signatures')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,4 +478,36 @@ TransactionBuilder.prototype.sign = function (vin, keyPair, redeemScript, hashTy
|
||||||
if (!valid) throw new Error('Key pair cannot sign for this input')
|
if (!valid) throw new Error('Key pair cannot sign for this input')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TransactionBuilder.prototype.__canModifyInputs = function () {
|
||||||
|
return this.inputs.every(function (otherInput) {
|
||||||
|
// no signature
|
||||||
|
if (otherInput.hashType === undefined) return true
|
||||||
|
|
||||||
|
// if SIGHASH_ANYONECANPAY is set, signatures would not
|
||||||
|
// be invalidated by more inputs
|
||||||
|
return otherInput.hashType & Transaction.SIGHASH_ANYONECANPAY
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
TransactionBuilder.prototype.__canModifyOutputs = function () {
|
||||||
|
var nInputs = this.tx.ins.length
|
||||||
|
var nOutputs = this.tx.outs.length
|
||||||
|
|
||||||
|
return this.inputs.every(function (input, i) {
|
||||||
|
// any signatures?
|
||||||
|
if (input.hashType === undefined) return true
|
||||||
|
|
||||||
|
var hashTypeMod = input.hashType & 0x1f
|
||||||
|
if (hashTypeMod === Transaction.SIGHASH_NONE) return true
|
||||||
|
if (hashTypeMod === Transaction.SIGHASH_SINGLE) {
|
||||||
|
// if SIGHASH_SINGLE is set, and nInputs > nOutputs
|
||||||
|
// some signatures would be invalidated by the addition
|
||||||
|
// of more outputs
|
||||||
|
return nInputs <= nOutputs
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = TransactionBuilder
|
module.exports = TransactionBuilder
|
||||||
|
|
Loading…
Reference in a new issue