Bitcoin Service

The Bitcoin Service is a Node.js interface to Bitcoin Core for querying information about the bitcoin block chain. It will manage starting and stopping bitcoind or connect to several running bitcoind processes. It uses a branch of a branch of Bitcoin Core with additional indexes for querying information about addresses and blocks. Results are cached for performance and there are several additional API methods added for common queries.

Configuration

The default configuration will include a "spawn" configuration in "bitcoind". This defines the location of the block chain database and the location of the bitcoind daemon executable. The below configuration points to a local clone of bitcoin, and will start bitcoind automatically with your Node.js application.

  "servicesConfig": {
    "bitcoind": {
      "spawn": {
        "datadir": "/home/bitcore/.bitcoin",
        "exec": "/home/bitcore/bitcoin/src/bitcoind"
      }
    }
  }

It's also possible to connect to separately managed bitcoind processes with round-robin quering, for example:

  "servicesConfig": {
    "bitcoind": {
      "connect": [
        {
          "rpchost": "127.0.0.1",
          "rpcport": 30521,
          "rpcuser": "bitcoin",
          "rpcpassword": "local321",
          "zmqpubrawtx": "tcp://127.0.0.1:30611"
        },
        {
          "rpchost": "127.0.0.1",
          "rpcport": 30522,
          "rpcuser": "bitcoin",
          "rpcpassword": "local321",
          "zmqpubrawtx": "tcp://127.0.0.1:30622"
        },
        {
          "rpchost": "127.0.0.1",
          "rpcport": 30523,
          "rpcuser": "bitcoin",
          "rpcpassword": "local321",
          "zmqpubrawtx": "tcp://127.0.0.1:30633"
        }
      ]
    }
  }

Note: For detailed example configuration see regtest/cluster.js

API Documentation

Methods are available by directly interfacing with the service:

node.services.bitcoind.<methodName>

Chain

Getting Latest Blocks

// gives the block hashes sorted from low to high within a range of timestamps
var high = 1460393372; // Mon Apr 11 2016 12:49:25 GMT-0400 (EDT)
var low = 1460306965; // Mon Apr 10 2016 12:49:25 GMT-0400 (EDT)
node.services.bitcoind.getBlockHashesByTimestamp(high, low, function(err, blockHashes) {
  //...
});

// get the current tip of the chain
node.services.bitcoind.getBestBlockHash(function(err, blockHash) {
  //...
})

Getting Synchronization and Node Status

// gives a boolean if the daemon is fully synced (not the initial block download)
node.services.bitcoind.isSynced(function(err, synced) {
  //...
})

// gives the current estimate of blockchain download as a percentage
node.services.bitcoind.syncPercentage(function(err, percent) {
  //...
});

// gives information about the chain including total number of blocks
node.services.bitcoind.getInfo(function(err, info) {
  //...
});

Generate Blocks

// will generate a block for the "regtest" network (development purposes)
var numberOfBlocks = 10;
node.services.bitcoind.generateBlock(numberOfBlocks, function(err, blockHashes) {
  //...
});

Blocks and Transactions

Getting Block Information

It's possible to query blocks by both block hash and by height. Blocks are given as Node.js Buffers and can be parsed via Bitcore:

var blockHeight = 0;
node.services.bitcoind.getRawBlock(blockHeight, function(err, blockBuffer) {
  if (err) {
    throw err;
  }
  var block = bitcore.Block.fromBuffer(blockBuffer);
  console.log(block);
};

// get a bitcore object of the block (as above)
node.services.bitcoind.getBlock(blockHash, function(err, block) {
  //...
};

// get only the block header and index (including chain work, height, and previous hash)
node.services.bitcoind.getBlockHeader(blockHeight, function(err, blockHeader) {
  //...
});

// get the block with a list of txids
node.services.bitcoind.getBlockOverview(blockHash, function(err, blockOverview) {
  //...
};

Retrieving and Sending Transactions

Get a transaction asynchronously by reading it from disk:

var txid = '7426c707d0e9705bdd8158e60983e37d0f5d63529086d6672b07d9238d5aa623';
node.services.bitcoind.getRawTransaction(txid, function(err, transactionBuffer) {
  if (err) {
    throw err;
  }
  var transaction = bitcore.Transaction().fromBuffer(transactionBuffer);
});

// get a bitcore object of the transaction (as above)
node.services.bitcoind.getTransaction(txid, function(err, transaction) {
  //...
});

// retrieve the transaction with input values, fees, spent and block info
node.services.bitcoind.getDetailedTransaction(txid, function(err, transaction) {
  //...
});

Send a transaction to the network:

var numberOfBlocks = 3;
node.services.bitcoind.estimateFee(numberOfBlocks, function(err, feesPerKilobyte) {
  //...
});

node.services.bitcoind.sendTransaction(transaction.serialize(), function(err, hash) {
  //...
});

Addresses

Get Unspent Outputs

One of the most common uses will be to retrieve unspent outputs necessary to create a transaction, here is how to get the unspent outputs for an address:

var address = 'mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW';
node.services.bitcoind.getAddressUnspentOutputs(address, options, function(err, unspentOutputs) {
  // see below
});

The unspentOutputs will have the format:

[
  {
    address: 'mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW',
    txid: '9d956c5d324a1c2b12133f3242deff264a9b9f61be701311373998681b8c1769',
    outputIndex: 1,
    height: 150,
    satoshis: 1000000000,
    script: '76a9140b2f0a0c31bfe0406b0ccc1381fdbe311946dadc88ac',
    confirmations: 3
  }
]

View Balances

var address = 'mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW';
node.services.bitcoind.getAddressBalance(address, options, function(err, balance) {
  // balance will be in satoshis with "received" and "balance"
});

View Address History

This method will give history of an address limited by a range of block heights by using the "start" and "end" arguments. The "start" value is the more recent, and greater, block height. The "end" value is the older, and lesser, block height. This feature is most useful for synchronization as previous history can be omitted. Furthermore for large ranges of block heights, results can be paginated by using the "from" and "to" arguments.

var addresses = ['mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW'];
var options = {
  start: 345000,
  end: 344000,
  queryMempool: true
};
node.services.bitcoind.getAddressHistory(addresses, options, function(err, history) {
  // see below
});

The history format will be:

{
  totalCount: 1, // The total number of items within "start" and "end"
  items: [
    {
      addresses: {
        'mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW': {
          inputIndexes: [],
          outputIndexes: [0]
        }
      },
      satoshis: 1000000000,
      tx: <detailed_transaction> // the same format as getDetailedTransaction
    }
  ]
}

View Address Summary

var address = 'mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW';
var options = {
  noTxList: false
};

node.services.bitcoind.getAddressSummary(address, options, function(err, summary) {
  // see below
});

The summary will have the format (values are in satoshis):

{
  totalReceived: 1000000000,
  totalSpent: 0,
  balance: 1000000000,
  unconfirmedBalance: 1000000000,
  appearances: 1,
  unconfirmedAppearances: 0,
  txids: [
    '3f7d13efe12e82f873f4d41f7e63bb64708fc4c942eb8c6822fa5bd7606adb00'
  ]
}

Notes:

  • totalReceived does not exclude change (the amount of satoshis originating from the same address)
  • unconfirmedBalance is the delta that the unconfirmed transactions have on the total balance (can be both positive and negative)
  • unconfirmedAppearances is the total number of unconfirmed transactions
  • appearances is the total confirmed transactions
  • txids Are sorted in block order with the most recent at the beginning. A maximum of 1000 (default) will be returned, the from and to options can be used to get further values.

Events

The Bitcoin Service exposes two events via the Bus, and there are a few events that can be directly registered:

node.services.bitcoind.on('tip', function(blockHash) {
  // a new block tip has been added, if there is a rapid update (with a second) this will not emit every tip update
});

node.services.bitcoind.on('tx', function(transactionBuffer) {
  // a new transaction has entered the mempool
});

node.services.bitcoind.on('block', function(blockHash) {
  // a new block has been added
});

For details on instantiating a bus for a node, see the Bus Documentation.

  • Name: bitcoind/rawtransaction
  • Name: bitcoind/hashblock
  • Name: bitcoind/addresstxid, Arguments: [address, address...]

Examples:

bus.subscribe('bitcoind/rawtransaction');
bus.subscribe('bitcoind/hashblock');
bus.subscribe('bitcoind/addresstxid', ['13FMwCYz3hUhwPcaWuD2M1U2KzfTtvLM89']);

bus.on('bitcoind/rawtransaction', function(transactionHex) {
  //...
});

bus.on('bitcoind/hashblock', function(blockhashHex) {
  //...
});

bus.on('bitcoind/addresstxid', function(data) {
  // data.address;
  // data.txid;
});

Bitcoin(options)

Provides a friendly event driven API to bitcoind in Node.js. Manages starting and stopping bitcoind as a child process for application support, as well as connecting to multiple bitcoind processes for server infrastructure. Results are cached in an LRU cache for improved performance and methods added for common queries.

Kind: global function

Param Type Description
options Object
options.node Node A reference to the node

bitcoin.getAPIMethods()

Called by Node to determine the available API methods.

Kind: instance method of Bitcoin

bitcoin.getPublishEvents()

Called by the Bus to determine the available events.

Kind: instance method of Bitcoin

bitcoin.unsubscribeAddressAll(name, emitter)

A helper function for the unsubscribe method to unsubscribe from all addresses.

Kind: instance method of Bitcoin

Param Type Description
name String The name of the event
emitter EventEmitter An instance of an event emitter

bitcoin.start(callback)

Called by Node to start the service

Kind: instance method of Bitcoin

Param Type
callback function

bitcoin.isSynced(callback)

Helper to determine the state of the database.

Kind: instance method of Bitcoin

Param Type
callback function

bitcoin.syncPercentage(callback)

Helper to determine the progress of the database.

Kind: instance method of Bitcoin

Param Type
callback function

bitcoin.getAddressBalance(addressArg, options, callback)

Will get the balance for an address or multiple addresses

Kind: instance method of Bitcoin

Param Type Description
addressArg String | Address | Array An address string, bitcore address, or array of addresses
options Object
callback function

bitcoin.getAddressUnspentOutputs(addressArg, options, callback)

Will get the unspent outputs for an address or multiple addresses

Kind: instance method of Bitcoin

Param Type Description
addressArg String | Address | Array An address string, bitcore address, or array of addresses
options Object
callback function

bitcoin.getAddressTxids(addressArg, options, callback)

Will get the txids for an address or multiple addresses

Kind: instance method of Bitcoin

Param Type Description
addressArg String | Address | Array An address string, bitcore address, or array of addresses
options Object
callback function

bitcoin._getAddressDetailedTransaction(txid, callback)

Will expand into a detailed transaction from a txid

Kind: instance method of Bitcoin

Param Type Description
txid Object A bitcoin transaction id
callback function

bitcoin.getAddressHistory(addressArg, options, callback)

Will detailed transaction history for an address or multiple addresses

Kind: instance method of Bitcoin

Param Type Description
addressArg String | Address | Array An address string, bitcore address, or array of addresses
options Object
callback function

bitcoin.getAddressSummary(addressArg, options, callback)

Will get the summary including txids and balance for an address or multiple addresses

Kind: instance method of Bitcoin

Param Type Description
addressArg String | Address | Array An address string, bitcore address, or array of addresses
options Object
callback function

bitcoin.getRawBlock(block, callback)

Will retrieve a block as a Node.js Buffer

Kind: instance method of Bitcoin

Param Type Description
block String | Number A block hash or block height number
callback function

bitcoin.getBlockOverview(block, callback)

Similar to getBlockHeader but will include a list of txids

Kind: instance method of Bitcoin

Param Type Description
block String | Number A block hash or block height number
callback function

bitcoin.getBlock(block, callback)

Will retrieve a block as a Bitcore object

Kind: instance method of Bitcoin

Param Type Description
block String | Number A block hash or block height number
callback function

bitcoin.getBlockHashesByTimestamp(high, low, callback)

Will retrieve an array of block hashes within a range of timestamps

Kind: instance method of Bitcoin

Param Type Description
high Number The more recent timestamp in seconds
low Number The older timestamp in seconds
callback function

bitcoin.getBlockHeader(block, callback)

Will return the block index information, the output will have the format: { hash: '0000000000000a817cd3a74aec2f2246b59eb2cbb1ad730213e6c4a1d68ec2f6', confirmations: 5, height: 828781, chainWork: '00000000000000000000000000000000000000000000000ad467352c93bc6a3b', prevHash: '0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9', nextHash: '00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8' version: 536870912, merkleRoot: '124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9', time: 1462979126, medianTime: 1462976771, nonce: 2981820714, bits: '1a13ca10', difficulty: 847779.0710240941, }

Kind: instance method of Bitcoin

Param Type Description
block String | Number A block hash or block height
callback function

bitcoin.estimateFee(blocks, callback)

Will estimate the fee per kilobyte.

Kind: instance method of Bitcoin

Param Type Description
blocks Number The number of blocks for the transaction to be confirmed.
callback function

bitcoin.sendTransaction(transaction, [options], callback)

Will add a transaction to the mempool and relay to connected peers

Kind: instance method of Bitcoin

Param Type Description
transaction String | Transaction The hex string of the transaction
[options] Object
[options.allowAbsurdFees] Boolean Enable large fees
callback function

bitcoin.getRawTransaction(txid, callback)

Will get a transaction as a Node.js Buffer. Results include the mempool.

Kind: instance method of Bitcoin

Param Type Description
txid String The transaction hash
callback function

bitcoin.getTransaction(txid, queryMempool, callback)

Will get a transaction as a Bitcore Transaction. Results include the mempool.

Kind: instance method of Bitcoin

Param Type Description
txid String The transaction hash
queryMempool Boolean Include the mempool
callback function

bitcoin.getDetailedTransaction(txid, callback)

Will get a detailed view of a transaction including addresses, amounts and fees.

Example result: { blockHash: '000000000000000002cd0ba6e8fae058747d2344929ed857a18d3484156c9250', height: 411462, blockTimestamp: 1463070382, version: 1, hash: 'de184cc227f6d1dc0316c7484aa68b58186a18f89d853bb2428b02040c394479', locktime: 411451, coinbase: true, inputs: [ { prevTxId: '3d003413c13eec3fa8ea1fe8bbff6f40718c66facffe2544d7516c9e2900cac2', outputIndex: 0, sequence: 123456789, script: [hexString], scriptAsm: [asmString], address: '1LCTmj15p7sSXv3jmrPfA6KGs6iuepBiiG', satoshis: 771146 } ], outputs: [ { satoshis: 811146, script: '76a914d2955017f4e3d6510c57b427cf45ae29c372c99088ac', scriptAsm: 'OP_DUP OP_HASH160 d2955017f4e3d6510c57b427cf45ae29c372c990 OP_EQUALVERIFY OP_CHECKSIG', address: '1LCTmj15p7sSXv3jmrPfA6KGs6iuepBiiG', spentTxId: '4316b98e7504073acd19308b4b8c9f4eeb5e811455c54c0ebfe276c0b1eb6315', spentIndex: 1, spentHeight: 100 } ], inputSatoshis: 771146, outputSatoshis: 811146, feeSatoshis: 40000 };

Kind: instance method of Bitcoin

Param Type Description
txid String The hex string of the transaction
callback function

bitcoin.getBestBlockHash(callback)

Will get the best block hash for the chain.

Kind: instance method of Bitcoin

Param Type
callback function

bitcoin.getSpentInfo(callback)

Will give the txid and inputIndex that spent an output

Kind: instance method of Bitcoin

Param Type
callback function

bitcoin.getInfo(callback)

This will return information about the database in the format: { version: 110000, protocolVersion: 70002, blocks: 151, timeOffset: 0, connections: 0, difficulty: 4.6565423739069247e-10, testnet: false, network: 'testnet' relayFee: 1000, errors: '' }

Kind: instance method of Bitcoin

Param Type
callback function

bitcoin.stop(callback)

Called by Node to stop the service.

Kind: instance method of Bitcoin

Param Type
callback function