diff --git a/lib/script_interpreter.js b/lib/script_interpreter.js index 952fc9b41..0c900e874 100644 --- a/lib/script_interpreter.js +++ b/lib/script_interpreter.js @@ -883,7 +883,6 @@ ScriptInterpreter.prototype.step = function() { subscript.findAndDelete(tmpScript); if (!this.checkSignatureEncoding(bufSig) || !this.checkPubkeyEncoding(bufPubkey)) { - // serror is set return false; } @@ -973,7 +972,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; } @@ -1045,6 +1043,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 +1062,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, @@ -1128,7 +1139,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 91220b1cc..88586dbbc 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('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,8 +242,7 @@ 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); @@ -249,9 +250,9 @@ describe('ScriptInterpreter', function() { 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);