diff --git a/example/index.js b/example/index.js index ca388753..3dcdbad4 100755 --- a/example/index.js +++ b/example/index.js @@ -33,22 +33,37 @@ bitcoind.on('open', function(status) { getBlocks(bitcoind); } - function hashCompare(obj) { + function compareObj(obj) { + // Hash if (obj.txid) { print('tx.txid: %s', obj.txid); + print('tx.getHash("hex"): %s', obj.getHash('hex')); + print('tx.txid === tx.getHash("hex"): %s', obj.txid === obj.getHash('hex')); } else { print('block.hash: %s', obj.hash); + print('block.getHash("hex"): %s', obj.getHash('hex')); + print('block.hash === block.getHash("hex"): %s', obj.hash === obj.getHash('hex')); } + + // Hex if (obj.txid) { - print('tx.hex: %s', obj.hex || obj.toHex()); + print('tx.hex: %s', obj.hex); + print('tx.toHex(): %s', obj.toHex()); + print('tx.hex === tx.toHex(): %s', obj.hex === obj.toHex()); } else { - print('block.hex: %s', obj.hex || obj.toHex()); + print('block.hex: %s', obj.hex); + print('block.toHex(): %s', obj.toHex()); + print('block.hex === block.toHex(): %s', obj.hex === obj.toHex()); } + + return; + var jshash = obj._getHashJS('hex'); var hash = obj.getHash('hex'); print('jshash === hash: %s', jshash == hash); print('jshash: %s', jshash); print('hash: %s', hash); + var jshex = obj._toHexJS(); var hex = obj.toHex(); print('jshex === hex: %s', jshex == hex); @@ -60,7 +75,7 @@ bitcoind.on('open', function(status) { bitcoind.on('block', function(block) { print('Found Block:'); print(block); - hashCompare(block); + compareObj(block); }); } @@ -68,12 +83,12 @@ bitcoind.on('open', function(status) { bitcoind.on('tx', function(tx) { print('Found TX:'); print(tx); - hashCompare(tx); + compareObj(tx); }); bitcoind.on('mptx', function(mptx) { print('Found mempool TX:'); print(mptx); - hashCompare(mptx); + compareObj(mptx); }); } diff --git a/lib/bitcoind.js b/lib/bitcoind.js index 38f31435..98c58dc0 100644 --- a/lib/bitcoind.js +++ b/lib/bitcoind.js @@ -383,9 +383,9 @@ Block.isBlock = function(block) { }; Block.prototype._getHashJS = function(enc) { - if (!this.hashJS) { - this.hashJS = utils.dsha256(this.rawHeader(), 'hex'); - } + //if (!this.hashJS) { + // this.hashJS = utils.dsha256(this.rawHeader(), 'hex'); + //} return enc === 'hex' ? this.hashJS : utils.dsha256(this.rawHeader()); @@ -393,10 +393,10 @@ Block.prototype._getHashJS = function(enc) { Block.prototype.getHash = function(enc) { var data = bitcoindjs.getBlockHex(this); - if (!this.hash) { - this.hash = data.hash; - } - if (enc === 'hex') return this.hash; + //if (!this.hash) { + // this.hash = data.hash; + //} + if (enc === 'hex') return data.hash; var buf = new Buffer(data.hash, 'hex'); var out = enc ? buf.toString(enc) : buf; return out; @@ -420,8 +420,8 @@ Block.prototype.verify = function() { }; Block.prototype.toHex = function() { + // return this.hex = this.hex || Block.toHex(this); return Block.toHex(this); - return this.hex = this.hex || Block.toHex(this); }; Block.toHex = function(block) { @@ -439,8 +439,8 @@ Block.toBinary = function(block) { }; Block.prototype._toHexJS = function() { + // return this.hexJS = this.hexJS || Block._toHexJS(this); return Block._toHexJS(this); - return this.hexJS = this.hexJS || Block._toHexJS(this); }; Block._toHexJS = function(block) { @@ -563,9 +563,9 @@ Transaction.fill = function(tx, options) { }; Transaction.prototype._getHashJS = function(enc) { - if (!this.hashJS) { - this.hashJS = utils.dsha256(this._toBinaryJS(), 'hex'); - } + //if (!this.hashJS) { + // this.hashJS = utils.dsha256(this._toBinaryJS(), 'hex'); + //} return enc === 'hex' ? this.hashJS : utils.dsha256(this._toBinaryJS()); @@ -573,10 +573,10 @@ Transaction.prototype._getHashJS = function(enc) { Transaction.prototype.getHash = function(enc) { var data = bitcoindjs.getTxHex(this); - if (!this.hash) { - this.hash = data.hash; - } - if (enc === 'hex') return this.hash; + //if (!this.hash) { + // this.hash = data.hash; + //} + if (enc === 'hex') return data.hash; var buf = new Buffer(data.hash, 'hex'); var out = enc ? buf.toString(enc) : buf; return out; @@ -587,8 +587,8 @@ Transaction.prototype.isCoinbase = function() { }; Transaction.prototype.toHex = function() { + // return this.hex = this.hex || Transaction.toHex(this); return Transaction.toHex(this); - return this.hex = this.hex || Transaction.toHex(this); }; Transaction.toHex = function(tx) { @@ -606,8 +606,8 @@ Transaction.toBinary = function(tx) { }; Transaction.prototype._toHexJS = function() { + // return this.hexJS = this.hexJS || Transaction._toHexJS(this); return Transaction._toHexJS(this); - return this.hexJS = this.hexJS || Transaction._toHexJS(this); }; Transaction._toHexJS = function(tx) { diff --git a/src/bitcoindjs.cc b/src/bitcoindjs.cc index 32bed422..53dbb33a 100644 --- a/src/bitcoindjs.cc +++ b/src/bitcoindjs.cc @@ -2459,8 +2459,8 @@ cblock_to_jsblock(const CBlock& cblock, const CBlockIndex* cblock_index, LocalSet(NanNew("hash"), NanNew(cblock.GetHash().GetHex().c_str())); CMerkleTx txGen(cblock.vtx[0]); txGen.SetMerkleBranch(&cblock); - jsblock->Set(NanNew("confirmations"), NanNew((int)txGen.GetDepthInMainChain())); - jsblock->Set(NanNew("size"), NanNew((int)::GetSerializeSize(cblock, SER_NETWORK, PROTOCOL_VERSION))); + jsblock->Set(NanNew("confirmations"), NanNew((int)txGen.GetDepthInMainChain())->ToInt32()); + jsblock->Set(NanNew("size"), NanNew((int)::GetSerializeSize(cblock, SER_NETWORK, PROTOCOL_VERSION))->ToInt32()); jsblock->Set(NanNew("height"), NanNew(cblock_index->nHeight)); jsblock->Set(NanNew("version"), NanNew(cblock.nVersion)); jsblock->Set(NanNew("merkleroot"), NanNew(cblock.hashMerkleRoot.GetHex())); @@ -2488,9 +2488,9 @@ cblock_to_jsblock(const CBlock& cblock, const CBlockIndex* cblock_index, LocalSet(NanNew("tx"), txs); - jsblock->Set(NanNew("time"), NanNew((boost::int64_t)cblock.GetBlockTime())); - jsblock->Set(NanNew("nonce"), NanNew((boost::uint64_t)cblock.nNonce)); - jsblock->Set(NanNew("bits"), NanNew(cblock.nBits)); + jsblock->Set(NanNew("time"), NanNew((unsigned int)cblock.GetBlockTime())->ToUint32()); + jsblock->Set(NanNew("nonce"), NanNew((unsigned int)cblock.nNonce)->ToUint32()); + jsblock->Set(NanNew("bits"), NanNew((unsigned int)cblock.nBits)->ToUint32()); jsblock->Set(NanNew("difficulty"), NanNew(GetDifficulty(cblock_index))); jsblock->Set(NanNew("chainwork"), NanNew(cblock_index->nChainWork.GetHex())); @@ -2515,33 +2515,37 @@ cblock_to_jsblock(const CBlock& cblock, const CBlockIndex* cblock_index, Local jstx) { - jstx->Set(NanNew("mintxfee"), NanNew(ctx.nMinTxFee)); - jstx->Set(NanNew("minrelaytxfee"), NanNew(ctx.nMinRelayTxFee)); - jstx->Set(NanNew("current_version"), NanNew(ctx.CURRENT_VERSION)); + jstx->Set(NanNew("mintxfee"), NanNew((int64_t)ctx.nMinTxFee)->ToInteger()); + jstx->Set(NanNew("minrelaytxfee"), NanNew((int64_t)ctx.nMinRelayTxFee)->ToInteger()); + jstx->Set(NanNew("current_version"), NanNew((int)ctx.CURRENT_VERSION)->ToInt32()); jstx->Set(NanNew("txid"), NanNew(ctx.GetHash().GetHex())); - jstx->Set(NanNew("version"), NanNew(ctx.nVersion)); - jstx->Set(NanNew("locktime"), NanNew(ctx.nLockTime)); + jstx->Set(NanNew("version"), NanNew((int)ctx.nVersion)->ToInt32()); + jstx->Set(NanNew("locktime"), NanNew((unsigned int)ctx.nLockTime)->ToUint32()); Local vin = NanNew(); int vi = 0; BOOST_FOREACH(const CTxIn& txin, ctx.vin) { Local in = NanNew(); - if (ctx.IsCoinBase()) { - in->Set(NanNew("coinbase"), NanNew(HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); - } + //if (ctx.IsCoinBase()) { + // in->Set(NanNew("coinbase"), NanNew(HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + // in->Set(NanNew("txid"), NanNew(txin.prevout.hash.GetHex())); + // in->Set(NanNew("vout"), NanNew((unsigned int)0)->ToUint32()); + // Local o = NanNew(); + // o->Set(NanNew("asm"), NanNew(txin.scriptSig.ToString())); + // o->Set(NanNew("hex"), NanNew(HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + // in->Set(NanNew("scriptSig"), o); + //} else { + in->Set(NanNew("txid"), NanNew(txin.prevout.hash.GetHex())); + in->Set(NanNew("vout"), NanNew((unsigned int)txin.prevout.n)->ToUint32()); + Local o = NanNew(); + o->Set(NanNew("asm"), NanNew(txin.scriptSig.ToString())); + o->Set(NanNew("hex"), NanNew(HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + in->Set(NanNew("scriptSig"), o); + //} - // else - in->Set(NanNew("txid"), NanNew(txin.prevout.hash.GetHex())); - in->Set(NanNew("vout"), NanNew((boost::int64_t)txin.prevout.n)); - Local o = NanNew(); - o->Set(NanNew("asm"), NanNew(txin.scriptSig.ToString())); - o->Set(NanNew("hex"), NanNew(HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); - in->Set(NanNew("scriptSig"), o); - // /else - - in->Set(NanNew("sequence"), NanNew((boost::int64_t)txin.nSequence)); + in->Set(NanNew("sequence"), NanNew((unsigned int)txin.nSequence)->ToUint32()); vin->Set(vi, in); vi++; @@ -2553,8 +2557,8 @@ ctx_to_jstx(const CTransaction& ctx, uint256 block_hash, Local jstx) { const CTxOut& txout = ctx.vout[vo]; Local out = NanNew(); - out->Set(NanNew("value"), NanNew(txout.nValue)); - out->Set(NanNew("n"), NanNew((boost::int64_t)vo)); + out->Set(NanNew("value"), NanNew((int64_t)txout.nValue)->ToInteger()); + out->Set(NanNew("n"), NanNew((unsigned int)vo)->ToUint32()); Local o = NanNew(); { @@ -2569,7 +2573,7 @@ ctx_to_jstx(const CTransaction& ctx, uint256 block_hash, Local jstx) { if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) { out->Set(NanNew("type"), NanNew(GetTxnOutputType(type))); } else { - out->Set(NanNew("reqSigs"), NanNew(nRequired)); + out->Set(NanNew("reqSigs"), NanNew((int)nRequired)->ToInt32()); out->Set(NanNew("type"), NanNew(GetTxnOutputType(type))); Local a = NanNew(); int ai = 0; @@ -2594,8 +2598,8 @@ ctx_to_jstx(const CTransaction& ctx, uint256 block_hash, Local jstx) { if (chainActive.Contains(cblock_index)) { jstx->Set(NanNew("confirmations"), NanNew(1 + chainActive.Height() - cblock_index->nHeight)); - jstx->Set(NanNew("time"), NanNew((boost::int64_t)cblock_index->nTime)); - jstx->Set(NanNew("blocktime"), NanNew((boost::int64_t)cblock_index->nTime)); + jstx->Set(NanNew("time"), NanNew((int64_t)cblock_index->nTime)->ToInteger()); + jstx->Set(NanNew("blocktime"), NanNew((int64_t)cblock_index->nTime)->ToInteger()); } else { jstx->Set(NanNew("confirmations"), NanNew(0)); } @@ -2606,11 +2610,34 @@ ctx_to_jstx(const CTransaction& ctx, uint256 block_hash, Local jstx) { ssTx << ctx; std::string strHex = HexStr(ssTx.begin(), ssTx.end()); jstx->Set(NanNew("hex"), NanNew(strHex)); + +#if DEBUG_TX + printf("TO JS -----------------------------------------------------------------\n"); + printf("nMinTxFee: %ld\n", ctx.nMinTxFee); + printf("nMinRelayTxFee: %ld\n", ctx.nMinRelayTxFee); + printf("CURRENT_VERSION: %d\n", ctx.CURRENT_VERSION); + printf("nVersion: %d\n", ctx.nVersion); + BOOST_FOREACH(const CTxIn& txin, ctx.vin) { + printf("txin.prevout.hash: %s\n", txin.prevout.hash.GetHex().c_str()); + printf("txin.prevout.n: %u\n", txin.prevout.n); + std::string strHex = HexStr(txin.scriptSig.begin(), txin.scriptSig.end(), true); + printf("txin.scriptSig: %s\n", strHex.c_str()); + printf("txin.nSequence: %u\n", txin.nSequence); + } + for (unsigned int vo = 0; vo < ctx.vout.size(); vo++) { + CTxOut txout = ctx.vout[vo]; + printf("txout.nValue: %ld\n", txout.nValue); + std::string strHex = HexStr(txout.scriptPubKey.begin(), txout.scriptPubKey.end(), true); + printf("txin.scriptPubKey: %s\n", strHex.c_str()); + } + printf("nLockTime: %u\n", ctx.nLockTime); + printf("/ TO JS -----------------------------------------------------------------\n"); +#endif } static inline void jsblock_to_cblock(const Local jsblock, CBlock& cblock) { - cblock.nVersion = (int)jsblock->Get(NanNew("version"))->IntegerValue(); + cblock.nVersion = (int)jsblock->Get(NanNew("version"))->Int32Value(); String::AsciiValue mhash__(jsblock->Get(NanNew("merkleroot"))->ToString()); std::string mhash_ = *mhash__; @@ -2618,9 +2645,9 @@ jsblock_to_cblock(const Local jsblock, CBlock& cblock) { uint256 mhash(mhash_); cblock.hashMerkleRoot = mhash; - cblock.nTime = (unsigned int)jsblock->Get(NanNew("time"))->IntegerValue(); - cblock.nNonce = (unsigned int)jsblock->Get(NanNew("nonce"))->IntegerValue(); - cblock.nBits = (unsigned int)jsblock->Get(NanNew("bits"))->IntegerValue(); + cblock.nTime = (unsigned int)jsblock->Get(NanNew("time"))->Uint32Value(); + cblock.nNonce = (unsigned int)jsblock->Get(NanNew("nonce"))->Uint32Value(); + cblock.nBits = (unsigned int)jsblock->Get(NanNew("bits"))->Uint32Value(); if (jsblock->Get(NanNew("previousblockhash"))->IsString()) { String::AsciiValue hash__(jsblock->Get(NanNew("previousblockhash"))->ToString()); @@ -2641,44 +2668,49 @@ jsblock_to_cblock(const Local jsblock, CBlock& cblock) { jstx_to_ctx(jstx, ctx); cblock.vtx.push_back(ctx); } + + if (cblock.vMerkleTree.empty()) { + cblock.BuildMerkleTree(); + } } static inline void jstx_to_ctx(const Local jstx, CTransaction& ctx) { - ctx.nMinTxFee = jstx->Get(NanNew("mintxfee"))->IntegerValue(); - ctx.nMinRelayTxFee = jstx->Get(NanNew("minrelaytxfee"))->IntegerValue(); - // ctx.CURRENT_VERSION = jstx->Get(NanNew("current_version"))->IntegerValue(); + ctx.nMinTxFee = (int64_t)jstx->Get(NanNew("mintxfee"))->IntegerValue(); + ctx.nMinRelayTxFee = (int64_t)jstx->Get(NanNew("minrelaytxfee"))->IntegerValue(); + // ctx.CURRENT_VERSION = (unsigned int)jstx->Get(NanNew("current_version"))->Int32Value(); - ctx.nVersion = jstx->Get(NanNew("version"))->IntegerValue(); + ctx.nVersion = (int)jstx->Get(NanNew("version"))->Int32Value(); Local vin = Local::Cast(jstx->Get(NanNew("vin"))); for (unsigned int vi = 0; vi < vin->Length(); vi++) { CTxIn txin; + Local in = Local::Cast(vin->Get(vi)); - String::AsciiValue phash__(in->Get(NanNew("txid"))->ToString()); - std::string phash_ = *phash__; - if (phash_[1] != 'x') phash_ = "0x" + phash_; - uint256 phash(phash_); + //if (ctx.IsCoinBase()) { + // txin.prevout.hash = uint256(0); + // txin.prevout.n = (unsigned int)0; + //} else { + String::AsciiValue phash__(in->Get(NanNew("txid"))->ToString()); + std::string phash_ = *phash__; + if (phash_[1] != 'x') phash_ = "0x" + phash_; + uint256 phash(phash_); - txin.prevout.hash = phash; - txin.prevout.n = (boost::int64_t)in->Get(NanNew("vout"))->IntegerValue(); + txin.prevout.hash = phash; + txin.prevout.n = (unsigned int)in->Get(NanNew("vout"))->Uint32Value(); + //} std::string shash_; - //if (in->Get(NanNew("coinbase"))->IsString()) { - // String::AsciiValue shash__(in->Get(NanNew("coinbase"))->ToString()); - // shash_ = *shash__; - //} else { Local script_obj = Local::Cast(in->Get(NanNew("scriptSig"))); String::AsciiValue shash__(script_obj->Get(NanNew("hex"))->ToString()); shash_ = *shash__; - //} if (shash_[1] != 'x') shash_ = "0x" + shash_; uint256 shash(shash_); CScript scriptSig(shash); txin.scriptSig = scriptSig; - txin.nSequence = (boost::int64_t)in->Get(NanNew("sequence"))->IntegerValue(); + txin.nSequence = (unsigned int)in->Get(NanNew("sequence"))->Uint32Value(); ctx.vin.push_back(txin); } @@ -2688,7 +2720,8 @@ jstx_to_ctx(const Local jstx, CTransaction& ctx) { CTxOut txout; Local out = Local::Cast(vout->Get(vo)); - txout.nValue = (int64_t)out->Get(NanNew("value"))->IntegerValue(); + int64_t nValue = (int64_t)out->Get(NanNew("value"))->IntegerValue(); + txout.nValue = nValue; Local script_obj = Local::Cast(out->Get(NanNew("scriptPubKey"))); String::AsciiValue phash__(script_obj->Get(NanNew("hex"))); @@ -2702,7 +2735,31 @@ jstx_to_ctx(const Local jstx, CTransaction& ctx) { ctx.vout.push_back(txout); } - ctx.nLockTime = jstx->Get(NanNew("locktime"))->IntegerValue(); + ctx.nLockTime = (unsigned int)jstx->Get(NanNew("locktime"))->Uint32Value(); + +#if DEBUG_TX + printf("TO CTX -----------------------------------------------------------------\n"); + printf("nMinTxFee: %ld\n", ctx.nMinTxFee); + printf("nMinRelayTxFee: %ld\n", ctx.nMinRelayTxFee); + printf("CURRENT_VERSION: %d\n", ctx.CURRENT_VERSION); + printf("nVersion: %d\n", ctx.nVersion); + for (unsigned int vi = 0; vi < vin->Length(); vi++) { + CTxIn txin = ctx.vin[vi]; + printf("txin.prevout.hash: %s\n", txin.prevout.hash.GetHex().c_str()); + printf("txin.prevout.n: %u\n", txin.prevout.n); + std::string strHex = HexStr(txin.scriptSig.begin(), txin.scriptSig.end(), true); + printf("txin.scriptSig: %s\n", strHex.c_str()); + printf("txin.nSequence: %u\n", txin.nSequence); + } + for (unsigned int vo = 0; vo < vout->Length(); vo++) { + CTxOut txout = ctx.vout[vo]; + printf("txout.nValue: %ld\n", txout.nValue); + std::string strHex = HexStr(txout.scriptPubKey.begin(), txout.scriptPubKey.end(), true); + printf("txin.scriptPubKey: %s\n", strHex.c_str()); + } + printf("nLockTime: %u\n", ctx.nLockTime); + printf("/ TO CTX -----------------------------------------------------------------\n"); +#endif } /** diff --git a/src/bitcoindjs.h b/src/bitcoindjs.h index 1e255dd7..022698c6 100644 --- a/src/bitcoindjs.h +++ b/src/bitcoindjs.h @@ -5,3 +5,5 @@ * bitcoindjs.h: * A bitcoind node.js binding header file. */ + +#define DEBUG_TX 0