From 5de6818fcbdd5584bb8bca45747ee26310e120eb Mon Sep 17 00:00:00 2001 From: Kirill Fomichev Date: Mon, 23 Nov 2015 17:05:06 +0300 Subject: [PATCH] Fix TransactionBuilder.addOutput --- src/transaction_builder.js | 9 ++++++--- test/transaction_builder.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/transaction_builder.js b/src/transaction_builder.js index e0dbc25..503ee92 100644 --- a/src/transaction_builder.js +++ b/src/transaction_builder.js @@ -227,10 +227,13 @@ TransactionBuilder.prototype.addInput = function (txHash, vout, sequence, prevOu } TransactionBuilder.prototype.addOutput = function (scriptPubKey, value) { - var valid = this.inputs.every(function (input) { + var tx = this.tx + var valid = this.inputs.every(function (input, index) { if (input.hashType === undefined) return true - return (input.hashType & 0x1f) === Transaction.SIGHASH_SINGLE + var hashType = input.hashType & 0x1f + return hashType === Transaction.SIGHASH_NONE || + (hashType === Transaction.SIGHASH_SINGLE && index < tx.outs.length) }) if (!valid) throw new Error('No, this would invalidate signatures') @@ -240,7 +243,7 @@ TransactionBuilder.prototype.addOutput = function (scriptPubKey, value) { scriptPubKey = baddress.toOutputScript(scriptPubKey, this.network) } - return this.tx.addOutput(scriptPubKey, value) + return tx.addOutput(scriptPubKey, value) } TransactionBuilder.prototype.build = function () { diff --git a/test/transaction_builder.js b/test/transaction_builder.js index dc1877a..1ee696f 100644 --- a/test/transaction_builder.js +++ b/test/transaction_builder.js @@ -202,6 +202,34 @@ describe('TransactionBuilder', function () { }, /2NGHjvjw83pcVFgMcA7QvSMh2c246rxLVz9 has no matching Script/) }) + it('add second output after signed first input with SIGHASH_NONE', function () { + txb.addInput(txHash, 0) + txb.addOutput(scripts[0], 2000) + txb.sign(0, keyPair, undefined, Transaction.SIGHASH_NONE) + assert.equal(txb.addOutput(scripts[1], 9000), 1) + }) + + it('add first output after signed first input with SIGHASH_NONE', function () { + txb.addInput(txHash, 0) + txb.sign(0, keyPair, undefined, Transaction.SIGHASH_NONE) + assert.equal(txb.addOutput(scripts[0], 2000), 0) + }) + + it('add second output after signed first input with SIGHASH_SINGLE', function () { + txb.addInput(txHash, 0) + txb.addOutput(scripts[0], 2000) + txb.sign(0, keyPair, undefined, Transaction.SIGHASH_SINGLE) + assert.equal(txb.addOutput(scripts[1], 9000), 1) + }) + + it('add first output after signed first input with SIGHASH_SINGLE', function () { + txb.addInput(txHash, 0) + txb.sign(0, keyPair, undefined, Transaction.SIGHASH_SINGLE) + assert.throws(function () { + txb.addOutput(scripts[0], 2000) + }, /No, this would invalidate signatures/) + }) + it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', function () { txb.addInput(txHash, 0) txb.addOutput(scripts[0], 2000)