This commit is contained in:
Christopher Jeffrey 2016-04-05 02:58:53 -07:00
parent 86312d9241
commit 141dbcb65e

View File

@ -191,18 +191,16 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
redeemScript = addr.program.encode(); redeemScript = addr.program.encode();
vector = input.witness.items; vector = input.witness.items;
dummy = new Buffer([]); dummy = new Buffer([]);
assert(addr.program.code[0] === opcodes.OP_0, if (addr.program.isWitnessScripthash()) {
'Non-zero version passed to address.');
if (addr.program.code[1].length === 32) {
// P2WSH nested within pay-to-scripthash // P2WSH nested within pay-to-scripthash
// (it had to be this complicated, didn't it?) // (it had to be this complicated, didn't it?)
witnessScript = addr.script.encode(); witnessScript = addr.script.encode();
prev = addr.script; prev = addr.script;
} else if (addr.program.code[1].length === 20) { } else if (addr.program.isWitnessPubkeyhash()) {
// P2WPKH nested within pay-to-scripthash. // P2WPKH nested within pay-to-scripthash.
prev = Script.createPubkeyhash(addr.keyHash); prev = Script.createPubkeyhash(addr.keyHash);
} else { } else {
assert(false, 'Unknown program data length passed to address.'); assert(false, 'Unknown program.');
} }
} else if (addr.script && utils.isEqual(prev.code[1], addr.scriptHash160)) { } else if (addr.script && utils.isEqual(prev.code[1], addr.scriptHash160)) {
// Regular P2SH. // Regular P2SH.
@ -218,17 +216,14 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
vector = input.witness.items; vector = input.witness.items;
dummy = new Buffer([]); dummy = new Buffer([]);
if (prev.code[0] !== opcodes.OP_0) if (prev.isWitnessScripthash()) {
return false;
if (prev.code[1].length === 32) {
// Bare P2WSH. // Bare P2WSH.
if (!addr.script || !utils.isEqual(prev.code[1], addr.scriptHash256)) if (!addr.script || !utils.isEqual(prev.code[1], addr.scriptHash256))
return false; return false;
witnessScript = addr.script.encode(); witnessScript = addr.script.encode();
prev = addr.script; prev = addr.script;
} else if (prev.code[1].length === 20) { } else if (prev.isWitnessPubkeyhash()) {
// Bare P2WPKH. // Bare P2WPKH.
if (!utils.isEqual(prev.code[1], addr.keyHash)) if (!utils.isEqual(prev.code[1], addr.keyHash))
return false; return false;
@ -320,7 +315,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
}; };
MTX.prototype.createSignature = function createSignature(index, prev, key, type, version) { MTX.prototype.createSignature = function createSignature(index, prev, key, type, version) {
var hash, signature; var hash;
if (typeof index !== 'number') if (typeof index !== 'number')
index = this.inputs.indexOf(index); index = this.inputs.indexOf(index);
@ -336,16 +331,11 @@ MTX.prototype.createSignature = function createSignature(index, prev, key, type,
hash = this.signatureHash(index, prev, type, version); hash = this.signatureHash(index, prev, type, version);
// Sign the transaction with our one input // Sign the transaction with our one input
signature = Script.sign(hash, key, type); return Script.sign(hash, key, type);
// Something is broken if this doesn't work:
// assert(Script.checksig(hash, signature, key), 'BUG: Verify failed.');
return signature;
}; };
MTX.prototype.signInput = function signInput(index, addr, type) { MTX.prototype.signInput = function signInput(index, addr, type) {
var input, prev, signature, ki, signatures, i; var input, prev, signature, index, signatures, i;
var len, m, n, keys, vector, dummy, version; var len, m, n, keys, vector, dummy, version;
assert(this.ts === 0, 'Cannot modify a confirmed tx.'); assert(this.ts === 0, 'Cannot modify a confirmed tx.');
@ -360,7 +350,7 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
// We should have previous outputs by now. // We should have previous outputs by now.
assert(input.coin); assert(input.coin);
// Get the previous output's subscript // Get the previous output's script
prev = input.coin.script; prev = input.coin.script;
vector = input.script.code; vector = input.script.code;
@ -398,10 +388,8 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
// Create our signature. // Create our signature.
signature = this.createSignature(index, prev, addr.key, type, version); signature = this.createSignature(index, prev, addr.key, type, version);
// Add signatures. // P2PK
if (prev.isPubkey()) { if (prev.isPubkey()) {
// P2PK
// Already signed. // Already signed.
if (Script.isSignature(vector[0])) if (Script.isSignature(vector[0]))
return true; return true;
@ -415,9 +403,8 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
return true; return true;
} }
// P2PKH
if (prev.isPubkeyhash()) { if (prev.isPubkeyhash()) {
// P2PKH
// Already signed. // Already signed.
if (Script.isSignature(vector[0])) if (Script.isSignature(vector[0]))
return true; return true;
@ -431,9 +418,8 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
return true; return true;
} }
// Multisig
if (prev.isMultisig()) { if (prev.isMultisig()) {
// Multisig
// Grab the redeem script's keys to figure // Grab the redeem script's keys to figure
// out where our key should go. // out where our key should go.
keys = prev.code.slice(1, -2); keys = prev.code.slice(1, -2);
@ -488,25 +474,25 @@ MTX.prototype.signInput = function signInput(index, addr, 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.
ki = utils.indexOf(keys, addr.publicKey); index = utils.indexOf(keys, addr.publicKey);
// Our public key is not in the prev_out // Our public key is not in the prev_out
// script. We tried to sign a transaction // script. We tried to sign a transaction
// that is not redeemable by us. // that is not redeemable by us.
if (ki === -1) if (index === -1)
return false; return false;
// Offset key index by one to turn it into // Offset key index by one to turn it into
// "sig index". Accounts for OP_0 byte at // "sig index". Accounts for OP_0 byte at
// the start. // the start.
ki++; index++;
// Add our signature to the correct slot // Add our signature to the correct slot
// and increment the total number of // and increment the total number of
// signatures. // signatures.
if (ki < len && signatures < m) { if (index < len && signatures < m) {
if (Script.isZero(vector[ki])) { if (Script.isZero(vector[index])) {
vector[ki] = signature; vector[index] = signature;
signatures++; signatures++;
} }
} }
@ -532,8 +518,8 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
} }
// Sanity checks. // Sanity checks.
assert.equal(signatures, m); assert(signatures === m);
assert.equal(len - 1, m); assert(len - 1 === m);
} }
return signatures === m; return signatures === m;
@ -551,7 +537,7 @@ MTX.prototype.isSigned = function isSigned() {
if (!input.coin) if (!input.coin)
return false; return false;
// Get the prevout's subscript // Get the prevout's script
prev = input.coin.script; prev = input.coin.script;
// Script length, needed for multisig // Script length, needed for multisig
@ -735,7 +721,7 @@ MTX.prototype.maxSize = function maxSize(options, force) {
continue; continue;
} }
// Get the previous output's subscript // Get the previous output's script
prev = input.coin.script; prev = input.coin.script;
// If we have access to the redeem script, // If we have access to the redeem script,