From 41fe58077b10cdd3f6d7654079bdc3c79bf29f85 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 3 Oct 2014 17:58:04 -0700 Subject: [PATCH] tests passed. remove javascript conversions. --- example/index.js | 14 -- lib/bitcoind.js | 352 +++------------------------------------------- src/bitcoindjs.cc | 32 +++-- 3 files changed, 45 insertions(+), 353 deletions(-) diff --git a/example/index.js b/example/index.js index 3dcdbad4..47a2439c 100755 --- a/example/index.js +++ b/example/index.js @@ -55,20 +55,6 @@ bitcoind.on('open', function(status) { 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); - print('jshex: %s', jshex); - print('hex: %s', hex); } if (argv['on-block']) { diff --git a/lib/bitcoind.js b/lib/bitcoind.js index 98c58dc0..4c6ff36d 100644 --- a/lib/bitcoind.js +++ b/lib/bitcoind.js @@ -5,13 +5,9 @@ */ var net = require('net'); -var crypto = require('crypto'); var EventEmitter = require('events').EventEmitter; var bitcoindjs = require('../build/Release/bitcoindjs.node'); var util = require('util'); -var net = require('net'); -var assert = require('assert'); -var bn = require('bn.js'); /** * Bitcoin @@ -367,7 +363,9 @@ function Block(data) { return bitcoin.tx(tx); }); - // this.hex = this.toHex(); + if (!this.hex) { + this.hex = this.toHex(); + } } Object.defineProperty(Block.prototype, '_blockFlag', { @@ -382,46 +380,27 @@ Block.isBlock = function(block) { return block._blockFlag === _blockFlag; }; -Block.prototype._getHashJS = function(enc) { - //if (!this.hashJS) { - // this.hashJS = utils.dsha256(this.rawHeader(), 'hex'); - //} - return enc === 'hex' - ? this.hashJS - : utils.dsha256(this.rawHeader()); -}; - Block.prototype.getHash = function(enc) { var data = bitcoindjs.getBlockHex(this); - //if (!this.hash) { - // this.hash = data.hash; - //} + if (!this.hash || this.hash !== data.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; }; -Block.prototype.rawHeader = function() { - var res = new Array(80); - - utils.writeU32(res, this.version, 0); - utils.copy(utils.toArray(this.previousblockhash, 'hex'), res, 4); - utils.copy(utils.toArray(this.merkleroot, 'hex'), res, 36); - utils.writeU32(res, this.time, 68); - utils.writeU32(res, this.bits, 72); - utils.writeU32(res, this.nonce, 76); - - return new Buffer(res); -}; - Block.prototype.verify = function() { return this.verified = this.verified || bitcoindjs.verifyBlock(this); }; Block.prototype.toHex = function() { - // return this.hex = this.hex || Block.toHex(this); - return Block.toHex(this); + var hex = Block.toHex(this); + if (!this.hex || this.hex !== hex) { + this.hex = hex; + } + return hex; }; Block.toHex = function(block) { @@ -438,60 +417,6 @@ Block.toBinary = function(block) { return new Buffer(data.hex, 'hex'); }; -Block.prototype._toHexJS = function() { - // return this.hexJS = this.hexJS || Block._toHexJS(this); - return Block._toHexJS(this); -}; - -Block._toHexJS = function(block) { - return Block._toBinaryJS(block).toString('hex'); -}; - -Block.prototype._toBinaryJS = function() { - return Block._toBinaryJS(this); -}; - -Block._toBinaryJS = function(block) { - var p = []; - var off = 0; - - // version - off += utils.writeU32(p, block.version, off); - - // prev_block - utils.toArray(block.previousblockhash, 'hex').forEach(function(ch) { - p[off++] = ch; - }); - - // merkle_root - utils.toArray(block.merkleroot, 'hex').forEach(function(ch) { - p[off++] = ch; - }); - - // timestamp - off += utils.writeU32(p, block.time, off); - - // bits - off += utils.writeU32(p, block.bits, off); - - // nonce - off += utils.writeU32(p, block.nonce, off); - - assert.equal(off, 80); - - // txn_count - off += utils.varint(p, block.tx.length, off); - // txs - block.tx.forEach(function(tx) { - tx = bitcoin.tx(tx); - utils.toArray(tx._toHexJS(), 'hex').forEach(function(ch) { - p[off++] = ch; - }); - }); - - return new Buffer(p); -}; - /** * Transaction */ @@ -515,7 +440,9 @@ function Transaction(data) { } }); - // this.hex = this.toHex(); + if (!this.hex) { + this.hex = this.toHex(); + } } Object.defineProperty(Transaction.prototype, '_txFlag', { @@ -562,20 +489,11 @@ Transaction.fill = function(tx, options) { return isTx ? true : tx; }; -Transaction.prototype._getHashJS = function(enc) { - //if (!this.hashJS) { - // this.hashJS = utils.dsha256(this._toBinaryJS(), 'hex'); - //} - return enc === 'hex' - ? this.hashJS - : utils.dsha256(this._toBinaryJS()); -}; - Transaction.prototype.getHash = function(enc) { var data = bitcoindjs.getTxHex(this); - //if (!this.hash) { - // this.hash = data.hash; - //} + if (!this.txid || this.txid !== data.hash) { + this.txid = data.hash; + } if (enc === 'hex') return data.hash; var buf = new Buffer(data.hash, 'hex'); var out = enc ? buf.toString(enc) : buf; @@ -587,8 +505,11 @@ Transaction.prototype.isCoinbase = function() { }; Transaction.prototype.toHex = function() { - // return this.hex = this.hex || Transaction.toHex(this); - return Transaction.toHex(this); + var hex = Transaction.toHex(this); + if (!this.hex || hex !== this.hex) { + this.hex = hex; + } + return hex; }; Transaction.toHex = function(tx) { @@ -605,58 +526,6 @@ Transaction.toBinary = function(tx) { return new Buffer(data.hex, 'hex'); }; -Transaction.prototype._toHexJS = function() { - // return this.hexJS = this.hexJS || Transaction._toHexJS(this); - return Transaction._toHexJS(this); -}; - -Transaction._toHexJS = function(tx) { - return Transaction._toBinaryJS(tx).toString('hex'); -}; - -Transaction.prototype._toBinaryJS = function() { - return Transaction._toBinaryJS(this); -}; - -Transaction._toBinaryJS = function(tx) { - var p = []; - var off = utils.writeU32(p, tx.version, 0); - off += utils.varint(p, tx.vin.length, off); - - for (var i = 0; i < tx.vin.length; i++) { - var input = tx.vin[i]; - - off += utils.copy(utils.toArray(input.txid, 'hex'), p, off, true); - off += utils.writeU32(p, input.vout, off); - - var s = script.encode(utils.toArray(input.scriptSig.hex, 'hex')); - off += utils.varint(p, s.length, off); - off += utils.copy(s, p, off, true); - - off += utils.writeU32(p, input.sequence, off); - } - - off += utils.varint(p, tx.vout.length, off); - for (var i = 0; i < tx.vout.length; i++) { - var output = tx.vout[i]; - - // Put LE value - var value = new bn(output.value).toArray().slice().reverse(); - assert(value.length <= 8); - off += utils.copy(value, p, off, true); - for (var j = value.length; j < 8; j++, off++) { - p[off] = 0; - } - - var s = script.encode(utils.toArray(output.scriptPubKey.hex, 'hex')); - off += utils.varint(p, s.length, off); - off += utils.copy(s, p, off, true); - } - off += utils.writeU32(p, tx.locktime, off); - - return new Buffer(p); -}; - Transaction.broadcast = function(tx, options, callback) { if (typeof tx === 'string') { tx = { hex: tx }; @@ -680,7 +549,6 @@ Transaction.broadcast = function(tx, options, callback) { if (!bitcoin.isTx(tx)) { tx = bitcoin.tx(tx); - // tx.hex = tx.toHex(); } return bitcoindjs.broadcastTx(tx, fee, own, function(err, hash, tx) { @@ -704,49 +572,6 @@ Transaction.prototype.broadcast = function(options, callback) { return Transaction.broadcast(this, options, callback); }; -/** - * Script - */ - -var script = {}; - -script.encode = function encode(s) { - if (!s) { - return []; - } - - var res = []; - for (var i = 0; i < s.length; i++) { - var instr = s[i]; - - // Push value to stack - if (Array.isArray(instr)) { - if (instr.length === 0) { - res.push(0); - } else if (instr.length === 1 && 0 < instr[0] && instr[0] <= 16) { - res.push(0x50 + instr[0]); - } else if (1 <= instr.length && instr.length <= 0x4b) { - res = res.concat(instr.length, instr); - } else if (instr.length <= 0xff) { - res = res.concat(0x4c, instr.length, instr); - } else if (instr.length <= 0xffff) { - res.push(0x4d); - utils.writeU16(res, instr.length, res.length); - res = res.concat(instr); - } else { - res.push(0x4e); - utils.writeU32(res, instr.length, res.length); - res = res.concat(instr); - } - continue; - } - - res.push(instr); - } - - return res; -}; - /** * Wallet * Singleton @@ -856,14 +681,6 @@ Wallet = new Wallet; var utils = {}; -utils.revHex = function revHex(s) { - var r = ''; - for (var i = 0; i < s.length; i += 2) { - r = s.slice(i, i + 2) + r; - } - return r; -}; - utils.forEach = function(obj, iter, done) { var pending = obj.length; if (!pending) return done(); @@ -875,129 +692,6 @@ utils.forEach = function(obj, iter, done) { }); }; -utils.writeU16 = function writeU16(dst, num, off) { - if (!off) - off = 0; - dst[off] = num & 0xff; - dst[off + 1] = (num >>> 8) & 0xff; - return 2; -}; - -utils.writeU32 = function writeU32(dst, num, off) { - if (!off) - off = 0; - dst[off] = num & 0xff; - dst[off + 1] = (num >>> 8) & 0xff; - dst[off + 2] = (num >>> 16) & 0xff; - dst[off + 3] = (num >>> 24) & 0xff; - return 4; -}; - -utils.varint = function(arr, value, off) { - if (!off) - off = 0; - if (value < 0xfd) { - arr[off] = value; - return 1; - } else if (value <= 0xffff) { - arr[off] = 0xfd; - arr[off + 1] = value & 0xff; - arr[off + 2] = value >>> 8; - return 3; - } else if (value <= 0xffffffff) { - arr[off] = 0xfe; - arr[off + 1] = value & 0xff; - arr[off + 2] = (value >>> 8) & 0xff; - arr[off + 3] = (value >>> 16) & 0xff; - arr[off + 4] = value >>> 24; - return 5; - } else { - arr[off] = 0xff; - utils.writeU64(arr, value, off + 1); - return 9; - } -}; - -utils.ripesha = function(data, enc) { - return utils.ripemd160(utils.sha256(data), enc); -}; - -utils.checksum = function(data, enc) { - var b = new Buffer(utils.toArray(utils.dsha256(data)).slice(0, 4)); - return enc ? b.toString(enc) : b; -}; - -utils.dsha256 = function(data, enc) { - return utils.sha256(utils.sha256(data), enc); -}; - -utils._hash = function(algo, data, enc) { - var hash = crypto.createHash(algo); - hash.update(data); - return hash.digest(enc); -}; - -utils.sha256 = function(data, enc) { - return utils._hash('sha256', data, enc); -}; - -utils.ripemd160 = function(data, enc) { - return utils._hash('ripemd160', data, enc); -}; - -utils.copy = function copy(src, dst, off, force) { - var len = src.length; - if (!force) - len = Math.min(dst.length - off, len); - for (var i = 0; i < len; i++) - dst[i + off] = src[i]; - return i; -}; - -function toArray(msg, enc) { - if (Buffer.isBuffer(msg)) - return Array.prototype.slice.call(msg); - if (Array.isArray(msg)) - return msg.slice(); - if (!msg) - return []; - var res = []; - if (typeof msg === 'string') { - if (!enc) { - for (var i = 0; i < msg.length; i++) { - var c = msg.charCodeAt(i); - var hi = c >> 8; - var lo = c & 0xff; - if (hi) - res.push(hi, lo); - else - res.push(lo); - } - } else if (enc === 'hex') { - msg = msg.replace(/[^a-z0-9]+/ig, ''); - if (msg.length % 2 !== 0) - msg = '0' + msg; - for (var i = 0; i < msg.length; i += 8) { - var slice = msg.slice(i, i + 8); - var num = parseInt(slice, 16); - - if (slice.length === 8) - res.push((num >>> 24) & 0xff); - if (slice.length >= 6) - res.push((num >>> 16) & 0xff); - if (slice.length >= 4) - res.push((num >>> 8) & 0xff); - res.push(num & 0xff); - } - } - } else { - for (var i = 0; i < msg.length; i++) - res[i] = msg[i] | 0; - } - return res; -} -utils.toArray = toArray; - utils.NOOP = function() {}; /** @@ -1028,6 +722,4 @@ exports.tx = Transaction; exports.Wallet = Wallet; exports.wallet = Wallet; -exports.script = script; - exports.utils = utils; diff --git a/src/bitcoindjs.cc b/src/bitcoindjs.cc index 53dbb33a..9f3e1c96 100644 --- a/src/bitcoindjs.cc +++ b/src/bitcoindjs.cc @@ -1354,7 +1354,7 @@ NAN_METHOD(GetTxHex) { Local data = NanNew(); - data->Set(NanNew("hash"), NanNew(ctx.GetHash().GetHex())); + data->Set(NanNew("hash"), NanNew(ctx.GetHash().GetHex().c_str())); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << ctx; @@ -2537,12 +2537,15 @@ ctx_to_jstx(const CTransaction& ctx, uint256 block_hash, Local jstx) { // 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); + 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)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); //} in->Set(NanNew("sequence"), NanNew((unsigned int)txin.nSequence)->ToUint32()); @@ -2657,8 +2660,7 @@ jsblock_to_cblock(const Local jsblock, CBlock& cblock) { cblock.hashPrevBlock = hash; } else { // genesis block - uint256 hash(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")); - cblock.hashPrevBlock = hash; + cblock.hashPrevBlock = uint256(0); } Local txs = Local::Cast(jsblock->Get(NanNew("tx"))); @@ -2676,6 +2678,18 @@ jsblock_to_cblock(const Local jsblock, CBlock& cblock) { static inline void jstx_to_ctx(const Local jstx, CTransaction& ctx) { + String::AsciiValue hex_string_(jstx->Get(NanNew("hex"))->ToString()); + std::string hex_string = *hex_string_; + + CDataStream ssData(ParseHex(hex_string), SER_NETWORK, PROTOCOL_VERSION); + try { + ssData >> ctx; + } catch (std::exception &e) { + NanThrowError("Bad TX decode"); + } + + return; + 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();