From a7c8695d9b5386f6d3302ebe5051327ff9ad9bb8 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 22 Sep 2014 12:05:17 -0700 Subject: [PATCH] getTx implemented. --- example/index.js | 14 ++++- lib/bitcoind.js | 4 ++ src/bitcoindjs.cc | 145 +++++++++++++++++++++++++++++++++++++++------- 3 files changed, 139 insertions(+), 24 deletions(-) diff --git a/example/index.js b/example/index.js index 58563dbc..2c75ff9b 100755 --- a/example/index.js +++ b/example/index.js @@ -5,13 +5,22 @@ process.title = 'bitcoind.js'; var util = require('util'); var bitcoind = require('../')(); +var genesisBlock = '0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'; +var genesisTx = '0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b'; + bitcoind.start(function(err) { bitcoind.on('error', function(err) { console.log('bitcoind: error="%s"', err.message); }); bitcoind.on('open', function(status) { + console.log('bitcoind: status="%s"', status); + return setTimeout(function() { + return bitcoind.getTx(genesisTx, genesisBlock, function(err, tx) { + if (err) throw err; + return print(tx); + }); + }, 1000); setTimeout(function() { - var genesis = '0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'; (function next(hash) { return bitcoind.getBlock(hash, function(err, block) { if (err) return console.log(err.message); @@ -20,9 +29,8 @@ bitcoind.start(function(err) { setTimeout(next.bind(null, block.nextblockhash), 200); } }); - })(genesis); + })(genesisBlock); }, 1000); - console.log('bitcoind: status="%s"', status); }); }); diff --git a/lib/bitcoind.js b/lib/bitcoind.js index 2180c183..1d0b3c26 100644 --- a/lib/bitcoind.js +++ b/lib/bitcoind.js @@ -144,6 +144,10 @@ Bitcoin.prototype.getBlock = function(hash, callback) { return bitcoindjs.getBlock(hash, callback); }; +Bitcoin.prototype.getTx = function(hash, blockHash, callback) { + return bitcoindjs.getTx(hash, blockHash, callback); +}; + Bitcoin.prototype.log = Bitcoin.prototype.info = function() { if (typeof arguments[0] !== 'string') { diff --git a/src/bitcoindjs.cc b/src/bitcoindjs.cc index 9ac26c29..d1df9f89 100644 --- a/src/bitcoindjs.cc +++ b/src/bitcoindjs.cc @@ -870,7 +870,6 @@ async_get_block_after(uv_work_t *req) { delete req; } -#if 0 /** * GetTx(hash, callback) * bitcoind.getTx(hash, callback) @@ -884,17 +883,77 @@ NAN_METHOD(GetTx) { if (args.Length() < 2 || !args[0]->IsString() - || !args[1]->IsFunction()) { + || !args[1]->IsString() + || !args[2]->IsFunction()) { return NanThrowError( "Usage: bitcoindjs.getTx(hash, callback)"); } - String::Utf8Value hash(args[0]->ToString()); - Local callback = Local::Cast(args[1]); + String::Utf8Value txHash_(args[0]->ToString()); + String::Utf8Value blockHash_(args[1]->ToString()); + Local callback = Local::Cast(args[2]); Persistent cb; cb = Persistent::New(callback); + std::string txHash = std::string(*txHash_); + std::string blockHash = std::string(*blockHash_); + + // uint256 hash = ParseHashV(params[0], "parameter 1"); + + // uint256 hashBlock(strHash); + // uint256 hashBlock = block.GetHash(); + // uint256 hashBlock = 0; + + + if (txHash[1] != 'x') { + txHash = "0x" + txHash; + } + + if (blockHash[1] != 'x') { + blockHash = "0x" + blockHash; + } + + uint256 hash(txHash); + uint256 hashBlock(blockHash); + // uint256 hashBlock = 0; + CTransaction tx; + if (!GetTransaction(hash, tx, hashBlock, true)) { + Local err = Exception::Error(String::New("Bad Transaction.")); + const unsigned argc = 1; + Local argv[argc] = { err }; + TryCatch try_catch; + cb->Call(Context::GetCurrent()->Global(), argc, argv); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + cb.Dispose(); + NanReturnValue(Undefined()); + } + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << tx; + string strHex = HexStr(ssTx.begin(), ssTx.end()); + + Local obj = NanNew(); + obj->Set(NanNew("hex"), NanNew(strHex.c_str())); + + // TxToJSON(tx, hashBlock, obj); + + const unsigned argc = 2; + Local argv[argc] = { + Local::New(Null()), + Local::New(obj) + }; + TryCatch try_catch; + cb->Call(Context::GetCurrent()->Global(), argc, argv); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + cb.Dispose(); + NanReturnValue(Undefined()); + +#if 0 const CWalletTx& wtx = pwalletMain->mapWallet[hash]; int64_t nFee; @@ -947,23 +1006,69 @@ NAN_METHOD(GetTx) { ret.push_back(entry); } } - - const unsigned argc = 2; - Local argv[argc] = { - Local::New(Null()), - Local::New(obj) - }; - TryCatch try_catch; - cb->Call(Context::GetCurrent()->Global(), argc, argv); - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - - cb.Dispose(); - - NanReturnValue(Undefined()); +#endif } +#if 0 +void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) +{ + entry.push_back(Pair("txid", tx.GetHash().GetHex())); + entry.push_back(Pair("version", tx.nVersion)); + entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime)); + Array vin; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + Object in; + if (tx.IsCoinBase()) + in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + else + { + in.push_back(Pair("txid", txin.prevout.hash.GetHex())); + in.push_back(Pair("vout", (boost::int64_t)txin.prevout.n)); + Object o; + o.push_back(Pair("asm", txin.scriptSig.ToString())); + o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + in.push_back(Pair("scriptSig", o)); + } + in.push_back(Pair("sequence", (boost::int64_t)txin.nSequence)); + vin.push_back(in); + } + entry.push_back(Pair("vin", vin)); + Array vout; + for (unsigned int i = 0; i < tx.vout.size(); i++) + { + const CTxOut& txout = tx.vout[i]; + Object out; + out.push_back(Pair("value", ValueFromAmount(txout.nValue))); + out.push_back(Pair("n", (boost::int64_t)i)); + Object o; + ScriptPubKeyToJSON(txout.scriptPubKey, o, true); + out.push_back(Pair("scriptPubKey", o)); + vout.push_back(out); + } + entry.push_back(Pair("vout", vout)); + + if (hashBlock != 0) + { + entry.push_back(Pair("blockhash", hashBlock.GetHex())); + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi != mapBlockIndex.end() && (*mi).second) + { + CBlockIndex* pindex = (*mi).second; + if (chainActive.Contains(pindex)) + { + entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight)); + entry.push_back(Pair("time", (boost::int64_t)pindex->nTime)); + entry.push_back(Pair("blocktime", (boost::int64_t)pindex->nTime)); + } + else + entry.push_back(Pair("confirmations", 0)); + } + } +} +#endif + +#if 0 void WalletTxToJSON(const CWalletTx& wtx, Object& entry) { int confirms = wtx.GetDepthInMainChain(); entry.push_back(Pair("confirmations", confirms)); @@ -1203,9 +1308,7 @@ init(Handle target) { NODE_SET_METHOD(target, "stopping", IsStopping); NODE_SET_METHOD(target, "stopped", IsStopped); NODE_SET_METHOD(target, "getBlock", GetBlock); -#if 0 NODE_SET_METHOD(target, "getTx", GetTx); -#endif } NODE_MODULE(bitcoindjs, init)