From dbfbc26adcb71bece794c7d8d8dfee84e4bddae7 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Thu, 27 Mar 2014 16:32:28 -0300 Subject: [PATCH] tracking down Transaction test problems --- ScriptInterpreter.js | 23 +++++++++++++++++++---- Transaction.js | 6 +++--- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/ScriptInterpreter.js b/ScriptInterpreter.js index 5240308a0..ef14282d1 100644 --- a/ScriptInterpreter.js +++ b/ScriptInterpreter.js @@ -691,10 +691,11 @@ ScriptInterpreter.prototype.eval = function eval(script, tx, inIndex, hashType, // Convert to binary var scriptCode = Script.fromChunks(scriptChunks); - // Drop the signatures, since a signature can't sign itself var that = this; sigs.forEach(function(sig) { + // check each signature is canonical that.isCanonicalSignature(new Buffer(sig)); + // Drop the signatures for the subscript, since a signature can't sign itself scriptCode.findAndDelete(sig); }); @@ -706,13 +707,15 @@ ScriptInterpreter.prototype.eval = function eval(script, tx, inIndex, hashType, function checkMultiSigStep() { if (success && sigsCount > 0) { var sig = sigs[isig]; - var key = keys[ikey]; + var pubkey = keys[ikey]; - checkSig(sig, key, scriptCode, tx, inIndex, hashType, function(e, result) { + checkSig(sig, pubkey, scriptCode, tx, inIndex, hashType, function(e, result) { if (!e && result) { + console.log('sig '+isig+' succeeded'); isig++; sigsCount--; } else { + console.log('key '+ikey+' failed '+e +' '+result); ikey++; keysCount--; @@ -996,17 +999,24 @@ ScriptInterpreter.verifyFull = var checkSig = ScriptInterpreter.checkSig = function(sig, pubkey, scriptCode, tx, n, hashType, callback) { + // https://en.bitcoin.it/wiki/OP_CHECKSIG#How_it_works if (!sig.length) { + console.log('sig length 0'); callback(null, false); return; } - if (hashType == 0) { + // If the hash-type value is 0, then it is replaced by the last_byte of the signature. + if (hashType === 0) { hashType = sig[sig.length - 1]; + console.log('hash type 0 -> '+hashType); } else if (hashType != sig[sig.length - 1]) { + console.log('wrong hashtype'); callback(null, false); return; } + + // Then the last byte of the signature is always deleted. (hashType removed) sig = sig.slice(0, sig.length - 1); // Signature verification requires a special hash procedure @@ -1015,6 +1025,11 @@ var checkSig = ScriptInterpreter.checkSig = // Verify signature var key = new Key(); key.public = pubkey; + + console.log('pubkey before verification: '+buffertools.toHex(key.public)); + console.log('sig before verification: '+buffertools.toHex(sig)); + console.log('hash before verification: '+buffertools.toHex(hash)); + key.verifySignature(hash, sig, callback); }; diff --git a/Transaction.js b/Transaction.js index c90ce4c15..0221190ba 100644 --- a/Transaction.js +++ b/Transaction.js @@ -316,8 +316,7 @@ Transaction.prototype.hashForSignature = // Serialize inputs if (hashType & SIGHASH_ANYONECANPAY) { - // Blank out all inputs except current one, not recommended for open - // transactions. + // Blank out all inputs except current one bytes.varint(1); bytes.put(this.ins[inIndex].o); bytes.varint(script.buffer.length); @@ -386,7 +385,8 @@ Transaction.prototype.hashForSignature = var buffer = bytes.buffer(); - // Append hashType + // An array of bytes is constructed from the serialized txCopy + // appended by four bytes for the hash type. buffer = Buffer.concat([buffer, new Buffer([parseInt(hashType), 0, 0, 0])]); return util.twoSha256(buffer);