Go to file
Braydon Fuller bbc421a31e Migrate chainlib functionality into bitcore-node. 2015-08-26 17:24:10 -04:00
benchmarks Merge pull request #101 from braydonf/blkbench 2015-08-04 16:42:59 -04:00
bin Include more options and fallback to default config with start command 2015-08-24 18:57:50 -04:00
cache Cache strategy changes 2015-08-05 16:29:54 -04:00
cli CLI Fixes 2015-08-26 13:19:02 -04:00
etc Removed signal handlers from bitcoind. 2015-08-24 13:29:42 -04:00
example changes for BWS integration 2015-08-14 11:15:07 -04:00
integration Migrate chainlib functionality into bitcore-node. 2015-08-26 17:24:10 -04:00
lib Migrate chainlib functionality into bitcore-node. 2015-08-26 17:24:10 -04:00
src Removed signal handlers from bitcoind. 2015-08-24 13:29:42 -04:00
test Migrate chainlib functionality into bitcore-node. 2015-08-26 17:24:10 -04:00
.gitignore Added files to gitignore for libbitcoind and also using this for npm. 2015-08-10 15:30:33 -04:00
.jshintrc Cleanup configuration options 2015-07-21 11:16:12 -04:00
.travis.yml Added node reorg integration regtest 2015-08-24 13:59:33 -04:00
LICENSE Updated the patch for a better version of LDFLAGS. 2015-06-24 17:06:27 -04:00
PATCH_VERSION 1. Updated patch for v0.11.0 2015-07-13 16:34:29 -04:00
README.md Update README with the correct links. 2015-08-25 14:02:28 -04:00
RELEASE.md Include `lastBuild` in release process notes. 2015-08-25 14:00:59 -04:00
binding.gyp Added CFLAGS for the bindings so that they know that the wallet is compiled in. 2015-08-19 16:33:01 -04:00
index.js Migrate chainlib functionality into bitcore-node. 2015-08-26 17:24:10 -04:00
package.json Migrate chainlib functionality into bitcore-node. 2015-08-26 17:24:10 -04:00

README.md

Bitcore Node

A Node.js module that adds a native interface to Bitcoin Core for querying information about the Bitcoin blockchain. Bindings are linked to Bitcoin Core compiled as a static library.

Install

Here is how you can you install and start your node:

npm install -g bitcore-node@0.2.0-beta.4
bitcore-node start

Note: For your convenience, we distribute binaries for x86_64 Linux and x86_64 Mac OS X. Upon npm install, the binaries for your platform will be downloaded. If you want to compile the project yourself, then please see the Build & Install for full detailed instructions to build the project from source.

Configuration

Bitcore Node includes a Command Line Interface (CLI) for managing, configuring and interfacing with your Bitcore Node. At the minimum, your node can function with all of the features from Bitcoin Core running as a full node. However you can enable additional features to make your node more useful such as exposing new APIs, adding new indexes for addresses, running a block explorer and custom modules.

bitcore-node create -d <bitcoin-data-dir> mynode "My Node"
cd mynode
bitcore-node add <module>
bitcore-node add https://github.com/yourname/helloworld

This will create a directory with configuration files for your node and install the necessary dependencies. If you're interested in developing a module, please see the Module Development Guide.

Build & Install

This includes a detailed instructions for compiling. There are two main parts of the build, compiling Bitcoin Core as a static library and the Node.js bindings.

Ubuntu 14.04 (Unix/Linux)

If git is not already installed, it can be installed by running:

sudo apt-get install git
git config --global user.email "you@example.com"
git config --global user.name "Your Name"

If Node.js v0.12 isn't installed, it can be installed using "nvm", it can be done by following the installation script at https://github.com/creationix/nvm#install-script and then install version v0.12

nvm install v0.12

To build Bitcoin Core and bindings development packages are needed:

sudo apt-get install build-essential libtool autotools-dev automake autoconf pkg-config libssl-dev

Clone the bitcore-node repository locally:

git clone https://github.com/bitpay/bitcore-node.git
cd bitcore-node

And finally run the build which will take several minutes. A script in the "bin" directory will download Bitcoin Core v0.11, apply a patch (see more info below), and compile the static library and Node.js bindings. You can start this by running:

npm install

Once everything is built, you can run bitcore-node via:

npm start

This will then start the syncing process for Bitcoin Core and the extended capabilities as provided by the built-in Address Module (details below).

Fedora

Later versions of Fedora (>= 22) should also work with this project. The directions for Ubuntu should generally work except the installation of system utilities and libraries is a bit different. Git is already installed and ready for use without installation.

yum install libtool automake autoconf pkgconfig openssl make gcc gcc-c++ kernel-devel openssl-devel.x86_64 patch

Mac OS X Yosemite

If Xcode is not already installed, it can be installed via the Mac App Store (will take several minutes). XCode includes "Clang", "git" and other build tools. Once Xcode is installed, you'll then need to install "xcode-select" via running in a terminal and following the prompts:

xcode-select --install

If "Homebrew" is not yet installed, it's needed to install "autoconf" and others. You can install it using the script at http://brew.sh and following the directions at https://github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/Installation.md And then run in a terminal:

brew install autoconf automake libtool openssl pkg-config

If Node.js v0.12 and associated commands "node", "npm" and "nvm" are not already installed, you can use "nvm" by running the script at https://github.com/creationix/nvm#install-script And then run this command to install Node.js v0.12

nvm install v0.12

Clone the bitcore-node repository locally:

git clone https://github.com/bitpay/bitcore-node.git
cd bitcore-node

And finally run the build which will take several minutes. A script in the "bin" directory will download Bitcoin Core v0.11, apply a patch (see more info below), and compile the static library and Node.js bindings. You can start this by running:

npm install

Once everything is built, you can run bitcore-node via:

npm start

This will then start the syncing process for Bitcoin Core and the extended capabilities as provided by the built-in Address Module (details below).

Development & Testing

To run all of the JavaScript tests:

npm run test

To run tests against the bindings, as defined in bindings.gyp the regtest feature of Bitcoin Core is used, and to enable this feature we currently need to build with the wallet enabled (not a part of the regular build). To do this, export an environment variable and recompile:

export BITCORENODE_ENV=test
npm run build

If you do not already have mocha installed:

npm install mocha -g

To run the integration tests:

mocha -R spec integration/regtest.js

If any changes have been made to the bindings in the "src" directory, manually compile the Node.js bindings, as defined in bindings.gyp, you can run (-d for debug):

$ node-gyp -d rebuild

Note: node-gyp can be installed with npm install node-gyp -g

To be able to debug you'll need to have gdb and node compiled for debugging with gdb using --gdb (sometimes called node_g), and you can then run:

$ gdb --args node examples/node.js

To run mocha from within gdb (notice _mocha and not mocha so that the tests run in the same process):

$ gdb --args node /path/to/_mocha -R spec integration/regtest.js

To run the benchmarks:

$ cd benchmarks
$ node index.js

Static Library Patch

To provide native bindings to JavaScript (or any other language for that matter), Bitcoin code, itself, must be linkable. Currently, Bitcoin Core provides a JSON RPC interface to bitcoind as well as a shared library for script validation (and hopefully more) called libbitcoinconsensus. There is a node module, node-libbitcoinconsensus, that exposes these methods. While these interfaces are useful for several use cases, there are additional use cases that are not fulfilled, and being able to implement customized interfaces is necessary. To be able to do this a few simple changes need to be made to Bitcoin Core to compile as a static library.

The patch is located at etc/bitcoin.patch and adds a configure option --enable-daemonlib to compile all object files with -fPIC (Position Independent Code - needed to create a shared object), exposes leveldb variables and objects, exposes the threadpool to the bindings, and conditionally includes the main function.

Every effort will be made to ensure that this patch stays up-to-date with the latest release of Bitcoin. At the very least, this project began supporting Bitcoin Core v0.11.

Example Usage


var BitcoinNode = require('bitcore-node').Node;

var configuration = {
  datadir: '~/.bitcoin',
  network: 'testnet'
};

var node = new BitcoinNode(configuration);

node.on('ready', function() {
  console.log('Bitcoin Node Ready');
});

node.on('error', function(err) {
  console.error(err);
});

node.chain.on('addblock', function(block) {
  console.log('New Best Tip:', block.hash);
});

API Documentation

Get Unspent Outputs

var address = '15vkcKf7gB23wLAnZLmbVuMiiVDc1Nm4a2';
var includeMempool = true;
node.getUnspentOutputs(address, includeMempool, function(err, unspentOutputs) {
  //...
});

View Balances

var address = '15vkcKf7gB23wLAnZLmbVuMiiVDc1Nm4a2';
var includeMempool = true;
node.getBalance(address, includeMempool, function(err, balance) {
  //...
});

Get Outputs

var address = '15vkcKf7gB23wLAnZLmbVuMiiVDc1Nm4a2';
var includeMempool = true;
node.getOutputs(address, includeMempool, function(err, outputs) {
  //...
});

Get Transaction

var txid = 'c349b124b820fe6e32136c30e99f6c4f115fce4d750838edf0c46d3cb4d7281e';
var includeMempool = true;
node.getTransaction(txid, includeMempool, function(err, transaction) {
  //...
});

Get Block

var blockHash = '00000000d17332a156a807b25bc5a2e041d2c730628ceb77e75841056082a2c2';
node.getBlock(blockHash, function(err, block) {
  //...
});

