diff --git a/src/script.js b/src/script.js index d6d5c31..2004fa1 100644 --- a/src/script.js +++ b/src/script.js @@ -4,11 +4,16 @@ var typeforce = require('typeforce') var types = require('./types') var OPS = require('./opcodes') -var REVERSE_OPS = [] -for (var op in OPS) { - var code = OPS[op] - REVERSE_OPS[code] = op -} +var REVERSE_OPS = (function () { + var result = {} + for (var op in OPS) { + var code = OPS[op] + result[code] = op + } + return result +})() + +const OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1 function toASM (chunks) { if (types.Buffer(chunks)) { @@ -225,21 +230,21 @@ function isMultisigOutput (script) { if (chunks[chunks.length - 1] !== OPS.OP_CHECKMULTISIG) return false var mOp = chunks[0] - if (mOp < OPS.OP_1) return false - if (mOp > OPS.OP_16) return false - var nOp = chunks[chunks.length - 2] - if (nOp < OPS.OP_1) return false - if (nOp > OPS.OP_16) return false - var m = mOp - (OPS.OP_1 - 1) - var n = nOp - (OPS.OP_1 - 1) - if (n < m) return false + if (!types.Number(mOp)) return false + if (!types.Number(nOp)) return false - var pubKeys = chunks.slice(1, -2) - if (n !== pubKeys.length) return false + var m = mOp - OP_INT_BASE + var n = nOp - OP_INT_BASE - return pubKeys.every(isCanonicalPubKey) + // 0 < m <= n <= 16 + if (m <= 0) return false + if (m > n) return false + if (n > 16) return false + if (n !== chunks.length - 3) return false + + return chunks.slice(1, -2).every(isCanonicalPubKey) } function isNullDataOutput (script) { @@ -309,9 +314,9 @@ function multisigOutput (m, pubKeys) { if (n < m) throw new Error('Not enough pubKeys provided') return compile([].concat( - (OPS.OP_1 - 1) + m, + OP_INT_BASE + m, pubKeys, - (OPS.OP_1 - 1) + n, + OP_INT_BASE + n, OPS.OP_CHECKMULTISIG )) } @@ -349,8 +354,8 @@ function multisigInput (signatures, scriptPubKey) { var mOp = chunks[0] var nOp = chunks[chunks.length - 2] - var m = mOp - (OPS.OP_1 - 1) - var n = nOp - (OPS.OP_1 - 1) + var m = mOp - OP_INT_BASE + var n = nOp - OP_INT_BASE if (signatures.length < m) throw new Error('Not enough signatures provided') if (signatures.length > n) throw new Error('Too many signatures provided') diff --git a/test/fixtures/script.json b/test/fixtures/script.json index 81f905d..8abdcd1 100644 --- a/test/fixtures/script.json +++ b/test/fixtures/script.json @@ -245,6 +245,14 @@ "description": "n > len(pubKeys)", "scriptPubKey": "OP_1 024289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34 OP_2 OP_CHECKMULTISIG" }, + { + "description": "m is data", + "scriptPubKey": "ffff 024289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34 OP_1 OP_CHECKMULTISIG" + }, + { + "description": "n is data", + "scriptPubKey": "OP_1 024289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34 ffff OP_CHECKMULTISIG" + }, { "description": "non-canonical pubKey (bad length)", "scriptPubKey": "OP_1 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ffff OP_1 OP_CHECKMULTISIG"