Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/transaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,16 @@ 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:

* The `addOutput(output)` method, which pushes an `Output` to the end of the `outputs` property and updates the `outputAmount` field. It also clears signatures (as the hash of the transaction may have changed) and updates the change output.
* 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:
Expand Down
19 changes: 18 additions & 1 deletion lib/transaction/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this also call this._updateChangeOutput()? Otherwise all the inputs will be miner's fee.

};


Transaction.prototype._addOutput = function(output) {
this.outputs.push(output);
this._outputAmount = undefined;
Expand Down
33 changes: 29 additions & 4 deletions test/transaction/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {

Expand Down Expand Up @@ -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');
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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);
});

});
});

Expand Down