From d3e4dfaf5c988060180a23287d136cbadfaf2064 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Tue, 22 Dec 2015 06:21:01 -0800 Subject: [PATCH] fix some getters. move getInputData and getOutputData. wallet.toAddress. --- lib/bcoin/block.js | 10 +- lib/bcoin/chain.js | 4 +- lib/bcoin/input.js | 98 ++++++++++++++++++- lib/bcoin/output.js | 116 ++++++++++++++++++++++- lib/bcoin/tx.js | 225 ++------------------------------------------ lib/bcoin/wallet.js | 31 ++++++ 6 files changed, 253 insertions(+), 231 deletions(-) diff --git a/lib/bcoin/block.js b/lib/bcoin/block.js index 0436a76a..348be531 100644 --- a/lib/bcoin/block.js +++ b/lib/bcoin/block.js @@ -31,6 +31,7 @@ function Block(data, subtype) { return utils.toHex(hash); }); this.flags = data.flags || []; + this.txs = data.txs || []; this._raw = data._raw || null; this._size = data._size || 0; @@ -45,7 +46,6 @@ function Block(data, subtype) { this.invalid = false; if (this.subtype === 'block') { - this.txs = data.txs || []; this.txs = this.txs.map(function(tx) { tx.network = self.network; tx.relayedBy = self.relayedBy; @@ -54,11 +54,7 @@ function Block(data, subtype) { tx.ts = tx.ts || self.ts; return tx; }); - this.tx = this.txs.map(function(tx) { - return tx.hash('hex'); - }); this.invalid = !this._checkBlock(); - this.hashes = []; } this._hash = null; @@ -75,7 +71,7 @@ Block.prototype.hash = function hash(enc) { }; Block.prototype.abbr = function abbr() { - if (this.network) + if (this.network && this._raw) return this._raw.slice(); var res = new Array(80); @@ -288,7 +284,7 @@ Block.prototype.getNextBlock = function getNextBlock(chain) { return this._nextBlock = next; }; -Block.prototype.__defineGetter__('rblock', function() { +Block.prototype.__defineGetter__('rhash', function() { return utils.revHex(this.hash('hex')); }); diff --git a/lib/bcoin/chain.js b/lib/bcoin/chain.js index 0958ac07..f626d3b1 100644 --- a/lib/bcoin/chain.js +++ b/lib/bcoin/chain.js @@ -597,7 +597,7 @@ Chain.prototype.getOrphanRoot = function getOrphanRoot(hash) { }; Chain.prototype.getHeight = function getHeight(hash) { - var chain, i, height; + var i, height; if (Array.isArray(hash)) hash = utils.toHex(hash); @@ -616,7 +616,7 @@ Chain.prototype.getHeight = function getHeight(hash) { Chain.prototype.getNextBlock = function getNextBlock(hash) { var height, nextHeight, i; - height = this.getHeight(chain); + height = this.getHeight(hash); nextHeight = this.index.heights[i + 1]; i = this.index.heights.indexOf(nextHeight); diff --git a/lib/bcoin/input.js b/lib/bcoin/input.js index 1eff13f7..32ed5e24 100644 --- a/lib/bcoin/input.js +++ b/lib/bcoin/input.js @@ -51,7 +51,7 @@ function Input(options) { } Input.prototype.__defineGetter__('data', function() { - return bcoin.tx.getInputData(this); + return Input.getData(this); }); Input.prototype.__defineGetter__('addr', function() { @@ -76,7 +76,7 @@ Input.prototype.__defineGetter__('output', function() { Input.prototype.__defineGetter__('value', function() { if (!this.output) - return; + return new bn(0); return this.output.value; }); @@ -84,6 +84,100 @@ Input.prototype.__defineGetter__('tx', function() { return this.out.tx; }); +Input.getData = function getData(input) { + if (!input || !input.script) + return; + + var s = input.script; + var sig, pub, hash, addr, redeem, data, output; + + if (!input.out) { + return { + type: 'unknown', + addr: '[unknown]', + hash: '[unknown]', + value: new bn(0), + script: s, + seq: input.seq, + none: true + }; + } + + if (+input.out.hash === 0) { + return { + type: 'coinbase', + addr: '[coinbase]', + hash: '[coinbase]', + value: new bn(0), + script: s, + seq: input.seq, + none: true + }; + } + + if (input.out.tx) { + output = input.out.tx.outputs[input.out.index]; + return bcoin.output.getData(output); + } + + if (bcoin.script.isPubkeyhashInput(s)) { + sig = utils.toHex(s[0]); + pub = s[1]; + hash = utils.ripesha(pub); + addr = bcoin.wallet.hash2addr(hash); + return { + type: 'pubkeyhash', + sig: sig, + pub: pub, + hash: hash, + addr: addr, + value: new bn(0), + script: s, + seq: input.seq + }; + } + + if (bcoin.script.isScripthashInput(s)) { + pub = s[s.length - 1]; + hash = utils.ripesha(pub); + addr = bcoin.wallet.hash2addr(hash, 'scripthash'); + redeem = bcoin.script.decode(pub); + data = bcoin.output.getData({ + script: redeem, + value: new bn(0) + }); + data.type = 'scripthash'; + data.pub = pub; + data.hash = hash; + data.addr = addr; + data.scripthash = { + redeem: redeem, + pub: pub, + hash: hash, + addr: addr, + m: data.multisig.m, + n: data.multisig.n, + keys: data.multisig.keys, + hashes: data.multisig.hashes, + addrs: data.multisig.addrs, + script: redeem + }; + data.script = s; + data.seq = input.seq; + return data; + } + + return { + type: 'unknown', + addr: '[unknown]', + hash: '[unknown]', + value: new bn(0), + script: s, + seq: input.seq, + none: true + }; +}; + /** * Expose */ diff --git a/lib/bcoin/output.js b/lib/bcoin/output.js index 3a75ee03..9a9ed4f8 100644 --- a/lib/bcoin/output.js +++ b/lib/bcoin/output.js @@ -35,7 +35,7 @@ function Output(options) { } Output.prototype.__defineGetter__('data', function() { - return bcoin.tx.getOutputData(this); + return Output.getData(this); }); Output.prototype.__defineGetter__('addr', function() { @@ -53,6 +53,120 @@ Output.prototype.__defineGetter__('lock', function() { return lock.toNumber(); }); +Output.getData = function getData(output) { + if (!output || !output.script) return; + + var s = output.script; + var lock = bcoin.script.lockTime(s); + var pub, hash, addr, pubs, ret; + + if (bcoin.script.isPubkey(s)) { + pub = s[0]; + hash = utils.ripesha(pub); + addr = bcoin.wallet.hash2addr(hash); + return { + type: 'pubkey', + sig: null, + pub: pub, + hash: hash, + addr: addr, + value: output.value, + script: s, + lock: lock + }; + } + + if (bcoin.script.isPubkeyhash(s)) { + hash = s[2]; + addr = bcoin.wallet.hash2addr(hash); + return { + type: 'pubkeyhash', + sig: null, + pub: null, + hash: hash, + addr: addr, + value: output.value, + script: s, + lock: lock + }; + } + + pubs = bcoin.script.isMultisig(s); + if (pubs) { + hash = utils.ripesha(pubs[0]); + addr = bcoin.wallet.hash2addr(hash); + return { + type: 'multisig', + sig: null, + pub: pubs[0], + hash: hash, + addr: addr, + keys: pubs, + multisig: { + m: new bn(s[0]).toNumber(), + n: new bn(s[s.length - 2]).toNumber(), + keys: pubs, + hashes: pubs.map(function(key) { + return utils.ripesha(key); + }), + addrs: pubs.map(function(key) { + var hash = utils.ripesha(key); + return bcoin.wallet.hash2addr(hash); + }) + }, + value: output.value, + script: s, + lock: lock + }; + } + + if (bcoin.script.isScripthash(s)) { + hash = utils.toHex(s[1]); + addr = bcoin.wallet.hash2addr(hash, 'scripthash'); + return { + type: 'scripthash', + sig: null, + pub: null, + hash: hash, + addr: addr, + scripthash: { + redeem: null, + pub: null, + hash: hash, + addr: addr + }, + value: output.value, + script: s, + lock: lock + }; + } + + if (bcoin.script.isColored(s)) { + ret = bcoin.script.colored(s); + return { + type: 'colored', + addr: '[colored]', + hash: '[colored]', + data: ret, + text: utils.array2ascii(ret), + value: output.value, + script: s, + lock: lock, + none: true + }; + } + + return { + type: 'unknown', + addr: '[unknown]', + hash: '[unknown]', + value: new bn(0), + script: s, + lock: lock, + none: true + }; +}; + /** * Expose */ diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index 30011ceb..56785907 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -37,6 +37,7 @@ function TX(data, block) { this.network = data.network || false; this.relayedBy = data.relayedBy || '0.0.0.0'; this._height = data._height != null ? data._height : -1; + this._confirmations = data._confirmations != null ? data._confirmations : -1; this._lock = this.lock; @@ -52,6 +53,7 @@ function TX(data, block) { } if (!data.ts && block && block.hasTX(this.hash('hex'))) { + // if (!data.block && block) { this.ts = block.ts; this.block = block.hash('hex'); } @@ -75,7 +77,7 @@ TX.prototype.hash = function hash(enc) { }; TX.prototype.render = function render() { - if (this.network) + if (this.network && this._raw) return this._raw.slice(); return bcoin.protocol.framer.tx(this); }; @@ -791,224 +793,6 @@ TX.prototype._recalculateFee = function recalculateFee() { this.changeOutput = output; }; -TX.prototype.inputAddrs = function inputAddrs() { - return this.inputs.filter(function(input) { - return bcoin.script.isPubkeyhashInput(input.script); - }).map(function(input) { - var pub = input.script[1]; - var hash = utils.ripesha(pub); - return bcoin.wallet.hash2addr(hash, 'pubkeyhash'); - }); -}; - -TX.getInputData = function getInputData(input) { - if (!input || !input.script) - return; - - var s = input.script; - var sig, pub, hash, addr, redeem, data, output; - - if (!input.out) { - return { - type: 'unknown', - addr: '[unknown]', - hash: '[unknown]', - value: new bn(0), - script: s, - seq: input.seq, - none: true - }; - } - - if (+input.out.hash === 0) { - return { - type: 'coinbase', - addr: '[coinbase]', - hash: '[coinbase]', - value: new bn(0), - script: s, - seq: input.seq, - none: true - }; - } - - if (input.out.tx) { - output = input.out.tx.outputs[input.out.index]; - return TX.getOutputData(output); - } - - if (bcoin.script.isPubkeyhashInput(s)) { - sig = utils.toHex(s[0]); - pub = s[1]; - hash = utils.ripesha(pub); - addr = bcoin.wallet.hash2addr(hash); - return { - type: 'pubkeyhash', - sig: sig, - pub: pub, - hash: hash, - addr: addr, - value: new bn(0), - script: s, - seq: input.seq - }; - } - - if (bcoin.script.isScripthashInput(s)) { - pub = s[s.length - 1]; - hash = utils.ripesha(pub); - addr = bcoin.wallet.hash2addr(hash, 'scripthash'); - redeem = bcoin.script.decode(pub); - data = TX.getOutputData({ - script: redeem, - value: new bn(0) - }); - data.type = 'scripthash'; - data.pub = pub; - data.hash = hash; - data.addr = addr; - data.scripthash = { - redeem: redeem, - pub: pub, - hash: hash, - addr: addr, - m: data.multisig.m, - n: data.multisig.n, - keys: data.multisig.keys, - hashes: data.multisig.hashes, - addrs: data.multisig.addrs, - script: redeem - }; - data.script = s; - data.seq = input.seq; - return data; - } - - return { - type: 'unknown', - addr: '[unknown]', - hash: '[unknown]', - value: new bn(0), - script: s, - seq: input.seq, - none: true - }; -}; - -TX.getOutputData = function getOutputData(output) { - if (!output || !output.script) return; - - var s = output.script; - var lock = bcoin.script.lockTime(s); - var pub, hash, addr, pubs, ret; - - if (bcoin.script.isPubkey(s)) { - pub = s[0]; - hash = utils.ripesha(pub); - addr = bcoin.wallet.hash2addr(hash); - return { - type: 'pubkey', - sig: null, - pub: pub, - hash: hash, - addr: addr, - value: output.value, - script: s, - lock: lock - }; - } - - if (bcoin.script.isPubkeyhash(s)) { - hash = s[2]; - addr = bcoin.wallet.hash2addr(hash); - return { - type: 'pubkeyhash', - sig: null, - pub: null, - hash: hash, - addr: addr, - value: output.value, - script: s, - lock: lock - }; - } - - pubs = bcoin.script.isMultisig(s); - if (pubs) { - hash = utils.ripesha(pubs[0]); - addr = bcoin.wallet.hash2addr(hash); - return { - type: 'multisig', - sig: null, - pub: pubs[0], - hash: hash, - addr: addr, - keys: pubs, - multisig: { - m: new bn(s[0]).toNumber(), - n: new bn(s[s.length - 2]).toNumber(), - keys: pubs, - hashes: pubs.map(function(key) { - return utils.ripesha(key); - }), - addrs: pubs.map(function(key) { - var hash = utils.ripesha(key); - return bcoin.wallet.hash2addr(hash); - }) - }, - value: output.value, - script: s, - lock: lock - }; - } - - if (bcoin.script.isScripthash(s)) { - hash = utils.toHex(s[1]); - addr = bcoin.wallet.hash2addr(hash, 'scripthash'); - return { - type: 'scripthash', - sig: null, - pub: null, - hash: hash, - addr: addr, - scripthash: { - redeem: null, - pub: null, - hash: hash, - addr: addr - }, - value: output.value, - script: s, - lock: lock - }; - } - - if (bcoin.script.isColored(s)) { - ret = bcoin.script.colored(s); - return { - type: 'colored', - addr: '[colored]', - hash: '[colored]', - data: ret, - text: utils.array2ascii(ret), - value: output.value, - script: s, - lock: lock, - none: true - }; - } - - return { - type: 'unknown', - addr: '[unknown]', - hash: '[unknown]', - value: new bn(0), - script: s, - lock: lock, - none: true - }; -}; - TX.prototype.getFee = function getFee() { return this.funds('in').sub(this.funds('out')); }; @@ -1072,6 +856,9 @@ TX.prototype.getHeight = function getHeight(chain) { TX.prototype.getConfirmations = function getConfirmations(chain) { var top, height; + if (this._confirmations >= 0) + return this._confirmations; + chain = chain || bcoin.chain.global; if (!chain) diff --git a/lib/bcoin/wallet.js b/lib/bcoin/wallet.js index 1bf4bbc6..d9b15955 100644 --- a/lib/bcoin/wallet.js +++ b/lib/bcoin/wallet.js @@ -564,6 +564,37 @@ Wallet.prototype.fill = function fill(tx, cb) { return tx; }; +Wallet.prototype.toAddress = function toAddress() { + var self = this; + var received = new bn(0); + var sent = new bn(0); + + var txs = Object.keys(this.tx._all).reduce(function(out, hash) { + out.push(self.tx._all[hash]); + return out; + }, []); + + txs.forEach(function(tx) { + tx.inputs.forEach(function(input, i) { + if (self.ownInput(tx, i)) + sent.iadd(input.value); + }); + tx.outputs.forEach(function(output, i) { + if (self.ownOutput(tx, i)) + received.iadd(output.value); + }); + }); + + return { + address: this.getFullAddress(), + hash: utils.toHex(this.getFullHash()), + received: received, + sent: sent, + balance: this.balance(), + txs: txs + }; +}; + Wallet.prototype.toJSON = function toJSON(encrypt) { return { v: 1,