From b63a2208fcd852c56bb9eedef89f9b0f36f6535e Mon Sep 17 00:00:00 2001 From: Chris Kleeschulte Date: Thu, 10 Aug 2017 18:56:13 -0400 Subject: [PATCH] Fixes to allow bcoin to work with Transaction controller. --- lib/addresses.js | 9 ++++-- lib/transactions.js | 72 ++++++++++++++++++++++++++------------------- 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/lib/addresses.js b/lib/addresses.js index b45bc18..ed1db73 100644 --- a/lib/addresses.js +++ b/lib/addresses.js @@ -7,6 +7,8 @@ var Common = require('./common'); function AddressController(node) { this.node = node; + this._address = this.node.services.address; + this._block = this.node.services.block; this.txController = new TxController(node); this.common = new Common({log: this.node.log}); } @@ -110,7 +112,7 @@ AddressController.prototype.check = function(req, res, next, addresses) { for(var i = 0; i < addresses.length; i++) { try { - var a = new bitcore.Address(addresses[i]); + new bitcore.Address(addresses[i]); } catch(e) { return self.common.handleErrors({ message: 'Invalid address: ' + e.message, @@ -159,7 +161,8 @@ AddressController.prototype.transformUtxo = function(utxoArg) { }; if (utxoArg.height && utxoArg.height > 0) { utxo.height = utxoArg.height; - utxo.confirmations = this.node.services.bitcoind.height - utxoArg.height + 1; + var height = this._block.getTip().height; + utxo.confirmations = height - utxoArg.height + 1; } else { utxo.confirmations = 0; } @@ -177,7 +180,7 @@ AddressController.prototype._getTransformOptions = function(req) { }; }; -AddressController.prototype.multitxs = function(req, res, next) { +AddressController.prototype.multitxs = function(req, res) { var self = this; var options = { diff --git a/lib/transactions.js b/lib/transactions.js index ec98f9e..0fb7f4b 100644 --- a/lib/transactions.js +++ b/lib/transactions.js @@ -2,6 +2,7 @@ var bitcore = require('bitcore-lib'); var _ = bitcore.deps._; +var bcoin = require('bcoin'); var $ = bitcore.util.preconditions; var Common = require('./common'); var async = require('async'); @@ -11,6 +12,7 @@ var MAXINT = 0xffffffff; // Math.pow(2, 32) - 1; function TxController(node) { this.node = node; this.common = new Common({log: this.node.log}); + this._block = this.node.services.block; } TxController.prototype.show = function(req, res) { @@ -27,12 +29,14 @@ TxController.prototype.transaction = function(req, res, next) { var txid = req.params.txid; this.node.getDetailedTransaction(txid, function(err, transaction) { - if (err && err.code === -5) { - return self.common.handleErrors(null, res); - } else if(err) { + if (err) { return self.common.handleErrors(err, res); } + if (!transaction) { + return self.common.handleErrors(null, res); + } + self.transformTransaction(transaction, function(err, transformedTransaction) { if (err) { return self.common.handleErrors(err, res); @@ -50,49 +54,50 @@ TxController.prototype.transformTransaction = function(transaction, options, cal options = {}; } $.checkArgument(_.isFunction(callback)); - var confirmations = 0; - if(transaction.height >= 0) { - confirmations = this.node.services.bitcoind.height - transaction.height + 1; + if(transaction.__height >= 0) { + var height = this._block.height; + confirmations = height - transaction.__height + 1; } var transformed = { - txid: transaction.hash, + txid: transaction.txid(), version: transaction.version, locktime: transaction.locktime }; - if(transaction.coinbase) { + if(transaction.inputs[0].isCoinbase()) { transformed.vin = [ { - coinbase: transaction.inputs[0].script, + coinbase: transaction.inputs[0].script.toJSON(), sequence: transaction.inputs[0].sequence, n: 0 } ]; } else { + options.inputiValues = transaction.__inputValues; transformed.vin = transaction.inputs.map(this.transformInput.bind(this, options)); } transformed.vout = transaction.outputs.map(this.transformOutput.bind(this, options)); transformed.blockhash = transaction.blockHash; - transformed.blockheight = transaction.height; - transformed.confirmations = confirmations; + transformed.blockheight = transaction.__height; + transformed.confirmations = transaction.confirmations; // TODO consider mempool txs with receivedTime? - var time = transaction.blockTimestamp ? transaction.blockTimestamp : Math.round(Date.now() / 1000); + var time = transaction.__timestamp ? transaction.__timestamp : Math.round(Date.now() / 1000); transformed.time = time; if (transformed.confirmations) { transformed.blocktime = transformed.time; } - if(transaction.coinbase) { + if(transaction.inputs[0].isCoinbase()) { transformed.isCoinBase = true; } transformed.valueOut = transaction.outputSatoshis / 1e8; - transformed.size = transaction.hex.length / 2; // in bytes - if (!transaction.coinbase) { + transformed.size = transaction.getSize(); + if (!transaction.inputs[0].isCoinbase()) { transformed.valueIn = transaction.inputSatoshis / 1e8; transformed.fees = transaction.feeSatoshis / 1e8; } @@ -103,24 +108,30 @@ TxController.prototype.transformTransaction = function(transaction, options, cal TxController.prototype.transformInput = function(options, input, index) { // Input scripts are validated and can be assumed to be valid var transformed = { - txid: input.prevTxId, - vout: input.outputIndex, + txid: input.prevout.txid(), + vout: input.prevout.index, sequence: input.sequence, n: index }; if (!options.noScriptSig) { transformed.scriptSig = { - hex: input.script + hex: input.script.toJSON() }; if (!options.noAsm) { - transformed.scriptSig.asm = input.scriptAsm; + transformed.scriptSig.asm = input.script.toASM(); } } - transformed.addr = input.address; - transformed.valueSat = input.satoshis; - transformed.value = input.satoshis / 1e8; + var address = input.getAddress(); + if (address) { + address.network = this.node.network || 'main'; + transformed.addr = address.toString(); + } else { + transformed.addr = null; + } + transformed.valueSat = options.inputValues[index]; + transformed.value = transformed.valueSat / 1e8; transformed.doubleSpentTxID = null; // TODO //transformed.isConfirmed = null; // TODO //transformed.confirmations = null; // TODO @@ -131,27 +142,28 @@ TxController.prototype.transformInput = function(options, input, index) { TxController.prototype.transformOutput = function(options, output, index) { var transformed = { - value: (output.satoshis / 1e8).toFixed(8), + value: (output.value / 1e8).toFixed(8), n: index, scriptPubKey: { - hex: output.script + hex: output.script.toJSON() } }; if (!options.noAsm) { - transformed.scriptPubKey.asm = output.scriptAsm; + transformed.scriptPubKey.asm = output.script.toASM(); } if (!options.noSpent) { - transformed.spentTxId = output.spentTxId || null; + transformed.spentTxId = output.spentTxId || null; // we aren't tracking this with the bcoin implementation transformed.spentIndex = _.isUndefined(output.spentIndex) ? null : output.spentIndex; transformed.spentHeight = output.spentHeight || null; } - if (output.address) { - transformed.scriptPubKey.addresses = [output.address]; - var address = bitcore.Address(output.address); //TODO return type from bitcore-node - transformed.scriptPubKey.type = address.type; + var address = output.getAddress(); + if (address) { + address.network = this.node.network || 'main'; + transformed.scriptPubKey.addresses = [address.toString()]; + transformed.scriptPubKey.type = address.getType(); } return transformed; };