bitcoindjs.verifyBlock.
This commit is contained in:
parent
4b6fceee37
commit
41c0cb5a4e
@ -69,7 +69,7 @@ function getBlocks(bitcoind) {
|
|||||||
return bitcoind.getBlock(hash, function(err, block) {
|
return bitcoind.getBlock(hash, function(err, block) {
|
||||||
if (err) return print(err.message);
|
if (err) return print(err.message);
|
||||||
|
|
||||||
// print(block);
|
print(block);
|
||||||
|
|
||||||
if (argv['get-tx'] && block.tx.length && block.tx[0].txid) {
|
if (argv['get-tx'] && block.tx.length && block.tx[0].txid) {
|
||||||
var txid = block.tx[0].txid;
|
var txid = block.tx[0].txid;
|
||||||
|
|||||||
124
lib/bitcoind.js
124
lib/bitcoind.js
@ -9,6 +9,7 @@ var EventEmitter = require('events').EventEmitter;
|
|||||||
var bitcoindjs = require('../build/Release/bitcoindjs.node');
|
var bitcoindjs = require('../build/Release/bitcoindjs.node');
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
var net = require('net');
|
var net = require('net');
|
||||||
|
var assert = require('assert');
|
||||||
var bn = require('bn.js');
|
var bn = require('bn.js');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -322,6 +323,83 @@ function Block(data) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Block.prototype.verify = function() {
|
||||||
|
return this._verified = this._verified || bitcoindjs.verifyBlock(this.toHex());
|
||||||
|
};
|
||||||
|
|
||||||
|
Block.prototype.toBinary = function() {
|
||||||
|
return Block.toBinary(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
Block.toBinary = function(block, type) {
|
||||||
|
var p = [];
|
||||||
|
var off = 0;
|
||||||
|
|
||||||
|
// version
|
||||||
|
off += utils.writeU32(p, block.nVersion || 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);
|
||||||
|
|
||||||
|
if (type === 'merkle') {
|
||||||
|
// txn_count
|
||||||
|
off += utils.writeU32(p, block.txn_count, off);
|
||||||
|
// hash count
|
||||||
|
off += utils.varint(p, block.hash_count, off);
|
||||||
|
// hashes
|
||||||
|
block.hashes.forEach(function(hash) {
|
||||||
|
utils.toArray(hash, 'hex').forEach(function(ch) {
|
||||||
|
p[off++] = ch;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// flag count
|
||||||
|
off += utils.varint(p, block.flags.length, off);
|
||||||
|
// flags
|
||||||
|
block.flags.forEach(function(flag) {
|
||||||
|
p[off++] = flag;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// txn_count
|
||||||
|
off += utils.varint(p, block.tx.length, off);
|
||||||
|
// txs
|
||||||
|
block.tx.forEach(function(tx) {
|
||||||
|
tx = bitcoin.tx(tx);
|
||||||
|
tx.toHex();
|
||||||
|
utils.toArray(tx.hex, 'hex').forEach(function(ch) {
|
||||||
|
p[off++] = ch;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Buffer(p);
|
||||||
|
};
|
||||||
|
|
||||||
|
Block.prototype.toHex = function() {
|
||||||
|
return this._hex = this._hex || Block.toHex(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
Block.toHex = function(block) {
|
||||||
|
return Block.toBinary(block).toString('hex');
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transaction
|
* Transaction
|
||||||
*/
|
*/
|
||||||
@ -420,7 +498,7 @@ Transaction.prototype.toHex = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Transaction.toHex = function(tx) {
|
Transaction.toHex = function(tx) {
|
||||||
return new bn(Transaction.toBinary(tx)).toString('hex');
|
return Transaction.toBinary(tx).toString('hex');
|
||||||
};
|
};
|
||||||
|
|
||||||
Transaction.toBinary = function(tx) {
|
Transaction.toBinary = function(tx) {
|
||||||
@ -470,7 +548,7 @@ Transaction.toBinary = function(tx) {
|
|||||||
}
|
}
|
||||||
off += utils.writeU32(p, tx.nLockTime || tx.locktime, off);
|
off += utils.writeU32(p, tx.nLockTime || tx.locktime, off);
|
||||||
|
|
||||||
return p;
|
return new Buffer(p);
|
||||||
};
|
};
|
||||||
|
|
||||||
Transaction.prototype.toBinary = function() {
|
Transaction.prototype.toBinary = function() {
|
||||||
@ -644,6 +722,48 @@ utils.copy = function copy(src, dst, off, force) {
|
|||||||
return i;
|
return i;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function toArray(msg, enc) {
|
||||||
|
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() {};
|
utils.NOOP = function() {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -126,6 +126,7 @@ NAN_METHOD(GetTx);
|
|||||||
NAN_METHOD(PollBlocks);
|
NAN_METHOD(PollBlocks);
|
||||||
NAN_METHOD(PollMempool);
|
NAN_METHOD(PollMempool);
|
||||||
NAN_METHOD(BroadcastTx);
|
NAN_METHOD(BroadcastTx);
|
||||||
|
NAN_METHOD(VerifyBlock);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
async_start_node_work(uv_work_t *req);
|
async_start_node_work(uv_work_t *req);
|
||||||
@ -636,7 +637,7 @@ async_get_block_after(uv_work_t *req) {
|
|||||||
NAN_METHOD(GetTx) {
|
NAN_METHOD(GetTx) {
|
||||||
NanScope();
|
NanScope();
|
||||||
|
|
||||||
if (args.Length() < 2
|
if (args.Length() < 3
|
||||||
|| !args[0]->IsString()
|
|| !args[0]->IsString()
|
||||||
|| !args[1]->IsString()
|
|| !args[1]->IsString()
|
||||||
|| !args[2]->IsFunction()) {
|
|| !args[2]->IsFunction()) {
|
||||||
@ -1084,6 +1085,32 @@ async_broadcast_tx_after(uv_work_t *req) {
|
|||||||
delete req;
|
delete req;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VerifyBlock
|
||||||
|
*/
|
||||||
|
|
||||||
|
NAN_METHOD(VerifyBlock) {
|
||||||
|
NanScope();
|
||||||
|
|
||||||
|
if (args.Length() < 1 || !args[0]->IsString()) {
|
||||||
|
return NanThrowError(
|
||||||
|
"Usage: bitcoindjs.verifyBlock(blockHex)");
|
||||||
|
}
|
||||||
|
|
||||||
|
String::Utf8Value blockHex_(args[0]->ToString());
|
||||||
|
std::string blockHex = std::string(*blockHex_);
|
||||||
|
|
||||||
|
CBlock block;
|
||||||
|
CDataStream ssData(ParseHex(blockHex), SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
CTransaction tx;
|
||||||
|
ssData >> block;
|
||||||
|
|
||||||
|
CValidationState state;
|
||||||
|
bool valid = CheckBlock(block, state);
|
||||||
|
|
||||||
|
NanReturnValue(NanNew<Boolean>(valid));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conversions
|
* Conversions
|
||||||
*/
|
*/
|
||||||
@ -1315,6 +1342,7 @@ init(Handle<Object> target) {
|
|||||||
NODE_SET_METHOD(target, "pollBlocks", PollBlocks);
|
NODE_SET_METHOD(target, "pollBlocks", PollBlocks);
|
||||||
NODE_SET_METHOD(target, "pollMempool", PollMempool);
|
NODE_SET_METHOD(target, "pollMempool", PollMempool);
|
||||||
NODE_SET_METHOD(target, "broadcastTx", BroadcastTx);
|
NODE_SET_METHOD(target, "broadcastTx", BroadcastTx);
|
||||||
|
NODE_SET_METHOD(target, "verifyBlock", VerifyBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
NODE_MODULE(bitcoindjs, init)
|
NODE_MODULE(bitcoindjs, init)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user