From d56fb0457503322d55e2ae434ad4649b373752f4 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 16 Dec 2014 17:39:44 -0300 Subject: [PATCH 1/3] add ScriptInterpreter#verify docs --- lib/script_interpreter.js | 13 +++++++++++++ test/script_interpreter.js | 14 ++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/script_interpreter.js b/lib/script_interpreter.js index 952fc9b41..88b1f0d0f 100644 --- a/lib/script_interpreter.js +++ b/lib/script_interpreter.js @@ -1045,6 +1045,16 @@ ScriptInterpreter.prototype.step = function() { } /** + * Verifies a Script by executing it and returns true if it is valid. + * This function needs to be provided with the scriptSig and the scriptPubkey + * separately. + * @param {Script} scriptSig - the script's first part (corresponding to the tx input) + * @param {Script} scriptPubkey - the script's last part (corresponding to the tx output) + * @param {Transaction} [tx] - the Transaction containing the scriptSig in one input (used + * to check signature validity for some opcodes like OP_CHECKSIG) + * @param {number} nin - index of the transaction input containing the scriptSig verified. + * @param {number} flags - evaluation flags. See ScriptInterpreter.SCRIPT_* constants + * * Translated from bitcoind's VerifyScript */ ScriptInterpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags) { @@ -1054,6 +1064,9 @@ ScriptInterpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, if (_.isUndefined(nin)) { nin = 0; } + if (_.isUndefined(flags)) { + flags = 0; + } this.set({ script: scriptSig, tx: tx, diff --git a/test/script_interpreter.js b/test/script_interpreter.js index 91220b1cc..085602a19 100644 --- a/test/script_interpreter.js +++ b/test/script_interpreter.js @@ -202,7 +202,7 @@ describe('ScriptInterpreter', function() { var verified = interp.verify(scriptSig, scriptPubkey, spendtx, 0, flags); verified.should.equal(expected); }; - describe('bitcoind fixtures', function() { + describe('bitcoind script evaluation fixtures', function() { var testAllFixtures = function(set, expected) { var c = 0; set.forEach(function(vector) { @@ -221,13 +221,15 @@ describe('ScriptInterpreter', function() { testAllFixtures(script_valid, true); testAllFixtures(script_invalid, false); + }); + describe.only('bitcoind transaction evaluation fixtures', function() { var c = 0; tx_valid.forEach(function(vector) { if (vector.length === 1) { return; } c++; - it.skip('should pass tx_valid vector ' + c, function() { + it('should pass tx_valid vector ' + c, function() { var inputs = vector[0]; var txhex = vector[1]; var flags = getFlags(vector[2]); @@ -240,18 +242,18 @@ describe('ScriptInterpreter', function() { if (txoutnum === -1) { txoutnum = 0xffffffff; //bitcoind casts -1 to an unsigned int } - var txkey = txid + ':' + txoutnum; - map[txkey] = Script.fromBitcoindString(scriptPubKeyStr); + map[txid + ':' + txoutnum] = Script.fromBitcoindString(scriptPubKeyStr); }); var tx = Transaction(txhex); tx.inputs.forEach(function(txin, j) { + console.log('input ' + j); var scriptSig = txin.script; var txidhex = txin.prevTxId.toString('hex'); var txoutnum = txin.outputIndex; - var txkey = txidhex + ':' + txoutnum; - var scriptPubkey = map[txkey]; + var scriptPubkey = map[txidhex + ':' + txoutnum]; should.exist(scriptPubkey); + should.exist(scriptSig); var interp = ScriptInterpreter(); var verified = interp.verify(scriptSig, scriptPubkey, tx, j, flags); verified.should.equal(true); From b3be9461cfbf5c3e7400843295861b97e740dad1 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 16 Dec 2014 18:21:29 -0300 Subject: [PATCH 2/3] tx_valid tests passing! --- lib/script_interpreter.js | 4 +--- lib/transaction/sighash.js | 5 +++-- test/script_interpreter.js | 1 - 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/script_interpreter.js b/lib/script_interpreter.js index 88b1f0d0f..cbcc7e0a4 100644 --- a/lib/script_interpreter.js +++ b/lib/script_interpreter.js @@ -162,6 +162,7 @@ ScriptInterpreter.prototype.checkPubkeyEncoding = function(buf) { * bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104 */ ScriptInterpreter.prototype.evaluate = function() { + console.log(this.script.toString()); if (this.script.toBuffer().length > 10000) { this.errstr = 'SCRIPT_ERR_SCRIPT_SIZE'; return false; @@ -883,7 +884,6 @@ ScriptInterpreter.prototype.step = function() { subscript.findAndDelete(tmpScript); if (!this.checkSignatureEncoding(bufSig) || !this.checkPubkeyEncoding(bufPubkey)) { - // serror is set return false; } @@ -973,7 +973,6 @@ ScriptInterpreter.prototype.step = function() { var bufPubkey = this.stack[this.stack.length - ikey]; if (!this.checkSignatureEncoding(bufSig) || !this.checkPubkeyEncoding(bufPubkey)) { - // serror is set return false; } @@ -1141,7 +1140,6 @@ ScriptInterpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, // evaluate redeemScript if (!this.evaluate()) - // serror is set return false; if (stackCopy.length === 0) { diff --git a/lib/transaction/sighash.js b/lib/transaction/sighash.js index 0d2782f22..30ebf6f06 100644 --- a/lib/transaction/sighash.js +++ b/lib/transaction/sighash.js @@ -11,6 +11,7 @@ var BN = require('../crypto/bn'); var Hash = require('../crypto/hash'); var ECDSA = require('../crypto/ecdsa'); var $ = require('../util/preconditions'); +var _ = require('lodash'); var SIGHASH_SINGLE_BUG = '0000000000000000000000000000000000000000000000000000000000000001'; var BITS_64_ON = 'ffffffffffffffff'; @@ -122,8 +123,8 @@ function sign(transaction, privateKey, sighashType, inputIndex, subscript) { * @return {boolean} */ function verify(transaction, signature, publicKey, inputIndex, subscript) { - $.checkArgument(transaction); - $.checkArgument(signature && signature.nhashtype); + $.checkArgument(!_.isUndefined(transaction)); + $.checkArgument(!_.isUndefined(signature) && !_.isUndefined(signature.nhashtype)); var hashbuf = sighash(transaction, signature.nhashtype, inputIndex, subscript); return ECDSA.verify(hashbuf, signature, publicKey, 'little'); } diff --git a/test/script_interpreter.js b/test/script_interpreter.js index 085602a19..aa846877f 100644 --- a/test/script_interpreter.js +++ b/test/script_interpreter.js @@ -247,7 +247,6 @@ describe('ScriptInterpreter', function() { var tx = Transaction(txhex); tx.inputs.forEach(function(txin, j) { - console.log('input ' + j); var scriptSig = txin.script; var txidhex = txin.prevTxId.toString('hex'); var txoutnum = txin.outputIndex; From cd00b3ebe53ea7ab041ff6f0ad7992f39b062c4b Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 16 Dec 2014 18:45:03 -0300 Subject: [PATCH 3/3] tx_valid tests passing! --- lib/script_interpreter.js | 1 - test/script_interpreter.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/script_interpreter.js b/lib/script_interpreter.js index cbcc7e0a4..0c900e874 100644 --- a/lib/script_interpreter.js +++ b/lib/script_interpreter.js @@ -162,7 +162,6 @@ ScriptInterpreter.prototype.checkPubkeyEncoding = function(buf) { * bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104 */ ScriptInterpreter.prototype.evaluate = function() { - console.log(this.script.toString()); if (this.script.toBuffer().length > 10000) { this.errstr = 'SCRIPT_ERR_SCRIPT_SIZE'; return false; diff --git a/test/script_interpreter.js b/test/script_interpreter.js index aa846877f..88586dbbc 100644 --- a/test/script_interpreter.js +++ b/test/script_interpreter.js @@ -222,7 +222,7 @@ describe('ScriptInterpreter', function() { testAllFixtures(script_invalid, false); }); - describe.only('bitcoind transaction evaluation fixtures', function() { + describe('bitcoind transaction evaluation fixtures', function() { var c = 0; tx_valid.forEach(function(vector) { if (vector.length === 1) {