Merge pull request #9 from matiu/feature/add-addr-and-values-to-tx-API
Feature/add addr and values to tx api -- It will be use in transaction page
This commit is contained in:
commit
e754d12129
|
@ -16,7 +16,12 @@ var Transaction = require('../models/Transaction');
|
|||
*/
|
||||
exports.transaction = function(req, res, next, txid) {
|
||||
Transaction.fromIdWithInfo(txid, function(err, tx) {
|
||||
if (err) return next(err);
|
||||
if (err) {
|
||||
console.log(err);
|
||||
res.status(404).send('Not found');
|
||||
return next();
|
||||
}
|
||||
|
||||
if (!tx) return next(new Error('Failed to load TX ' + txid));
|
||||
req.transaction = tx.info;
|
||||
next();
|
||||
|
@ -25,9 +30,11 @@ exports.transaction = function(req, res, next, txid) {
|
|||
|
||||
|
||||
/**
|
||||
* Show block
|
||||
*/
|
||||
exports.show = function(req, res) {
|
||||
|
||||
if (req.transaction) {
|
||||
res.jsonp(req.transaction);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ BlockSchema.statics.fromHash = function(hash, cb) {
|
|||
BlockSchema.statics.fromHashWithInfo = function(hash, cb) {
|
||||
this.fromHash(hash, function(err, block) {
|
||||
if (err) return cb(err);
|
||||
if (!block) { return cb(new Error('Block not found')); }
|
||||
|
||||
block.getInfo(function(err) { return cb(err,block); } );
|
||||
});
|
||||
|
|
|
@ -7,6 +7,11 @@ var mongoose = require('mongoose'),
|
|||
Schema = mongoose.Schema,
|
||||
async = require('async'),
|
||||
RpcClient = require('bitcore/RpcClient').class(),
|
||||
Transaction = require('bitcore/Transaction').class(),
|
||||
Address = require('bitcore/Address').class(),
|
||||
networks = require('bitcore/networks'),
|
||||
util = require('bitcore/util/util'),
|
||||
bignum = require('BigNum'),
|
||||
config = require('../../config/config');
|
||||
|
||||
|
||||
|
@ -41,10 +46,15 @@ TransactionSchema.statics.fromId = function(txid, cb) {
|
|||
};
|
||||
|
||||
TransactionSchema.statics.fromIdWithInfo = function(txid, cb) {
|
||||
|
||||
// TODO Should we go to mongoDB first? Now, no extra information is stored at mongo.
|
||||
|
||||
this.fromId(txid, function(err, tx) {
|
||||
if (err) return cb(err);
|
||||
|
||||
tx.getInfo(function(err) { return cb(err,tx); } );
|
||||
if (!tx) { return cb(new Error('TX not found')); }
|
||||
|
||||
tx.queryInfo(function(err) { return cb(err,tx); } );
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -79,18 +89,98 @@ TransactionSchema.statics.createFromArray = function(txs, next) {
|
|||
};
|
||||
|
||||
|
||||
TransactionSchema.methods.fillInputValues = function (tx, next) {
|
||||
|
||||
TransactionSchema.methods.getInfo = function (next) {
|
||||
if (! this.rpc) this.rpc = new RpcClient(config.bitcoind);
|
||||
|
||||
var that = this;
|
||||
var rpc = new RpcClient(config.bitcoind);
|
||||
async.each(tx.ins, function(i, cb) {
|
||||
|
||||
rpc.getRawTransaction(this.txid, 1, function(err, txInfo) {
|
||||
var outHash = i.getOutpointHash();
|
||||
var outIndex = i.getOutpointIndex();
|
||||
var outHashBase64 = outHash.reverse().toString('hex');
|
||||
|
||||
var c=0;
|
||||
that.rpc.getRawTransaction(outHashBase64, function(err, txdata) {
|
||||
var txin = new Transaction();
|
||||
var b = new Buffer(txdata.result,'hex');
|
||||
txin.parse(b);
|
||||
|
||||
txin.outs.forEach( function(j) {
|
||||
// console.log( c + ': ' + util.formatValue(j.v) );
|
||||
if (c === outIndex) {
|
||||
i.value = j.v;
|
||||
}
|
||||
c++;
|
||||
});
|
||||
return cb();
|
||||
});
|
||||
},
|
||||
function(err) {
|
||||
return next(err);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
TransactionSchema.methods.queryInfo = function (next) {
|
||||
|
||||
var that = this;
|
||||
var network = ( config.network === 'testnet') ? networks.testnet : networks.livenet ;
|
||||
this.rpc = new RpcClient(config.bitcoind);
|
||||
|
||||
|
||||
this.rpc.getRawTransaction(this.txid, 1, function(err, txInfo) {
|
||||
if (err) return next(err);
|
||||
|
||||
that.info = txInfo.result;
|
||||
|
||||
//console.log("THAT", that);
|
||||
return next(null, that.info);
|
||||
// Transaction parsing
|
||||
var b = new Buffer(txInfo.result.hex,'hex');
|
||||
var tx = new Transaction();
|
||||
tx.parse(b);
|
||||
|
||||
that.fillInputValues(tx, function(err) {
|
||||
|
||||
// Copy TX relevant values to .info
|
||||
|
||||
var c = 0;
|
||||
|
||||
|
||||
var valueIn = bignum(0);
|
||||
var valueOut = bignum(0);
|
||||
tx.ins.forEach(function(i) {
|
||||
|
||||
that.info.vin[c].value = util.formatValue(i.value);
|
||||
|
||||
var n = util.valueToBigInt(i.value).toNumber();
|
||||
valueIn = valueIn.add( n );
|
||||
|
||||
|
||||
var scriptSig = i.getScript();
|
||||
var pubKey = scriptSig.simpleInPubKey();
|
||||
var pubKeyHash = util.sha256ripe160(pubKey);
|
||||
var addr = new Address(network.addressPubkey, pubKeyHash);
|
||||
var addrStr = addr.toString();
|
||||
|
||||
that.info.vin[c].addr = addrStr;
|
||||
|
||||
c++;
|
||||
});
|
||||
|
||||
|
||||
tx.outs.forEach( function(i) {
|
||||
var n = util.valueToBigInt(i.v).toNumber();
|
||||
valueOut = valueOut.add(n);
|
||||
});
|
||||
|
||||
that.info.valueIn = valueIn / util.COIN;
|
||||
that.info.valueOut = valueOut / util.COIN;
|
||||
that.info.feeds = (valueIn - valueOut) / util.COIN;
|
||||
|
||||
that.info.size = b.length;
|
||||
|
||||
return next(err, that.info);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -11,5 +11,6 @@ module.exports = {
|
|||
protocol: 'http',
|
||||
host: process.env.BITCOIND_HOST || '127.0.0.1',
|
||||
port: process.env.BITCOIND_PORT || '8332',
|
||||
}
|
||||
},
|
||||
network: 'testnet',
|
||||
}
|
||||
|
|
|
@ -9,8 +9,11 @@ module.exports = function(app) {
|
|||
//Block routes
|
||||
var blocks = require('../app/controllers/blocks');
|
||||
app.get('/api/blocks', blocks.list);
|
||||
|
||||
|
||||
app.get('/api/block/:blockHash', blocks.show);
|
||||
app.param('blockHash', blocks.block);
|
||||
|
||||
app.get('/last_blocks', blocks.last_blocks);
|
||||
|
||||
var transactions = require('../app/controllers/transactions');
|
||||
|
|
|
@ -6,7 +6,8 @@ testnet=3
|
|||
txindex=1
|
||||
|
||||
# Allow connections outsite localhost?
|
||||
# rpcallowip=192.168.0.*
|
||||
rpcallowip=192.168.1.*
|
||||
rpcallowip='192.168.1.*'
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
"async": "*",
|
||||
"classtool": "*",
|
||||
"commander": "*",
|
||||
"bignum": "*",
|
||||
"express": "~3.4.7",
|
||||
"jade": "~1.0.2",
|
||||
"mongoose": "~3.8.3",
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
||||
|
||||
|
||||
var TESTING_BLOCK = '0000000000b6288775bbd326bedf324ca8717a15191da58391535408205aada4';
|
||||
var TESTING_BLOCK = '000000000185678d3d7ecc9962c96418174431f93fe20bf216d5565272423f74';
|
||||
|
||||
var
|
||||
mongoose= require('mongoose'),
|
||||
|
@ -14,7 +14,7 @@ var
|
|||
|
||||
mongoose.connection.on('error', function(err) { console.log(err); });
|
||||
|
||||
describe('Block getInfo', function(){
|
||||
describe('Block fromHashWithInfo', function(){
|
||||
|
||||
before(function(done) {
|
||||
mongoose.connect(config.db);
|
||||
|
@ -27,7 +27,9 @@ describe('Block getInfo', function(){
|
|||
});
|
||||
|
||||
it('should poll block\'s info from mongoose', function(done) {
|
||||
console.log('asdasd');
|
||||
var block2 = Block.fromHashWithInfo(TESTING_BLOCK, function(err, b2) {
|
||||
console.log('333');
|
||||
if (err) done(err);
|
||||
|
||||
assert.equal(b2.hash, TESTING_BLOCK);
|
||||
|
@ -39,7 +41,7 @@ describe('Block getInfo', function(){
|
|||
var block2 = Block.fromHashWithInfo(TESTING_BLOCK, function(err, b2) {
|
||||
if (err) done(err);
|
||||
assert.equal(b2.info.hash, TESTING_BLOCK);
|
||||
assert.equal(b2.info.chainwork, '00000000000000000000000000000000000000000000000000446af21d50acd3');
|
||||
assert.equal(b2.info.chainwork, '000000000000000000000000000000000000000000000000001b6dc969ffe847');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
||||
|
||||
|
||||
var TESTING_TX = '9f4648538a8fd773029139f7e67cee51586bced78d7ff0388d10cb71096f2289';
|
||||
var TESTING_TX = '21798ddc9664ac0ef618f52b151dda82dafaf2e26d2bbef6cdaf55a6957ca237';
|
||||
|
||||
var
|
||||
mongoose= require('mongoose'),
|
||||
|
@ -14,7 +14,7 @@ var
|
|||
|
||||
mongoose.connection.on('error', function(err) { console.log(err); });
|
||||
|
||||
describe('Transaction getInfo', function(){
|
||||
describe('Transaction fromIdWithInfo', function(){
|
||||
|
||||
before(function(done) {
|
||||
mongoose.connect(config.db);
|
||||
|
@ -38,7 +38,10 @@ describe('Transaction getInfo', function(){
|
|||
Transaction.fromIdWithInfo(TESTING_TX, function(err, tx) {
|
||||
if (err) done(err);
|
||||
assert.equal(tx.info.txid, TESTING_TX);
|
||||
assert.equal(tx.info.blockhash, '000000007af2a08af7ce4934167dc2afd7a2e6bfd31472332db02a6f38cb7b4d');
|
||||
assert.equal(tx.info.blockhash, '000000000185678d3d7ecc9962c96418174431f93fe20bf216d5565272423f74');
|
||||
assert.equal(tx.info.valueOut, 1.66174);
|
||||
assert.equal(tx.info.feeds, 0.0005 );
|
||||
assert.equal(tx.info.size, 226 );
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue