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;
};
TX.prototype.signature = function(input, key) {
TX.prototype.signature = function(input, key, type) {
// Get the previous output's subscript
var s = input.out.tx.getSubscript(input.out.index);
@ -142,13 +142,11 @@ TX.prototype.scriptInput = function(input, pub, nsigs) {
// Multisig
// raw format: OP_FALSE [sig-1] [sig-2] ...
if (bcoin.script.isMultisig(s)) {
if (!nsigs) {
if (!nsigs)
throw new Error('`nsigs` is required for multisig');
}
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'];
}
return;
}
@ -157,21 +155,22 @@ TX.prototype.scriptInput = function(input, pub, nsigs) {
if (bcoin.script.isScripthash(s)) {
input.script = [ constants.opcodes['false'] ];
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'];
}
// P2SH requires the redeem script after signatures
if (bcoin.script.isScripthash(s)) {
if (bcoin.script.isScripthash(s))
input.script.push(pub);
}
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
TX.prototype.signInput = function(input, key) {
TX.prototype.signInput = function(input, key, type) {
if (!type)
type = 'all';
// Get the previous output's subscript
var s = input.out.tx.getSubscript(input.out.index);
@ -191,29 +190,39 @@ TX.prototype.signInput = function(input, key) {
}
// Multisig
// empty array == OP_FALSE == OP_0
// raw format: OP_FALSE [sig-1] [sig-2] ...
// p2sh format: OP_FALSE [sig-1] [sig-2] ... [redeem-script]
if (bcoin.script.isMultisig(s) || bcoin.script.isScripthash(s)) {
var l = input.script.length;
if (bcoin.script.isScripthash(s)) {
l--;
}
for (var i = 0; i < l; i++) {
input.script[i + 1] = signature;
var len = input.script.length;
if (bcoin.script.isScripthash(s))
len--;
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
TX.prototype.scriptSig = function(input, key, pub, nsigs) {
TX.prototype.scriptSig = function(input, key, pub, type, nsigs) {
// Build script for input
tx.scriptInput(input, pub, nsigs);
// 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) {

View File

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