From 5e89aedf0bb04b446834b15bf491dff6c62e487e Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Thu, 17 Dec 2015 15:45:40 -0800 Subject: [PATCH] improve input testing. --- lib/bcoin/script.js | 87 ++++++++++++++++++++++++++++++++++++--------- lib/bcoin/wallet.js | 12 ++++--- 2 files changed, 78 insertions(+), 21 deletions(-) diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index 4604ecfc..3f8649b6 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -800,7 +800,7 @@ script.lockTime = function lockTime(s) { && new bn(s[0]); }; -script.isPubkey = function isPubkey(s, hash) { +script.isPubkey = function isPubkey(s, key) { if (script.lockTime(s)) s = s.slice(3); @@ -811,8 +811,8 @@ script.isPubkey = function isPubkey(s, hash) { if (!match) return false; - if (hash) - return utils.isEqual(s[0], hash); + if (key) + return utils.isEqual(s[0], key); else return s[0]; }; @@ -838,13 +838,16 @@ script.isPubkeyhash = function isPubkeyhash(s, hash) { return s[2]; }; -script.isMultisig = function isMultisig(s, key) { +script.isMultisig = function isMultisig(s, pubs) { if (script.lockTime(s)) s = s.slice(3); if (s.length < 4) return false; + if (pubs && !Array.isArray(pubs[0])) + pubs = [pubs]; + var m = s[0]; if (typeof m === 'number' && m >= 1 && m <= 15) m = [m]; @@ -872,11 +875,13 @@ script.isMultisig = function isMultisig(s, key) { if (!isArray) return false; - if (!key) + if (!pubs) return keys; return m === keys.filter(function(k) { - return utils.isEqual(k, key); + return pubs.some(function(pub) { + return utils.isEqual(k, pub); + }); }).length; }; @@ -917,55 +922,105 @@ script.colored = function colored(s) { return s[1]; }; -script.isPubkeyInput = function isPubkeyInput(s) { +script.standardInput = function standardInput(s) { + return (script.isPubkeyInput(s) && 'pubkey') + || (script.isPubkeyhashInput(s) && 'pubkeyhash') + || (script.isScripthashInput(s) && 'scripthash') + || (script.isMultisigInput(s) && 'multisig') + || 'nonstandard'; +}; + +script.isPubkeyInput = function isPubkeyInput(s, key) { + if (key) + throw new Error('Cannot check for pubkey in p2pk input.'); + if (s.length !== 1 || !Array.isArray(s[0])) return false; return 9 <= s[0].length && s[0].length <= 73; }; -script.isPubkeyhashInput = function isPubkeyhashInput(s) { +script.isPubkeyhashInput = function isPubkeyhashInput(s, key) { if (s.length !== 2 || !Array.isArray(s[0]) || !Array.isArray(s[1])) return false; - return 9 <= s[0].length && s[0].length <= 73 && - 33 <= s[1].length && s[1].length <= 65; + var ret = 9 <= s[0].length && s[0].length <= 73 && + 33 <= s[1].length && s[1].length <= 65; + + if (!ret) + return false; + + if (key) + return utils.isEqual(s[1], key); + + return true; }; -script.isMultisigInput = function isMultisigInput(s) { +script.isMultisigInput = function isMultisigInput(s, pubs) { if (s.length < 3) return false; if (!Array.isArray(s[0]) || s[0].length !== 0) return false; + if (pubs && !Array.isArray(pubs[0])) + pubs = [pubs]; + + var total = 0; for (var i = 1; i < s.length; i++) { - var ret = 9 <= s[i].length && s[i].length <= 73; + var ret = Array.isArray(s[i]) && 33 <= s[i].length && s[i].length <= 65; if (!ret) return false; + if (pubs) { + var has = pubs.some(function(pub) { + return utils.isEqual(s[i], pub); + }); + if (has) + total++; + } } - return true; + if (!pubs) + return true; + + return total; }; -script.isScripthashInput = function isScripthashInput(s) { +script.isScripthashInput = function isScripthashInput(s, pubs) { if (s.length < 4) return false; if (!Array.isArray(s[0]) || s[0].length !== 0) return false; + if (pubs && !Array.isArray(pubs[0])) + pubs = [pubs]; + + var total = 0; for (var i = 1; i < s.length - 1; i++) { - var ret = Array.isArray(s[i]) && 9 <= s[i].length && s[i].length <= 73; + var ret = Array.isArray(s[i]) && 33 <= s[i].length && s[i].length <= 65; if (!ret) return false; + if (pubs) { + var has = pubs.some(function(pub) { + return utils.isEqual(s[i], pub); + }); + if (has) + total++; + } } var r = Array.isArray(s[s.length - 1]) && s[s.length - 1]; if (r[r.length - 1] !== constants.opcodes.checkmultisig) return false; - return true; + if (!pubs) + return true; + + // var m = r[0]; + // return m === total; + + return total; }; // https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki diff --git a/lib/bcoin/wallet.js b/lib/bcoin/wallet.js index 0d462073..515cc4bf 100644 --- a/lib/bcoin/wallet.js +++ b/lib/bcoin/wallet.js @@ -357,7 +357,7 @@ Wallet.validateAddress = Wallet.prototype.validateAddress; Wallet.prototype.ownOutput = function ownOutput(tx, index) { var scriptHash = this.getFullHash(); var hash = this.getOwnHash(); - var key = this.getOwnPublicKey(); + var keys = this.getPublicKeys(); var outputs = tx.outputs.filter(function(output, i) { if (index !== undefined && index !== i) @@ -371,7 +371,7 @@ Wallet.prototype.ownOutput = function ownOutput(tx, index) { if (bcoin.script.isPubkeyhash(s, hash)) return true; - if (bcoin.script.isMultisig(s, key)) + if (bcoin.script.isMultisig(s, keys)) return true; if (bcoin.script.isScripthash(s, scriptHash)) @@ -379,6 +379,7 @@ Wallet.prototype.ownOutput = function ownOutput(tx, index) { return false; }, this); + if (outputs.length === 0) return false; @@ -389,13 +390,13 @@ Wallet.prototype.ownInput = function ownInput(tx, index) { var scriptHash = this.getFullHash(); var hash = this.getOwnHash(); var key = this.getOwnPublicKey(); + var keys = this.getPublicKeys(); var inputs = tx.inputs.filter(function(input, i) { if (index !== undefined && index !== i) return false; - if (bcoin.script.isPubkeyhashInput(input.script) && - utils.isEqual(input.script[1], key)) + if (bcoin.script.isPubkeyhashInput(input.script, key)) return true; if (!input.out.tx) @@ -405,7 +406,7 @@ Wallet.prototype.ownInput = function ownInput(tx, index) { if (bcoin.script.isPubkeyhash(s, hash)) return true; - if (bcoin.script.isMultisig(s, key)) + if (bcoin.script.isMultisig(s, keys)) return true; if (bcoin.script.isScripthash(s, scriptHash)) @@ -413,6 +414,7 @@ Wallet.prototype.ownInput = function ownInput(tx, index) { return false; }, this); + if (inputs.length === 0) return false;