From b0a3a0e853d2cf1e7a3f369e6a301c55ec1cce6c Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 14 Dec 2015 13:55:59 -0800 Subject: [PATCH] utils. minor fixes. wallet functions. --- lib/bcoin/hd.js | 10 +++--- lib/bcoin/script.js | 6 ++-- lib/bcoin/tx.js | 4 +-- lib/bcoin/utils.js | 20 +++++++++++ lib/bcoin/wallet.js | 81 ++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 106 insertions(+), 15 deletions(-) diff --git a/lib/bcoin/hd.js b/lib/bcoin/hd.js index 6036419d..70f51c50 100644 --- a/lib/bcoin/hd.js +++ b/lib/bcoin/hd.js @@ -136,7 +136,7 @@ function HDPriv(options) { if (typeof options === 'string' && options.indexOf('xprv') === 0) options = { xkey: options }; - if (options.passphrase) + if (options.passphrase !== undefined) options.seed = new HDSeed({ passphrase: options.passphrase }); if (options.seed) { @@ -400,7 +400,7 @@ HDPriv.prototype.deriveString = function(path) { function HDPub(options) { if (!(this instanceof HDPub)) - return new HDPriv(options); + return new HDPub(options); var data; @@ -576,9 +576,9 @@ HDPub.prototype.deriveString = function(path) { return this.pair.verify.apply(this.pair, arguments); }; - HD.prototype.inspect = function inspect() { - return this.pair.inspect.apply(this.pair, arguments); - }; + // HD.prototype.inspect = function inspect() { + // return this.pair.inspect.apply(this.pair, arguments); + // }; HD.prototype.__defineGetter__('pub', function() { return this.pair.pub; diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index fd9b4501..c6e6672f 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -636,12 +636,12 @@ script.execute = function execute(s, stack, tx, index) { if (!constants.rhashType[type & 0x7f]) return false; - var subscript = s.slice(lastSep + 1); - var hash = tx.subscriptHash(index, subscript, type); - if (!script.isValidSig(sig)) return false; + var subscript = s.slice(lastSep + 1); + var hash = tx.subscriptHash(index, subscript, type); + // Strict order: var res = script.verify(hash, sig.slice(0, -1), keys.pop()); if (res) diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index 731d11d7..de0edc6d 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -447,8 +447,8 @@ TX.prototype.verify = function verify(index, force) { if (bcoin.script.isScripthash(prev)) { // p2sh transactions cannot have anything // other than pushdata ops in the scriptSig - var push = !input.script.slice(1).every(Array.isArray); - if (push) + var push = input.script.slice(1).every(Array.isArray); + if (!push) return false; } diff --git a/lib/bcoin/utils.js b/lib/bcoin/utils.js index 611674b3..9e41cc45 100644 --- a/lib/bcoin/utils.js +++ b/lib/bcoin/utils.js @@ -268,6 +268,26 @@ utils.writeAscii = function writeAscii(dst, str, off) { return i; }; +utils.readAscii = function readAscii(arr, off, len) { + var str = ''; + for (var i = off; i < off + len; i++) { + var c = String.fromCharCode(arr[i] & 0xff); + str += c; + } + return str; +}; + +utils.ascii2array = function ascii2array(str) { + var dst = []; + utils.writeAscii(dst, str, 0); + return dst; +}; + +// stringify +utils.array2ascii = function array2ascii(arr) { + return utils.readAscii(arr, 0, arr.length); +}; + utils.copy = function copy(src, dst, off, force) { var len = src.length; if (!force) diff --git a/lib/bcoin/wallet.js b/lib/bcoin/wallet.js index 8aaca748..f253ef76 100644 --- a/lib/bcoin/wallet.js +++ b/lib/bcoin/wallet.js @@ -40,7 +40,9 @@ function Wallet(options, passphrase) { this.hd = options.pub; this.key = this.hd; } else if (options.hd) { - this.hd = bcoin.hd.priv(options); + this.hd = typeof options.hd === 'object' + ? bcoin.hd.priv(options.hd) + : bcoin.hd.priv(); this.key = this.hd; } else if (options.key) { if ((options.key instanceof bcoin.hd.priv) @@ -132,6 +134,9 @@ Wallet.prototype.multisig = function multisig(options) { this.addKey(pub); + if (network.prefixes[this.type] == null) + throw new Error('Unknown prefix: ' + this.type); + options.keys.forEach(function(key) { this.addKey(key); }, this); @@ -271,7 +276,7 @@ Wallet.prototype.getPublicKeys = function() { }; Wallet.prototype.getFullHash = function getFullHash() { - return utils.ripesha(this.getFullPublicKey()); + return Wallet.key2hash(this.getFullPublicKey()); }; Wallet.prototype.getFullAddress = function getFullAddress() { @@ -279,7 +284,7 @@ Wallet.prototype.getFullAddress = function getFullAddress() { }; Wallet.prototype.getOwnHash = function getOwnHash() { - return utils.ripesha(this.getOwnPublicKey()); + return Wallet.key2hash(this.getOwnPublicKey()); }; Wallet.prototype.getOwnAddress = function getOwnAddress() { @@ -287,13 +292,19 @@ Wallet.prototype.getOwnAddress = function getOwnAddress() { }; Wallet.prototype.getHash = function getHash() { - return utils.ripesha(this.getFullPublicKey()); + return Wallet.key2hash(this.getFullPublicKey()); }; Wallet.prototype.getAddress = function getAddress() { return Wallet.hash2addr(this.getFullHash(), this.type); }; +Wallet.key2hash = function key2hash(key) { + if (typeof key === 'string') + key = utils.toArray(key, 'hex'); + return utils.ripesha(key); +}; + Wallet.hash2addr = function hash2addr(hash, prefix) { hash = utils.toArray(hash, 'hex'); @@ -307,7 +318,7 @@ Wallet.hash2addr = function hash2addr(hash, prefix) { Wallet.__defineGetter__('prefixes', function() { if (Wallet._prefixes) return Wallet._prefixes; Wallet._prefixes = ['pubkey', 'script'].reduce(function(out, prefix) { - var ch = Wallet.hash2addr(bcoin.utils.ripesha([]), prefix)[0]; + var ch = Wallet.hash2addr(Wallet.key2hash([]), prefix)[0]; out[ch] = prefix; return out; }, {}); @@ -408,6 +419,66 @@ Wallet.prototype.ownInput = function ownInput(tx, index) { return inputs; }; +Wallet.prototype.scriptOutputs = function scriptOutputs(tx, options, outputs) { + options = options || {}; + + if (this.n > 1) { + options.keys = this.keys; + options.m = this.m || 1; + options.n = this.n || 1; + } + + outputs = outputs || tx.outputs; + + outputs.forEach(function(output) { + tx.scriptOutput(output, options); + }); + + return outputs.length; +}; + +Wallet.prototype.fillUnspent = function fillUnspent(tx, unspent, change) { + return tx.fillUnspent(tx, unspent, change); +}; + +Wallet.prototype.scriptInputs = function scriptInputs(tx, inputs) { + var pub = this.getFullPublicKey(); + + inputs = inputs || tx.inputs; + + inputs = inputs.filter(function(input) { + // Filter inputs that this wallet own + if (!input.out.tx || !this.ownOutput(input.out.tx)) + return false; + + tx.scriptInput(input, pub); + + return true; + }, this); + + return inputs.length; +}; + +Wallet.prototype.signInputs = function(tx, type, inputs) { + if (!type) + type = 'all'; + + var key = this.key; + + inputs = inputs || tx.inputs; + + inputs = inputs.filter(function(input) { + if (!input.out.tx || !this.ownOutput(input.out.tx)) + return false; + + tx.signInput(input, key, type); + + return true; + }, this); + + return inputs.length; +}; + Wallet.prototype.sign = function sign(tx, type, inputs) { if (!type) type = 'all';