You can log output from the daemon using:

$ tail -f ~/.bitcoin/debug.log

^C (SIGINT) will call StartShutdown() in bitcoind on the node thread pool.

Modules

Bitcore Node has a module system where additional information can be indexed and queried from the blockchain. One built-in module is the address module which exposes the API methods for getting balances and outputs.

Writing a Module

A new module can be created by inheriting from Node.Module, implementing the methods blockHandler(), getAPIMethods(), getPublishEvents() and any additional methods for querying the data. Here is an example:

var inherits = require('util').inherits;
var Node = require('bitcore-node').Node;

var MyModule = function(options) {
  Node.Module.call(this, options);
};

inherits(MyModule, Node.Module);

/**
 * blockHandler
 * @param {Block} block - the block being added or removed from the chain
 * @param {Boolean} add - whether the block is being added or removed
 * @param {Function} callback - call with the leveldb database operations to perform
 */
MyModule.prototype.blockHandler = function(block, add, callback) {
  var transactions = this.db.getTransactionsFromBlock(block);
  // loop through transactions and outputs
  // call the callback with leveldb database operations
  var operations = [];
  if(add) {
    operations.push({
      type: 'put',
      key: 'key',
      value: 'value'
    });
  } else {
    operations.push({
      type: 'del',
      key: 'key'
    });
  }

  // If your function is not asynchronous, it is important to use setImmediate.
  setImmediate(function() {
    callback(null, operations);
  });
};

/**
 * the API methods to expose
 * @return {Array} return array of methods
 */
MyModule.prototype.getAPIMethods = function() {
  return [
    ['getData', this, this.getData, 1]
  ];
};

/**
 * the bus events available for subscription
 * @return {Array} array of events
 */
MyModule.prototype.getPublishEvents = function() {
  return [
    {
      name: 'custom',
      scope: this,
      subscribe: this.subscribeCustom,
      unsubscribe: this.unsubscribeCustom
    }
  ]
};

/**
 * Will keep track of event listeners to later publish and emit events.
 */
MyModule.prototype.subscribeCustom = function(emitter, param) {
  if(!this.subscriptions[param]) {
    this.subscriptions[param] = [];
  }
  this.subscriptions[param].push(emitter);
}

MyModule.prototype.getData = function(arg1, callback) {
  // You can query the data by reading from the leveldb store on db
  this.db.store.get(arg1, callback);
};

module.exports = MyModule;

The module can then be used when running a node:

var configuration = {
  datadir: process.env.BITCORENODE_DIR || '~/.bitcoin',
  db: {
    modules: [MyModule]
  }
};

var node = new Node(configuration);

node.on('ready', function() {
  node.getData('key', function(err, value) {
    console.log(err || value);
  });
});

Note that if you already have a bitcore-node database, and you want to query data from previous blocks in the blockchain, you will need to reindex. Reindexing right now means deleting your bitcore-node database and resyncing.

Daemon Documentation

  • daemon.start([options], [callback]) - Start the JavaScript Bitcoin node.
  • daemon.getBlock(blockHash|blockHeight, callback) - Get any block asynchronously by block hash or height as a node buffer.
  • daemon.isSpent(txid, outputIndex) - Returns a boolean if a txid and outputIndex is already spent.
  • daemon.getBlockIndex(blockHash) - Will return the block chain work and previous hash.
  • daemon.estimateFee(blocks) - Estimates the fees required to have a transaction included in the number of blocks specified as the first argument.
  • daemon.sendTransaction(transaction, allowAbsurdFees) - Will attempt to add a transaction to the mempool and broadcast to peers.
  • daemon.getTransaction(txid, queryMempool, callback) - Get any tx asynchronously by reading it from disk, with an argument to optionally not include the mempool.
  • daemon.getTransactionWithBlockInfo(txid, queryMempool, callback) - Similar to getTransaction but will also include the block timestamp and height.
  • daemon.getMempoolOutputs(address) - Will return an array of outputs that match an address from the mempool.
  • daemon.getInfo() - Basic information about the chain including total number of blocks.
  • daemon.isSynced() - Returns a boolean if the daemon is fully synced (not the initial block download)
  • daemon.syncPercentage() - Returns the current estimate of blockchain download as a percentage.
  • daemon.stop([callback]) - Stop the JavaScript bitcoin node safely, the callback will be called when bitcoind is closed. This will also be done automatically on process.exit. It also takes the bitcoind node off the libuv event loop. If the daemon object is the only thing on the event loop. Node will simply close.

License

Code released under the MIT license.

Copyright 2013-2015 BitPay, Inc.

  • bitcoin: Copyright (c) 2009-2015 Bitcoin Core Developers (MIT License)
  • bcoin (some code borrowed temporarily): Copyright Fedor Indutny, 2014.