From 8a13a22bafbb6168d725b375d0d82f61aa59f345 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Thu, 14 May 2015 22:34:44 -0300 Subject: [PATCH] add Transaction#clearOutputs --- docs/transaction.md | 4 +++- lib/transaction/transaction.js | 19 ++++++++++++++++++- test/transaction/transaction.js | 33 +++++++++++++++++++++++++++++---- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/docs/transaction.md b/docs/transaction.md index 24d26a7..68dc0ae 100644 --- a/docs/transaction.md +++ b/docs/transaction.md @@ -129,7 +129,7 @@ The following methods are used to manage signatures for a transaction: * `clearSignatures`: removes all signatures for this input * `isFullySigned`: returns true if the input is fully signed -## Adding outputs +## Handling Outputs Outputs can be added by: @@ -137,6 +137,8 @@ Outputs can be added by: * The `to(address, amount)` method, that adds an output with the script that corresponds to the given address. Builds an output and calls the `addOutput` method. * Specifying a [change address](#Fee_calculation) +To remove all outputs, you can use `clearOutputs()`, which preserves change output configuration. + ## Serialization There are a series of methods used for serialization: diff --git a/lib/transaction/transaction.js b/lib/transaction/transaction.js index bdfd458..94bf778 100644 --- a/lib/transaction/transaction.js +++ b/lib/transaction/transaction.js @@ -639,10 +639,11 @@ Transaction.prototype.fee = function(amount) { * Beware that this resets all the signatures for inputs (in further versions, * SIGHASH_SINGLE or SIGHASH_NONE signatures will not be reset). * - * @param {address} An address for change to be sent to. + * @param {Address} address An address for change to be sent to. * @return {Transaction} this, for chaining */ Transaction.prototype.change = function(address) { + $.checkArgument(address, 'address is required'); this._changeScript = Script.fromAddress(address); this._updateChangeOutput(); return this; @@ -713,6 +714,22 @@ Transaction.prototype.addOutput = function(output) { return this; }; + +/** + * Remove all outputs from the transaction. + * + * @return {Transaction} this, for chaining + */ +Transaction.prototype.clearOutputs = function() { + this.outputs = []; + this._clearSignatures(); + this._outputAmount = undefined; + this._changeIndex = undefined; + this._updateChangeOutput(); + return this; +}; + + Transaction.prototype._addOutput = function(output) { this.outputs.push(output); this._outputAmount = undefined; diff --git a/test/transaction/transaction.js b/test/transaction/transaction.js index c4498f0..66db3e5 100644 --- a/test/transaction/transaction.js +++ b/test/transaction/transaction.js @@ -143,6 +143,9 @@ describe('Transaction', function() { script: Script.buildPublicKeyHashOut(fromAddress).toString(), satoshis: 1e8 }; + var tenth = 1e7; + var fourth = 25e6; + var half = 5e7; describe('adding inputs', function() { @@ -499,7 +502,9 @@ describe('Transaction', function() { 'satoshis': testAmount }).to('mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc', testAmount - 10000); - tx.toBuffer = sinon.stub().returns({length: 10000000}); + tx.toBuffer = sinon.stub().returns({ + length: 10000000 + }); var verify = tx.verify(); verify.should.equal('transaction over the maximum block size'); @@ -738,9 +743,6 @@ describe('Transaction', function() { describe('output ordering', function() { - var tenth = 1e7; - var fourth = 25e6; - var half = 5e7; var transaction, out1, out2, out3, out4; beforeEach(function() { @@ -791,6 +793,29 @@ describe('Transaction', function() { }).to.throw(errors.Transaction.InvalidSorting); }); + + + }); + + describe('clearOutputs', function() { + + it('removes all outputs and maintains the transaction in order', function() { + var tx = new Transaction() + .from(simpleUtxoWith1BTC) + .to(toAddress, tenth) + .to(toAddress, fourth) + .to(toAddress, half) + .change(changeAddress); + tx.clearOutputs(); + tx.outputs.length.should.equal(1); + tx.to(toAddress, tenth); + tx.outputs.length.should.equal(2); + tx.outputs[0].satoshis.should.equal(10000000); + tx.outputs[0].script.toAddress().toString().should.equal(toAddress); + tx.outputs[1].satoshis.should.equal(89990000); + tx.outputs[1].script.toAddress().toString().should.equal(changeAddress); + }); + }); });