Merge pull request #1028 from eordano/transaction/changeupdate
Improvements to Transaction
This commit is contained in:
commit
cd7e5d5a1e
@ -240,6 +240,7 @@ Transaction.prototype.toObject = function toObject() {
|
|||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
change: this._change ? this._change.toString() : undefined,
|
change: this._change ? this._change.toString() : undefined,
|
||||||
|
fee: this._fee ? this._fee : undefined,
|
||||||
version: this.version,
|
version: this.version,
|
||||||
inputs: inputs,
|
inputs: inputs,
|
||||||
outputs: outputs,
|
outputs: outputs,
|
||||||
@ -270,6 +271,9 @@ Transaction.prototype.fromObject = function(transaction) {
|
|||||||
if (transaction.change) {
|
if (transaction.change) {
|
||||||
this.change(transaction.change);
|
this.change(transaction.change);
|
||||||
}
|
}
|
||||||
|
if (transaction.fee) {
|
||||||
|
this.fee(transaction.fee);
|
||||||
|
}
|
||||||
this.nLockTime = transaction.nLockTime;
|
this.nLockTime = transaction.nLockTime;
|
||||||
this.version = transaction.version;
|
this.version = transaction.version;
|
||||||
};
|
};
|
||||||
@ -354,8 +358,14 @@ Transaction.prototype.from = function(utxo, pubkeys, threshold) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Transaction.prototype._fromNonP2SH = function(utxo) {
|
Transaction.prototype._fromNonP2SH = function(utxo) {
|
||||||
|
var clazz;
|
||||||
utxo = new UnspentOutput(utxo);
|
utxo = new UnspentOutput(utxo);
|
||||||
this.inputs.push(new PublicKeyHashInput({
|
if (utxo.script.isPublicKeyHashOut()) {
|
||||||
|
clazz = PublicKeyHashInput;
|
||||||
|
} else {
|
||||||
|
clazz = Input;
|
||||||
|
}
|
||||||
|
this.addInput(new clazz({
|
||||||
output: new Output({
|
output: new Output({
|
||||||
script: utxo.script,
|
script: utxo.script,
|
||||||
satoshis: utxo.satoshis
|
satoshis: utxo.satoshis
|
||||||
@ -365,7 +375,6 @@ Transaction.prototype._fromNonP2SH = function(utxo) {
|
|||||||
sequenceNumber: DEFAULT_SEQNUMBER,
|
sequenceNumber: DEFAULT_SEQNUMBER,
|
||||||
script: Script.empty()
|
script: Script.empty()
|
||||||
}));
|
}));
|
||||||
this._inputAmount += utxo.satoshis;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Transaction.prototype._fromMultisigUtxo = function(utxo, pubkeys, threshold) {
|
Transaction.prototype._fromMultisigUtxo = function(utxo, pubkeys, threshold) {
|
||||||
@ -394,10 +403,10 @@ Transaction.prototype._fromMultisigUtxo = function(utxo, pubkeys, threshold) {
|
|||||||
*/
|
*/
|
||||||
Transaction.prototype.addInput = function(input, outputScript, satoshis) {
|
Transaction.prototype.addInput = function(input, outputScript, satoshis) {
|
||||||
$.checkArgumentType(input, Input, 'input');
|
$.checkArgumentType(input, Input, 'input');
|
||||||
if (!input.output || !(input.output instanceof Output) && !outputScript && !satoshis) {
|
if (!input.output && (_.isUndefined(outputScript) || _.isUndefined(satoshis))) {
|
||||||
throw new errors.Transaction.NeedMoreInfo('Need information about the UTXO script and satoshis');
|
throw new errors.Transaction.NeedMoreInfo('Need information about the UTXO script and satoshis');
|
||||||
}
|
}
|
||||||
if (!input.output && outputScript && satoshis) {
|
if (!input.output && outputScript && !_.isUndefined(satoshis)) {
|
||||||
outputScript = outputScript instanceof Script ? outputScript : new Script(outputScript);
|
outputScript = outputScript instanceof Script ? outputScript : new Script(outputScript);
|
||||||
$.checkArgumentType(satoshis, 'number', 'satoshis');
|
$.checkArgumentType(satoshis, 'number', 'satoshis');
|
||||||
input.output = new Output({
|
input.output = new Output({
|
||||||
@ -417,11 +426,11 @@ Transaction.prototype.addInput = function(input, outputScript, satoshis) {
|
|||||||
*/
|
*/
|
||||||
Transaction.prototype.uncheckedAddInput = function(input) {
|
Transaction.prototype.uncheckedAddInput = function(input) {
|
||||||
$.checkArgumentType(input, Input, 'input');
|
$.checkArgumentType(input, Input, 'input');
|
||||||
this._changeSetup = false;
|
|
||||||
this.inputs.push(input);
|
this.inputs.push(input);
|
||||||
if (input.output) {
|
if (input.output) {
|
||||||
this._inputAmount += input.output.satoshis;
|
this._inputAmount += input.output.satoshis;
|
||||||
}
|
}
|
||||||
|
this._updateChangeOutput();
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -446,7 +455,7 @@ Transaction.prototype.hasAllUtxoInfo = function() {
|
|||||||
*/
|
*/
|
||||||
Transaction.prototype.fee = function(amount) {
|
Transaction.prototype.fee = function(amount) {
|
||||||
this._fee = amount;
|
this._fee = amount;
|
||||||
this._changeSetup = false;
|
this._updateChangeOutput();
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -463,7 +472,7 @@ Transaction.prototype.fee = function(amount) {
|
|||||||
*/
|
*/
|
||||||
Transaction.prototype.change = function(address) {
|
Transaction.prototype.change = function(address) {
|
||||||
this._change = new Address(address);
|
this._change = new Address(address);
|
||||||
this._changeSetup = false;
|
this._updateChangeOutput();
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -505,8 +514,12 @@ Transaction.prototype.addData = function(value) {
|
|||||||
|
|
||||||
Transaction.prototype.addOutput = function(output) {
|
Transaction.prototype.addOutput = function(output) {
|
||||||
$.checkArgumentType(output, Output, 'output');
|
$.checkArgumentType(output, Output, 'output');
|
||||||
|
this._addOutput(output);
|
||||||
|
this._updateChangeOutput();
|
||||||
|
};
|
||||||
|
|
||||||
|
Transaction.prototype._addOutput = function(output) {
|
||||||
this.outputs.push(output);
|
this.outputs.push(output);
|
||||||
this._changeSetup = false;
|
|
||||||
this._outputAmount += output.satoshis;
|
this._outputAmount += output.satoshis;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -514,12 +527,7 @@ Transaction.prototype._updateChangeOutput = function() {
|
|||||||
if (!this._change) {
|
if (!this._change) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this._changeSetup) {
|
this._clearSignatures();
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!_.isUndefined(this._changeSetup)) {
|
|
||||||
this._clearSignatures();
|
|
||||||
}
|
|
||||||
if (!_.isUndefined(this._changeOutput)) {
|
if (!_.isUndefined(this._changeOutput)) {
|
||||||
this.removeOutput(this._changeOutput);
|
this.removeOutput(this._changeOutput);
|
||||||
}
|
}
|
||||||
@ -527,14 +535,13 @@ Transaction.prototype._updateChangeOutput = function() {
|
|||||||
var fee = this.getFee();
|
var fee = this.getFee();
|
||||||
if (available - fee > 0) {
|
if (available - fee > 0) {
|
||||||
this._changeOutput = this.outputs.length;
|
this._changeOutput = this.outputs.length;
|
||||||
this.addOutput(new Output({
|
this._addOutput(new Output({
|
||||||
script: Script.fromAddress(this._change),
|
script: Script.fromAddress(this._change),
|
||||||
satoshis: available - fee
|
satoshis: available - fee
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
this._changeOutput = undefined;
|
this._changeOutput = undefined;
|
||||||
}
|
}
|
||||||
this._changeSetup = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Transaction.prototype.getFee = function() {
|
Transaction.prototype.getFee = function() {
|
||||||
@ -602,7 +609,6 @@ Transaction.prototype.removeOutput = function(index) {
|
|||||||
*/
|
*/
|
||||||
Transaction.prototype.sign = function(privateKey, sigtype) {
|
Transaction.prototype.sign = function(privateKey, sigtype) {
|
||||||
$.checkState(this.hasAllUtxoInfo());
|
$.checkState(this.hasAllUtxoInfo());
|
||||||
this._updateChangeOutput();
|
|
||||||
var self = this;
|
var self = this;
|
||||||
if (_.isArray(privateKey)) {
|
if (_.isArray(privateKey)) {
|
||||||
_.each(privateKey, function(privateKey) {
|
_.each(privateKey, function(privateKey) {
|
||||||
|
|||||||
@ -250,6 +250,14 @@ describe('Transaction', function() {
|
|||||||
return transaction.serialize(true);
|
return transaction.serialize(true);
|
||||||
}).to.not.throw();
|
}).to.not.throw();
|
||||||
});
|
});
|
||||||
|
it('stores the fee set by the user', function() {
|
||||||
|
var fee = 1000000;
|
||||||
|
var serialized = new Transaction()
|
||||||
|
.fee(fee)
|
||||||
|
.toObject();
|
||||||
|
var deserialized = new Transaction(serialized);
|
||||||
|
expect(deserialized._fee).to.equal(fee);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('checked serialize', function() {
|
describe('checked serialize', function() {
|
||||||
@ -265,7 +273,8 @@ describe('Transaction', function() {
|
|||||||
var transaction = new Transaction()
|
var transaction = new Transaction()
|
||||||
.from(simpleUtxoWith1BTC)
|
.from(simpleUtxoWith1BTC)
|
||||||
.change(changeAddress)
|
.change(changeAddress)
|
||||||
.to(toAddress, 1);
|
.fee(50000000)
|
||||||
|
.to(toAddress, 40000000);
|
||||||
expect(function() {
|
expect(function() {
|
||||||
return transaction.serialize();
|
return transaction.serialize();
|
||||||
}).to.throw(errors.Transaction.FeeError);
|
}).to.throw(errors.Transaction.FeeError);
|
||||||
@ -325,6 +334,29 @@ describe('Transaction', function() {
|
|||||||
expect(deserialized.inputs[0] instanceof Transaction.Input.MultiSigScriptHash).to.equal(true);
|
expect(deserialized.inputs[0] instanceof Transaction.Input.MultiSigScriptHash).to.equal(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('checks on adding inputs', function() {
|
||||||
|
var transaction = new Transaction();
|
||||||
|
it('fails if no output script is provided', function() {
|
||||||
|
expect(function() {
|
||||||
|
transaction.addInput(new Transaction.Input());
|
||||||
|
}).to.throw(errors.Transaction.NeedMoreInfo);
|
||||||
|
});
|
||||||
|
it('fails if no satoshi amount is provided', function() {
|
||||||
|
var input = new Transaction.Input();
|
||||||
|
expect(function() {
|
||||||
|
transaction.addInput(input);
|
||||||
|
}).to.throw(errors.Transaction.NeedMoreInfo);
|
||||||
|
expect(function() {
|
||||||
|
transaction.addInput(new Transaction.Input(), Script.empty());
|
||||||
|
}).to.throw(errors.Transaction.NeedMoreInfo);
|
||||||
|
});
|
||||||
|
it('allows output and transaction to be feed as arguments', function() {
|
||||||
|
expect(function() {
|
||||||
|
transaction.addInput(new Transaction.Input(), Script.empty(), 0);
|
||||||
|
}).to.not.throw();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var tx_empty_hex = '01000000000000000000';
|
var tx_empty_hex = '01000000000000000000';
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user