From bc2048dfcaf3c3e36336a57114c1d87b4f8e612f Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 13 Oct 2014 18:36:46 +1100 Subject: [PATCH 01/11] scripts: remove out-of-date comments --- src/scripts.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/scripts.js b/src/scripts.js index 911fd1c..8ed78f8 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -2,16 +2,6 @@ var assert = require('assert') var enforceType = require('./types') var opcodes = require('./opcodes') -// FIXME: use ECPubKey, currently the circular dependency breaks everything. -// -// Solutions: -// * Remove ECPubKey.getAddress -// - Minimal change, but likely unpopular -// * Move all script related functionality out of Address -// - Means a lot of changes to Transaction/Wallet -// * Ignore it (existing solution) -// * Some form of hackery with commonjs -// var ecurve = require('ecurve') var curve = ecurve.getCurveByName('secp256k1') @@ -56,7 +46,6 @@ function isCanonicalPubKey(buffer) { if (!Buffer.isBuffer(buffer)) return false try { - // FIXME: boo ecurve.Point.decodeFrom(curve, buffer) } catch (e) { if (!(e.message.match(/Invalid sequence (length|tag)/))) throw e From 407d15869a9605aed525a86de80cde839665fbbf Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 13 Oct 2014 18:37:50 +1100 Subject: [PATCH 02/11] scripts: s/opcodes/ops --- src/scripts.js | 64 +++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/scripts.js b/src/scripts.js index 8ed78f8..fdec7b1 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -1,6 +1,6 @@ var assert = require('assert') var enforceType = require('./types') -var opcodes = require('./opcodes') +var ops = require('./opcodes') var ecurve = require('ecurve') var curve = ecurve.getCurveByName('secp256k1') @@ -78,12 +78,12 @@ function isPubKeyHashInput() { function isPubKeyHashOutput() { return this.chunks.length === 5 && - this.chunks[0] === opcodes.OP_DUP && - this.chunks[1] === opcodes.OP_HASH160 && + this.chunks[0] === ops.OP_DUP && + this.chunks[1] === ops.OP_HASH160 && Buffer.isBuffer(this.chunks[2]) && this.chunks[2].length === 20 && - this.chunks[3] === opcodes.OP_EQUALVERIFY && - this.chunks[4] === opcodes.OP_CHECKSIG + this.chunks[3] === ops.OP_EQUALVERIFY && + this.chunks[4] === ops.OP_CHECKSIG } function isPubKeyInput() { @@ -94,7 +94,7 @@ function isPubKeyInput() { function isPubKeyOutput() { return this.chunks.length === 2 && isCanonicalPubKey(this.chunks[0]) && - this.chunks[1] === opcodes.OP_CHECKSIG + this.chunks[1] === ops.OP_CHECKSIG } function isScriptHashInput() { @@ -111,33 +111,33 @@ function isScriptHashInput() { function isScriptHashOutput() { return this.chunks.length === 3 && - this.chunks[0] === opcodes.OP_HASH160 && + this.chunks[0] === ops.OP_HASH160 && Buffer.isBuffer(this.chunks[1]) && this.chunks[1].length === 20 && - this.chunks[2] === opcodes.OP_EQUAL + this.chunks[2] === ops.OP_EQUAL } function isMultisigInput() { - return this.chunks[0] === opcodes.OP_0 && + return this.chunks[0] === ops.OP_0 && this.chunks.slice(1).every(isCanonicalSignature) } function isMultisigOutput() { if (this.chunks < 4) return false - if (this.chunks[this.chunks.length - 1] !== opcodes.OP_CHECKMULTISIG) return false + if (this.chunks[this.chunks.length - 1] !== ops.OP_CHECKMULTISIG) return false var mOp = this.chunks[0] - if (mOp === opcodes.OP_0) return false - if (mOp < opcodes.OP_1) return false - if (mOp > opcodes.OP_16) return false + if (mOp === ops.OP_0) return false + if (mOp < ops.OP_1) return false + if (mOp > ops.OP_16) return false var nOp = this.chunks[this.chunks.length - 2] - if (nOp === opcodes.OP_0) return false - if (nOp < opcodes.OP_1) return false - if (nOp > opcodes.OP_16) return false + if (nOp === ops.OP_0) return false + if (nOp < ops.OP_1) return false + if (nOp > ops.OP_16) return false - var m = mOp - (opcodes.OP_1 - 1) - var n = nOp - (opcodes.OP_1 - 1) + var m = mOp - (ops.OP_1 - 1) + var n = nOp - (ops.OP_1 - 1) if (n < m) return false var pubKeys = this.chunks.slice(1, -2) @@ -147,7 +147,7 @@ function isMultisigOutput() { } function isNulldataOutput() { - return this.chunks[0] === opcodes.OP_RETURN + return this.chunks[0] === ops.OP_RETURN } // Standard Script Templates @@ -155,7 +155,7 @@ function isNulldataOutput() { function pubKeyOutput(pubKey) { return Script.fromChunks([ pubKey.toBuffer(), - opcodes.OP_CHECKSIG + ops.OP_CHECKSIG ]) } @@ -164,11 +164,11 @@ function pubKeyHashOutput(hash) { enforceType('Buffer', hash) return Script.fromChunks([ - opcodes.OP_DUP, - opcodes.OP_HASH160, + ops.OP_DUP, + ops.OP_HASH160, hash, - opcodes.OP_EQUALVERIFY, - opcodes.OP_CHECKSIG + ops.OP_EQUALVERIFY, + ops.OP_CHECKSIG ]) } @@ -177,9 +177,9 @@ function scriptHashOutput(hash) { enforceType('Buffer', hash) return Script.fromChunks([ - opcodes.OP_HASH160, + ops.OP_HASH160, hash, - opcodes.OP_EQUAL + ops.OP_EQUAL ]) } @@ -195,10 +195,10 @@ function multisigOutput(m, pubKeys) { var n = pubKeys.length return Script.fromChunks([].concat( - (opcodes.OP_1 - 1) + m, + (ops.OP_1 - 1) + m, pubKeyBuffers, - (opcodes.OP_1 - 1) + n, - opcodes.OP_CHECKMULTISIG + (ops.OP_1 - 1) + n, + ops.OP_CHECKMULTISIG )) } @@ -231,14 +231,14 @@ function multisigInput(signatures, scriptPubKey) { var mOp = scriptPubKey.chunks[0] var nOp = scriptPubKey.chunks[scriptPubKey.chunks.length - 2] - var m = mOp - (opcodes.OP_1 - 1) - var n = nOp - (opcodes.OP_1 - 1) + var m = mOp - (ops.OP_1 - 1) + var n = nOp - (ops.OP_1 - 1) assert(signatures.length >= m, 'Not enough signatures provided') assert(signatures.length <= n, 'Too many signatures provided') } - return Script.fromChunks([].concat(opcodes.OP_0, signatures)) + return Script.fromChunks([].concat(ops.OP_0, signatures)) } module.exports = { From b7febc1bd807c2fe25f99b509654b43d7294de15 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 13 Oct 2014 18:38:54 +1100 Subject: [PATCH 03/11] scripts: re-order classify functions --- src/scripts.js | 68 +++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/scripts.js b/src/scripts.js index fdec7b1..fafb91e 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -8,40 +8,6 @@ var curve = ecurve.getCurveByName('secp256k1') var ECSignature = require('./ecsignature') var Script = require('./script') -function classifyOutput(script) { - enforceType(Script, script) - - if (isPubKeyHashOutput.call(script)) { - return 'pubkeyhash' - } else if (isScriptHashOutput.call(script)) { - return 'scripthash' - } else if (isMultisigOutput.call(script)) { - return 'multisig' - } else if (isPubKeyOutput.call(script)) { - return 'pubkey' - } else if (isNulldataOutput.call(script)) { - return 'nulldata' - } else { - return 'nonstandard' - } -} - -function classifyInput(script) { - enforceType(Script, script) - - if (isPubKeyHashInput.call(script)) { - return 'pubkeyhash' - } else if (isScriptHashInput.call(script)) { - return 'scripthash' - } else if (isMultisigInput.call(script)) { - return 'multisig' - } else if (isPubKeyInput.call(script)) { - return 'pubkey' - } else { - return 'nonstandard' - } -} - function isCanonicalPubKey(buffer) { if (!Buffer.isBuffer(buffer)) return false @@ -150,6 +116,40 @@ function isNulldataOutput() { return this.chunks[0] === ops.OP_RETURN } +function classifyOutput(script) { + enforceType(Script, script) + + if (isPubKeyHashOutput.call(script)) { + return 'pubkeyhash' + } else if (isScriptHashOutput.call(script)) { + return 'scripthash' + } else if (isMultisigOutput.call(script)) { + return 'multisig' + } else if (isPubKeyOutput.call(script)) { + return 'pubkey' + } else if (isNulldataOutput.call(script)) { + return 'nulldata' + } else { + return 'nonstandard' + } +} + +function classifyInput(script) { + enforceType(Script, script) + + if (isPubKeyHashInput.call(script)) { + return 'pubkeyhash' + } else if (isScriptHashInput.call(script)) { + return 'scripthash' + } else if (isMultisigInput.call(script)) { + return 'multisig' + } else if (isPubKeyInput.call(script)) { + return 'pubkey' + } else { + return 'nonstandard' + } +} + // Standard Script Templates // {pubKey} OP_CHECKSIG function pubKeyOutput(pubKey) { From 1a20c0db39a98c85bb699975cad828e779f0271a Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 13 Oct 2014 18:46:50 +1100 Subject: [PATCH 04/11] scripts: avoid unnecessary this context --- src/scripts.js | 100 ++++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/src/scripts.js b/src/scripts.js index fafb91e..74942f2 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -36,68 +36,68 @@ function isCanonicalSignature(buffer) { return true } -function isPubKeyHashInput() { - return this.chunks.length === 2 && - isCanonicalSignature(this.chunks[0]) && - isCanonicalPubKey(this.chunks[1]) +function isPubKeyHashInput(script) { + return script.chunks.length === 2 && + isCanonicalSignature(script.chunks[0]) && + isCanonicalPubKey(script.chunks[1]) } -function isPubKeyHashOutput() { - return this.chunks.length === 5 && - this.chunks[0] === ops.OP_DUP && - this.chunks[1] === ops.OP_HASH160 && - Buffer.isBuffer(this.chunks[2]) && - this.chunks[2].length === 20 && - this.chunks[3] === ops.OP_EQUALVERIFY && - this.chunks[4] === ops.OP_CHECKSIG +function isPubKeyHashOutput(script) { + return script.chunks.length === 5 && + script.chunks[0] === ops.OP_DUP && + script.chunks[1] === ops.OP_HASH160 && + Buffer.isBuffer(script.chunks[2]) && + script.chunks[2].length === 20 && + script.chunks[3] === ops.OP_EQUALVERIFY && + script.chunks[4] === ops.OP_CHECKSIG } -function isPubKeyInput() { - return this.chunks.length === 1 && - isCanonicalSignature(this.chunks[0]) +function isPubKeyInput(script) { + return script.chunks.length === 1 && + isCanonicalSignature(script.chunks[0]) } -function isPubKeyOutput() { - return this.chunks.length === 2 && - isCanonicalPubKey(this.chunks[0]) && - this.chunks[1] === ops.OP_CHECKSIG +function isPubKeyOutput(script) { + return script.chunks.length === 2 && + isCanonicalPubKey(script.chunks[0]) && + script.chunks[1] === ops.OP_CHECKSIG } -function isScriptHashInput() { - if (this.chunks.length < 2) return false - var lastChunk = this.chunks[this.chunks.length - 1] +function isScriptHashInput(script) { + if (script.chunks.length < 2) return false + var lastChunk = script.chunks[script.chunks.length - 1] if (!Buffer.isBuffer(lastChunk)) return false - var scriptSig = Script.fromChunks(this.chunks.slice(0, -1)) + var scriptSig = Script.fromChunks(script.chunks.slice(0, -1)) var scriptPubKey = Script.fromBuffer(lastChunk) return classifyInput(scriptSig) === classifyOutput(scriptPubKey) } -function isScriptHashOutput() { - return this.chunks.length === 3 && - this.chunks[0] === ops.OP_HASH160 && - Buffer.isBuffer(this.chunks[1]) && - this.chunks[1].length === 20 && - this.chunks[2] === ops.OP_EQUAL +function isScriptHashOutput(script) { + return script.chunks.length === 3 && + script.chunks[0] === ops.OP_HASH160 && + Buffer.isBuffer(script.chunks[1]) && + script.chunks[1].length === 20 && + script.chunks[2] === ops.OP_EQUAL } -function isMultisigInput() { - return this.chunks[0] === ops.OP_0 && - this.chunks.slice(1).every(isCanonicalSignature) +function isMultisigInput(script) { + return script.chunks[0] === ops.OP_0 && + script.chunks.slice(1).every(isCanonicalSignature) } -function isMultisigOutput() { - if (this.chunks < 4) return false - if (this.chunks[this.chunks.length - 1] !== ops.OP_CHECKMULTISIG) return false +function isMultisigOutput(script) { + if (script.chunks < 4) return false + if (script.chunks[script.chunks.length - 1] !== ops.OP_CHECKMULTISIG) return false - var mOp = this.chunks[0] + var mOp = script.chunks[0] if (mOp === ops.OP_0) return false if (mOp < ops.OP_1) return false if (mOp > ops.OP_16) return false - var nOp = this.chunks[this.chunks.length - 2] + var nOp = script.chunks[script.chunks.length - 2] if (nOp === ops.OP_0) return false if (nOp < ops.OP_1) return false if (nOp > ops.OP_16) return false @@ -106,28 +106,28 @@ function isMultisigOutput() { var n = nOp - (ops.OP_1 - 1) if (n < m) return false - var pubKeys = this.chunks.slice(1, -2) + var pubKeys = script.chunks.slice(1, -2) if (n < pubKeys.length) return false return pubKeys.every(isCanonicalPubKey) } -function isNulldataOutput() { - return this.chunks[0] === ops.OP_RETURN +function isNulldataOutput(script) { + return script.chunks[0] === ops.OP_RETURN } function classifyOutput(script) { enforceType(Script, script) - if (isPubKeyHashOutput.call(script)) { + if (isPubKeyHashOutput(script)) { return 'pubkeyhash' - } else if (isScriptHashOutput.call(script)) { + } else if (isScriptHashOutput(script)) { return 'scripthash' - } else if (isMultisigOutput.call(script)) { + } else if (isMultisigOutput(script)) { return 'multisig' - } else if (isPubKeyOutput.call(script)) { + } else if (isPubKeyOutput(script)) { return 'pubkey' - } else if (isNulldataOutput.call(script)) { + } else if (isNulldataOutput(script)) { return 'nulldata' } else { return 'nonstandard' @@ -137,13 +137,13 @@ function classifyOutput(script) { function classifyInput(script) { enforceType(Script, script) - if (isPubKeyHashInput.call(script)) { + if (isPubKeyHashInput(script)) { return 'pubkeyhash' - } else if (isScriptHashInput.call(script)) { + } else if (isScriptHashInput(script)) { return 'scripthash' - } else if (isMultisigInput.call(script)) { + } else if (isMultisigInput(script)) { return 'multisig' - } else if (isPubKeyInput.call(script)) { + } else if (isPubKeyInput(script)) { return 'pubkey' } else { return 'nonstandard' @@ -227,7 +227,7 @@ function scriptHashInput(scriptSig, scriptPubKey) { // OP_0 [signatures ...] function multisigInput(signatures, scriptPubKey) { if (scriptPubKey) { - assert(isMultisigOutput.call(scriptPubKey)) + assert(isMultisigOutput(scriptPubKey)) var mOp = scriptPubKey.chunks[0] var nOp = scriptPubKey.chunks[scriptPubKey.chunks.length - 2] From b65e70b29c159949a3f98260c2cef57562ab8acb Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 13 Oct 2014 18:53:07 +1100 Subject: [PATCH 05/11] scripts: remove explict else branch --- src/scripts.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/scripts.js b/src/scripts.js index 74942f2..7d77b16 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -129,9 +129,9 @@ function classifyOutput(script) { return 'pubkey' } else if (isNulldataOutput(script)) { return 'nulldata' - } else { - return 'nonstandard' } + + return 'nonstandard' } function classifyInput(script) { @@ -145,9 +145,9 @@ function classifyInput(script) { return 'multisig' } else if (isPubKeyInput(script)) { return 'pubkey' - } else { - return 'nonstandard' } + + return 'nonstandard' } // Standard Script Templates From 27a99436df06003f3c6a6bae1b98fc3386cd1830 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 13 Oct 2014 19:34:26 +1100 Subject: [PATCH 06/11] tests: cover all multisigOutput branchs --- test/fixtures/scripts.json | 44 +++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/test/fixtures/scripts.json b/test/fixtures/scripts.json index e264a4a..aa5d29e 100644 --- a/test/fixtures/scripts.json +++ b/test/fixtures/scripts.json @@ -53,25 +53,45 @@ "invalid": { "classify": [ { - "description": "multisig output : m > n", - "scriptPubKey": "OP_2 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_1 OP_CHECKMULTISIG" + "description": "multisig output : OP_CHECKMULTISIG not found", + "scriptPubKey": "OP_0 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_2 OP_HASH160" + }, + { + "description": "multisig output : less than 4 chunks", + "scriptPubKey": "OP_0 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 OP_HASH160" + }, + { + "description": "multisig output : m === 0", + "scriptPubKey": "OP_0 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_2 OP_CHECKMULTISIG" + }, + { + "description": "multisig output : m < OP_1", + "scriptPubKey": "OP_1NEGATE 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_2 OP_CHECKMULTISIG" + }, + { + "description": "multisig output : m > OP_16", + "scriptPubKey": "OP_NOP 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_2 OP_CHECKMULTISIG" }, { "description": "multisig output : n === 0", - "scriptPubKey": "OP_0 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_0 OP_CHECKMULTISIG" + "scriptPubKey": "OP_1 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_0 OP_CHECKMULTISIG" }, { - "description": "multisig output : not (m <= len(pubKeys) <= n)", + "description": "multisig output : n < OP_1", + "scriptPubKey": "OP_1 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_1NEGATE OP_CHECKMULTISIG" + }, + { + "description": "multisig output : n > OP_16", + "scriptPubKey": "OP_1 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_NOP OP_CHECKMULTISIG" + }, + { + "description": "multisig output : n < m", + "scriptPubKey": "OP_2 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_1 OP_CHECKMULTISIG" + }, + { + "description": "multisig output : n < len(pubKeys)", "scriptPubKey": "OP_2 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 024289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34 OP_2 OP_CHECKMULTISIG" }, - { - "description": "multisig output : m not a small int", - "scriptPubKey": "OP_HASH160 024289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34 OP_1 OP_CHECKMULTISIG" - }, - { - "description": "multisig output : n not a small int", - "scriptPubKey": "OP_1 024289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34 OP_HASH160 OP_CHECKMULTISIG" - }, { "description": "multisig output : non-canonical pubKey (bad length)", "scriptPubKey": "OP_1 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ffff OP_1 OP_CHECKMULTISIG" From ddb24ee6153f4a0d77d2e44f42222d6175f4c2ac Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 13 Oct 2014 19:46:20 +1100 Subject: [PATCH 07/11] scripts: check chunks length properly --- src/scripts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripts.js b/src/scripts.js index 7d77b16..b7c4dd5 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -89,7 +89,7 @@ function isMultisigInput(script) { } function isMultisigOutput(script) { - if (script.chunks < 4) return false + if (script.chunks.length < 4) return false if (script.chunks[script.chunks.length - 1] !== ops.OP_CHECKMULTISIG) return false var mOp = script.chunks[0] From f3138dcb6859b880e7e025586b96085d11cb2c30 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 13 Oct 2014 19:51:13 +1100 Subject: [PATCH 08/11] tests: test non-standard pathway for classifyInput --- test/fixtures/scripts.json | 4 ++++ test/scripts.js | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/test/fixtures/scripts.json b/test/fixtures/scripts.json index aa5d29e..cd69470 100644 --- a/test/fixtures/scripts.json +++ b/test/fixtures/scripts.json @@ -95,6 +95,10 @@ { "description": "multisig output : non-canonical pubKey (bad length)", "scriptPubKey": "OP_1 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ffff OP_1 OP_CHECKMULTISIG" + }, + { + "description": "pubKeyHash input : extraneous data", + "scriptSig": "304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1 ffffffff" } ], "multisig": [ diff --git a/test/scripts.js b/test/scripts.js index b50ec3a..9709ec9 100644 --- a/test/scripts.js +++ b/test/scripts.js @@ -19,6 +19,17 @@ describe('Scripts', function() { assert.equal(type, f.type) }) }) + + fixtures.invalid.classify.forEach(function(f) { + if (!f.scriptSig) return + + it('returns nonstandard for ' + f.description, function() { + var script = Script.fromASM(f.scriptSig) + var type = scripts.classifyInput(script) + + assert.equal(type, 'nonstandard') + }) + }) }) describe('classifyOutput', function() { @@ -34,6 +45,8 @@ describe('Scripts', function() { }) fixtures.invalid.classify.forEach(function(f) { + if (!f.scriptPubKey) return + it('returns nonstandard for ' + f.description, function() { var script = Script.fromASM(f.scriptPubKey) var type = scripts.classifyOutput(script) From f9a5c47d95debfa2159d9c1db105493f3e66e605 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 13 Oct 2014 19:59:21 +1100 Subject: [PATCH 09/11] tests: add OP_RETURN scripts fixture --- test/fixtures/scripts.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/fixtures/scripts.json b/test/fixtures/scripts.json index cd69470..238c85c 100644 --- a/test/fixtures/scripts.json +++ b/test/fixtures/scripts.json @@ -48,6 +48,10 @@ "redeemScriptSig": "OP_0 304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501", "scriptSig": "OP_0 304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501 522102359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1210395a9d84d47d524548f79f435758c01faec5da2b7e551d3b8c995b7e06326ae4a52ae", "scriptPubKey": "OP_HASH160 722ff0bc2c3f47b35c20df646c395594da24e90e OP_EQUAL" + }, + { + "type": "nulldata", + "scriptPubKey": "OP_RETURN ffffffffffffffffffffffffffffffffffffffff" } ], "invalid": { From f6e340f64ca1c97e0ca1ed0c1e1c010316828179 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 13 Oct 2014 20:04:42 +1100 Subject: [PATCH 10/11] tests: add scriptHash redeemScript non-data fixture --- test/fixtures/scripts.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/fixtures/scripts.json b/test/fixtures/scripts.json index 238c85c..65d63cc 100644 --- a/test/fixtures/scripts.json +++ b/test/fixtures/scripts.json @@ -103,6 +103,10 @@ { "description": "pubKeyHash input : extraneous data", "scriptSig": "304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1 ffffffff" + }, + { + "description": "scriptHash input : redeemScript not data", + "scriptSig": "OP_0 304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501 OP_RESERVED" } ], "multisig": [ From ab57630f2022c9b0d2b2145d7024223b50ec4f9e Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 13 Oct 2014 20:30:23 +1100 Subject: [PATCH 11/11] tests: add non-canonical signature test --- test/fixtures/scripts.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/fixtures/scripts.json b/test/fixtures/scripts.json index 65d63cc..4afdc97 100644 --- a/test/fixtures/scripts.json +++ b/test/fixtures/scripts.json @@ -107,6 +107,10 @@ { "description": "scriptHash input : redeemScript not data", "scriptSig": "OP_0 304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501 OP_RESERVED" + }, + { + "description": "pubKey input : non-canonical signature", + "scriptSig": "304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf7593ffffffffffffffff" } ], "multisig": [