refactor signing.

This commit is contained in:
Christopher Jeffrey 2016-02-11 01:29:35 -08:00
parent b963809318
commit 4a6c73fc8e
4 changed files with 48 additions and 30 deletions

View File

@ -331,12 +331,18 @@ Address.prototype.ownInput = function ownInput(tx, index) {
return inputs; return inputs;
}; };
Address.prototype.scriptInputs = function scriptInputs(tx) { Address.prototype.scriptInputs = function scriptInputs(tx, index) {
var self = this; var self = this;
var publicKey = this.getPublicKey(); var publicKey = this.getPublicKey();
var redeem = this.getScript(); var redeem = this.getScript();
if (index && typeof index === 'object')
index = tx.inputs.indexOf(index);
return tx.inputs.reduce(function(total, input, i) { return tx.inputs.reduce(function(total, input, i) {
if (index != null && index !== i)
return total;
if (!input.output) if (!input.output)
return total; return total;
@ -350,15 +356,21 @@ Address.prototype.scriptInputs = function scriptInputs(tx) {
}, 0); }, 0);
}; };
Address.prototype.signInputs = function signInputs(tx, type) { Address.prototype.signInputs = function signInputs(tx, type, index) {
var self = this; var self = this;
var key = this.key; var key = this.key;
var total = 0; var total = 0;
if (index && typeof index === 'object')
index = tx.inputs.indexOf(index);
if (!key.privateKey) if (!key.privateKey)
return 0; return 0;
return tx.inputs.reduce(function(total, input, i) { return tx.inputs.reduce(function(total, input, i) {
if (index != null && index !== i)
return total;
if (!input.output) if (!input.output)
return total; return total;
@ -372,17 +384,22 @@ Address.prototype.signInputs = function signInputs(tx, type) {
}, 0); }, 0);
}; };
Address.prototype.sign = function sign(tx, type) { Address.prototype.sign = function sign(tx, type, index) {
var self = this; var self = this;
var publicKey = this.getPublicKey();
var redeem = this.getScript(); var redeem = this.getScript();
var key = this.key; var key = this.key;
if (index && typeof index === 'object')
index = tx.inputs.indexOf(index);
if (!key.privateKey) if (!key.privateKey)
return 0; return 0;
// Add signature script to each input // Add signature script to each input
return tx.inputs.reduce(function(total, input, i) { return tx.inputs.reduce(function(total, input, i) {
if (index != null && index !== i)
return total;
// Filter inputs that this wallet own // Filter inputs that this wallet own
if (!input.output) if (!input.output)
return total; return total;
@ -390,7 +407,7 @@ Address.prototype.sign = function sign(tx, type) {
if (!self.ownOutput(input.output)) if (!self.ownOutput(input.output))
return total; return total;
if (tx.scriptSig(i, key, publicKey, redeem, type)) if (tx.sign(i, key, redeem, type))
total++; total++;
return total; return total;

View File

@ -218,7 +218,7 @@ TX.prototype._inputIndex = function _inputIndex(hash, index) {
return -1; return -1;
}; };
TX.prototype.scriptInput = function scriptInput(index, pub, redeem) { TX.prototype.scriptInput = function scriptInput(index, publicKey, redeem) {
var input, s, n, i; var input, s, n, i;
if (typeof index !== 'number') if (typeof index !== 'number')
@ -249,7 +249,7 @@ TX.prototype.scriptInput = function scriptInput(index, pub, redeem) {
if (bcoin.script.isPubkey(s)) { if (bcoin.script.isPubkey(s)) {
// P2PK // P2PK
if (!utils.isEqual(s[0], pub)) if (!utils.isEqual(s[0], publicKey))
return false; return false;
// Already has a script template (at least) // Already has a script template (at least)
if (input.script.length) if (input.script.length)
@ -257,16 +257,16 @@ TX.prototype.scriptInput = function scriptInput(index, pub, redeem) {
input.script = [[]]; input.script = [[]];
} else if (bcoin.script.isPubkeyhash(s)) { } else if (bcoin.script.isPubkeyhash(s)) {
// P2PKH // P2PKH
if (!utils.isEqual(s[2], bcoin.address.hash160(pub))) if (!utils.isEqual(s[2], bcoin.address.hash160(publicKey)))
return false; return false;
// Already has a script template (at least) // Already has a script template (at least)
if (input.script.length) if (input.script.length)
return true; return true;
input.script = [[], pub]; input.script = [[], publicKey];
} else if (bcoin.script.isMultisig(s)) { } else if (bcoin.script.isMultisig(s)) {
// Multisig // Multisig
for (i = 0; i < s.length; i++) { for (i = 0; i < s.length; i++) {
if (utils.isEqual(s[i], pub)) if (utils.isEqual(s[i], publicKey))
break; break;
} }
@ -290,7 +290,7 @@ TX.prototype.scriptInput = function scriptInput(index, pub, redeem) {
input.script[i + 1] = []; input.script[i + 1] = [];
} else { } else {
for (i = 0; i < s.length; i++) { for (i = 0; i < s.length; i++) {
if (utils.isEqual(s[i], pub)) if (utils.isEqual(s[i], publicKey))
break; break;
} }
@ -371,8 +371,8 @@ TX.prototype.signature = TX.prototype.createSignature;
// Sign the now-built scriptSigs // Sign the now-built scriptSigs
TX.prototype.signInput = function signInput(index, key, type) { TX.prototype.signInput = function signInput(index, key, type) {
var input, s, hash, signature; var input, s, signature, ki, signatures, i;
var len, m, n, keys, pub, pkh, ki, signatures, i; var len, m, n, keys, publicKey, keyHash;
if (typeof index !== 'number') if (typeof index !== 'number')
index = this.inputs.indexOf(index); index = this.inputs.indexOf(index);
@ -401,9 +401,8 @@ TX.prototype.signInput = function signInput(index, key, type) {
len--; len--;
} }
// Get pubkey and pubkey hash. // Get pubkey.
pub = key.getPublic(true, 'array'); publicKey = key.getPublic(true, 'array');
pkh = bcoin.address.hash160(pub);
// Add signatures. // Add signatures.
if (bcoin.script.isPubkey(s)) { if (bcoin.script.isPubkey(s)) {
@ -418,7 +417,7 @@ TX.prototype.signInput = function signInput(index, key, type) {
return true; return true;
// Make sure the pubkey is ours. // Make sure the pubkey is ours.
if (!utils.isEqual(pub, s[0])) if (!utils.isEqual(publicKey, s[0]))
return false; return false;
input.script[0] = signature; input.script[0] = signature;
@ -438,7 +437,8 @@ TX.prototype.signInput = function signInput(index, key, type) {
return true; return true;
// Make sure the pubkey hash is ours. // Make sure the pubkey hash is ours.
if (!utils.isEqual(pkh, s[2])) keyHash = bcoin.address.hash160(publicKey);
if (!utils.isEqual(keyHash, s[2]))
return false; return false;
input.script[0] = signature; input.script[0] = signature;
@ -502,7 +502,7 @@ TX.prototype.signInput = function signInput(index, key, type) {
// Find the key index so we can place // Find the key index so we can place
// the signature in the same index. // the signature in the same index.
for (ki = 0; ki < keys.length; ki++) { for (ki = 0; ki < keys.length; ki++) {
if (utils.isEqual(pub, keys[ki])) if (utils.isEqual(publicKey, keys[ki]))
break; break;
} }
@ -555,7 +555,8 @@ TX.prototype.signInput = function signInput(index, key, type) {
return signatures === m; return signatures === m;
}; };
TX.prototype.scriptSig = function scriptSig(index, key, pub, redeem, type) { TX.prototype.sign = function sign(index, key, redeem, type) {
var publicKey = key.getPublic(true, 'array');
var input; var input;
if (index && typeof index === 'object') if (index && typeof index === 'object')
@ -565,14 +566,14 @@ TX.prototype.scriptSig = function scriptSig(index, key, pub, redeem, type) {
assert(input); assert(input);
// Build script for input // Build script for input
if (!this.scriptInput(index, pub, redeem)) if (!this.scriptInput(index, publicKey, redeem))
return false; return false;
// Sign input // Sign input
if (!this.signInput(index, key, type)) if (!this.signInput(index, key, type))
return false; return false;
return input.script; return true;
}; };
TX.prototype.isSigned = function isSigned(index, required) { TX.prototype.isSigned = function isSigned(index, required) {

View File

@ -683,27 +683,27 @@ Wallet.prototype.syncOutputDepth = function syncOutputDepth(tx) {
this.setReceiveDepth(depth.receive); this.setReceiveDepth(depth.receive);
}; };
Wallet.prototype.scriptInputs = function scriptInputs(tx) { Wallet.prototype.scriptInputs = function scriptInputs(tx, index) {
this.fillPrevout(tx); this.fillPrevout(tx);
var addresses = this.deriveInputs(tx); var addresses = this.deriveInputs(tx);
return addresses.reduce(function(total, address) { return addresses.reduce(function(total, address) {
return total + address.scriptInputs(tx); return total + address.scriptInputs(tx, index);
}, 0); }, 0);
}; };
Wallet.prototype.signInputs = function signInputs(tx, type) { Wallet.prototype.signInputs = function signInputs(tx, type, index) {
this.fillPrevout(tx); this.fillPrevout(tx);
var addresses = this.deriveInputs(tx); var addresses = this.deriveInputs(tx);
return addresses.reduce(function(total, address) { return addresses.reduce(function(total, address) {
return total + address.signInputs(tx, type); return total + address.signInputs(tx, type, index);
}, 0); }, 0);
}; };
Wallet.prototype.sign = function sign(tx, type) { Wallet.prototype.sign = function sign(tx, type, index) {
this.fillPrevout(tx); this.fillPrevout(tx);
var addresses = this.deriveInputs(tx); var addresses = this.deriveInputs(tx);
return addresses.reduce(function(total, address) { return addresses.reduce(function(total, address) {
return total + address.sign(tx, type); return total + address.sign(tx, type, index);
}, 0); }, 0);
}; };

View File

@ -256,8 +256,8 @@ describe('Wallet', function() {
tx.input(unspent1[1]); tx.input(unspent1[1]);
tx.input(unspent1[2]); tx.input(unspent1[2]);
tx.input(unspent2[1]); tx.input(unspent2[1]);
assert.equal(w1.sign(tx, 'all', tx.inputs.slice()), 2); assert.equal(w1.sign(tx, 'all'), 2);
assert.equal(w2.sign(tx, 'all', tx.inputs.slice(2)), 1); assert.equal(w2.sign(tx, 'all'), 1);
// Verify // Verify
assert.equal(tx.verify(), true); assert.equal(tx.verify(), true);