Browse Source

refactor transaction input deserializtion

patch-2
Manuel Araoz 10 years ago
parent
commit
8ca396c34f
  1. 5
      lib/errors/spec.js
  2. 45
      lib/transaction/transaction.js
  3. 10
      test/transaction/transaction.js

5
lib/errors/spec.js

@ -24,7 +24,7 @@ module.exports = [{
name: 'InvalidArgument', name: 'InvalidArgument',
message: function() { message: function() {
return 'Invalid Argument' + (arguments[0] ? (': ' + arguments[0]) : '') + return 'Invalid Argument' + (arguments[0] ? (': ' + arguments[0]) : '') +
(arguments[1] ? (' Documentation: ' + docsURL + arguments[1]): ''); (arguments[1] ? (' Documentation: ' + docsURL + arguments[1]) : '');
} }
}, { }, {
name: 'AbstractMethodInvoked', name: 'AbstractMethodInvoked',
@ -53,6 +53,9 @@ module.exports = [{
errors: [{ errors: [{
name: 'MissingScript', name: 'MissingScript',
message: 'Need a script to create an input' message: 'Need a script to create an input'
}, {
name: 'UnsupportedScript',
message: 'Unsupported input script type: {0}'
}] }]
}, { }, {
name: 'NeedMoreInfo', name: 'NeedMoreInfo',

45
lib/transaction/transaction.js

@ -226,33 +226,46 @@ Transaction.prototype.toObject = function toObject() {
this.outputs.forEach(function(output) { this.outputs.forEach(function(output) {
outputs.push(output.toObject()); outputs.push(output.toObject());
}); });
return { var obj = {
changeScript: this._changeScript ? this._changeScript.toString() : undefined,
changeIndex: !_.isUndefined(this._changeIndex) ? this._changeIndex : undefined,
fee: this._fee ? this._fee : undefined,
version: this.version, version: this.version,
inputs: inputs, inputs: inputs,
outputs: outputs, outputs: outputs,
nLockTime: this.nLockTime nLockTime: this.nLockTime
}; };
if (this._changeScript) {
obj.changeScript = this._changeScript.toString();
}
if (!_.isUndefined(this._changeIndex)) {
obj.changeIndex = this._changeIndex;
}
if (!_.isUndefined(this._fee)) {
obj.fee = this._fee;
}
return obj;
}; };
Transaction.prototype.fromObject = function(transaction) { Transaction.prototype.fromObject = function(transaction) {
var self = this; var self = this;
_.each(transaction.inputs, function(input) { _.each(transaction.inputs, function(input) {
if (input.output && input.output.script) { if (!input.output || !input.output.script) {
input.output.script = new Script(input.output.script); self.uncheckedAddInput(new Input(input));
if (input.output.script.isPublicKeyHashOut()) { return;
self.addInput(new Input.PublicKeyHash(input)); }
return; input.output.script = new Script(input.output.script);
} else if (input.output.script.isScriptHashOut() && input.publicKeys && input.threshold) { var txin;
self.addInput(new Input.MultiSigScriptHash( if (input.output.script.isPublicKeyHashOut()) {
input, input.publicKeys, input.threshold, input.signatures console.log('p2pkh');
)); console.log(input.output.script);
return; txin = new Input.PublicKeyHash(input);
} } else if (input.output.script.isScriptHashOut() && input.publicKeys && input.threshold) {
console.log('p2sh');
txin = new Input.MultiSigScriptHash(
input, input.publicKeys, input.threshold, input.signatures
);
} else {
throw new errors.Transaction.Input.UnsupportedScript(input.output.script);
} }
self.uncheckedAddInput(new Input(input)); self.addInput(txin);
}); });
_.each(transaction.outputs, function(output) { _.each(transaction.outputs, function(output) {
self.addOutput(new Output(output)); self.addOutput(new Output(output));

10
test/transaction/transaction.js

@ -490,12 +490,20 @@ describe('Transaction', function() {
}).to.throw(errors.Transaction.NLockTimeOutOfRange); }).to.throw(errors.Transaction.NLockTimeOutOfRange);
}); });
}); });
it('handles anyone-can-spend utxo', function() { it('handles anyone-can-spend utxo', function() {
var transaction = new Transaction() var transaction = new Transaction()
.from(anyoneCanSpendUTXO) .from(anyoneCanSpendUTXO)
.to(toAddress, 50000); .to(toAddress, 50000);
should.exist(transaction); should.exist(transaction);
}); });
it('handles unsupported utxo in tx object', function() {
var transaction = new Transaction();
transaction.fromJSON.bind(transaction, unsupportedTxObj)
.should.throw('Unsupported input script type: OP_1 OP_ADD OP_2 OP_EQUAL');
});
}); });
var tx_empty_hex = '01000000000000000000'; var tx_empty_hex = '01000000000000000000';
@ -506,3 +514,5 @@ var tx_1_id = '779a3e5b3c2c452c85333d8521f804c1a52800e60f4b7c3bbe36f4bab350b72c'
var tx2hex = '0100000001e07d8090f4d4e6fcba6a2819e805805517eb19e669e9d2f856b41d4277953d640000000091004730440220248bc60bb309dd0215fbde830b6371e3fdc55685d11daa9a3c43828892e26ce202205f10cd4011f3a43657260a211f6c4d1fa81b6b6bdd6577263ed097cc22f4e5b50147522102fa38420cec94843ba963684b771ba3ca7ce1728dc2c7e7cade0bf298324d6b942103f948a83c20b2e7228ca9f3b71a96c2f079d9c32164cd07f08fbfdb483427d2ee52aeffffffff01180fe200000000001976a914ccee7ce8e8b91ec0bc23e1cfb6324461429e6b0488ac00000000'; var tx2hex = '0100000001e07d8090f4d4e6fcba6a2819e805805517eb19e669e9d2f856b41d4277953d640000000091004730440220248bc60bb309dd0215fbde830b6371e3fdc55685d11daa9a3c43828892e26ce202205f10cd4011f3a43657260a211f6c4d1fa81b6b6bdd6577263ed097cc22f4e5b50147522102fa38420cec94843ba963684b771ba3ca7ce1728dc2c7e7cade0bf298324d6b942103f948a83c20b2e7228ca9f3b71a96c2f079d9c32164cd07f08fbfdb483427d2ee52aeffffffff01180fe200000000001976a914ccee7ce8e8b91ec0bc23e1cfb6324461429e6b0488ac00000000';
var unsupportedTxObj = '{"version":1,"inputs":[{"prevTxId":"a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458","outputIndex":0,"sequenceNumber":4294967295,"script":"OP_1","output":{"satoshis":1020000,"script":"OP_1 OP_ADD OP_2 OP_EQUAL"}}],"outputs":[{"satoshis":1010000,"script":"OP_DUP OP_HASH160 20 0x7821c0a3768aa9d1a37e16cf76002aef5373f1a8 OP_EQUALVERIFY OP_CHECKSIG"}],"nLockTime":0}';

Loading…
Cancel
Save