fix scriptInput/signInput for multisig/p2sh.

This commit is contained in:
Christopher Jeffrey 2015-12-05 18:58:27 -08:00
parent db0da78ae5
commit 4f76b9f18c
2 changed files with 31 additions and 22 deletions

View File

@ -112,7 +112,7 @@ TX.prototype._inputIndex = function _inputIndex(hash, index) {
return -1; return -1;
}; };
TX.prototype.signature = function(input, key) { TX.prototype.signature = function(input, key, type) {
// Get the previous output's subscript // Get the previous output's subscript
var s = input.out.tx.getSubscript(input.out.index); var s = input.out.tx.getSubscript(input.out.index);
@ -142,13 +142,11 @@ TX.prototype.scriptInput = function(input, pub, nsigs) {
// Multisig // Multisig
// raw format: OP_FALSE [sig-1] [sig-2] ... // raw format: OP_FALSE [sig-1] [sig-2] ...
if (bcoin.script.isMultisig(s)) { if (bcoin.script.isMultisig(s)) {
if (!nsigs) { if (!nsigs)
throw new Error('`nsigs` is required for multisig'); throw new Error('`nsigs` is required for multisig');
}
input.script = [ constants.opcodes['false'] ]; input.script = [ constants.opcodes['false'] ];
for (var i = 0; i < nsigs; i++) { for (var i = 0; i < nsigs; i++)
input.script[i + 1] = constants.opcodes['0']; input.script[i + 1] = constants.opcodes['0'];
}
return; return;
} }
@ -157,21 +155,22 @@ TX.prototype.scriptInput = function(input, pub, nsigs) {
if (bcoin.script.isScripthash(s)) { if (bcoin.script.isScripthash(s)) {
input.script = [ constants.opcodes['false'] ]; input.script = [ constants.opcodes['false'] ];
var m = pub[0] - constants.opcodes['1'] + 1; var m = pub[0] - constants.opcodes['1'] + 1;
for (var i = 0; i < m; i++) { for (var i = 0; i < m; i++)
input.script[i + 1] = constants.opcodes['0']; input.script[i + 1] = constants.opcodes['0'];
}
// P2SH requires the redeem script after signatures // P2SH requires the redeem script after signatures
if (bcoin.script.isScripthash(s)) { if (bcoin.script.isScripthash(s))
input.script.push(pub); input.script.push(pub);
}
return; return;
} }
throw new Error('could not identify prev_out type'); throw new Error('scriptInput(): could not identify prev_out type');
}; };
// Sign the now-built scriptSigs // Sign the now-built scriptSigs
TX.prototype.signInput = function(input, key) { TX.prototype.signInput = function(input, key, type) {
if (!type)
type = 'all';
// Get the previous output's subscript // Get the previous output's subscript
var s = input.out.tx.getSubscript(input.out.index); var s = input.out.tx.getSubscript(input.out.index);
@ -191,29 +190,39 @@ TX.prototype.signInput = function(input, key) {
} }
// Multisig // Multisig
// empty array == OP_FALSE == OP_0
// raw format: OP_FALSE [sig-1] [sig-2] ... // raw format: OP_FALSE [sig-1] [sig-2] ...
// p2sh format: OP_FALSE [sig-1] [sig-2] ... [redeem-script] // p2sh format: OP_FALSE [sig-1] [sig-2] ... [redeem-script]
if (bcoin.script.isMultisig(s) || bcoin.script.isScripthash(s)) { if (bcoin.script.isMultisig(s) || bcoin.script.isScripthash(s)) {
var l = input.script.length; var len = input.script.length;
if (bcoin.script.isScripthash(s)) {
l--; if (bcoin.script.isScripthash(s))
} len--;
for (var i = 0; i < l; i++) {
input.script[i + 1] = signature; for (var i = 1; i < len; i++) {
// Already signed
if (utils.isEqual(input.script[i], signature))
break;
if (input.script[i] === constants.opcodes['0']) {
input.script[i] = signature;
break;
}
} }
return;
} }
throw new Error('signInput(): could not identify prev_out type');
}; };
// Build the scriptSig and sign it // Build the scriptSig and sign it
TX.prototype.scriptSig = function(input, key, pub, nsigs) { TX.prototype.scriptSig = function(input, key, pub, type, nsigs) {
// Build script for input // Build script for input
tx.scriptInput(input, pub, nsigs); tx.scriptInput(input, pub, nsigs);
// Sign input // Sign input
tx.signInput(input, key); tx.signInput(input, key, type);
return this.input.script; return input.script;
}; };
TX.prototype.input = function input(i, index) { TX.prototype.input = function input(i, index) {

View File

@ -347,7 +347,7 @@ Wallet.prototype.sign = function sign(tx, type, inputs) {
if (!input.out.tx || !this.ownOutput(input.out.tx)) if (!input.out.tx || !this.ownOutput(input.out.tx))
return false; return false;
tx.scriptSig(input, key, pub, nsigs); tx.scriptSig(input, key, pub, type, nsigs);
return true; return true;
}, this); }, this);