Skip to content

Latest commit

 

History

History
275 lines (208 loc) · 9.17 KB

17_3_Accessing_Bitcoind_with_NodeJS.md

File metadata and controls

275 lines (208 loc) · 9.17 KB

18.3: Accessing Bitcoind with NodeJS

Set Up Node.js

BCRPC is built on node.js. Thus, you'll first need to install the node.js and npm (node package manager) packages for your system.

If you're using a Ubuntu machine, you can run the following commands to get a new version of node.js (as opposed to the horribly out-of-date version in the Ubuntu package system).

curl -sL https://deb.nodesource.com/setup_14.x | sudo bash -
sudo apt-get install -y nodejs
sudo npm install mocha -g

Test BCRPC

Clone the BCRPC package from GitHub and install its dependencies.

$ git clone https://github.com/dgarage/bcrpc.git
$ cd bcrpc
$ npm install

To test the BCRPC package, you must first set environmental variables for your rpcuser and rpcpassword. As noted in §12.1: Accessing Bitcoind with Curl, these come from ~/.bitcoin/bitcoin.conf. You must also set the RPC port to 18332 which should be correct for the standard testnet setup described in these documents.

$ export BITCOIND_USER=bitcoinrpc
$ export BITCOIND_PASS=d8340efbcd34e312044c8431c59c792c
$ export BITCOIND_PORT=18332

WARNING: Obviously, you'd never put set your password in an environmental variable in a production environment.

MAINNET VS TESTNET: The port would be 8332 for a mainnet setup.

You can now verify everything is working correctly:

$ npm test

> bcrpc@0.2.2 test /home/user1/bcrpc
> mocha tests.js

  BitcoinD
    ✓ is running

  bcrpc
    ✓ can get info

  2 passing (36ms)

Congratulations, you now have a Bitcoin-ready RPC wrapper for Node.js working with your Bitcoin setup.

Set Up BCRPC

Leave the BCRPC directory and create a new Node.js project with BCRPC installed via npm.

$ cd ..
$ mkdir myproject
$ cd myproject
$ npm init
  [continue with default options]
$ npm install bcrpc

In this myproject directory, create a file called server.js in which the JavaScript code can be executed. Enter the following at the top of the file to connect to your Bitcoin node:

const RpcAgent = require('bcrpc');
agent = new RpcAgent({port: 18332, user: 'bitcoinrpc', pass: 'd8340efbcd34e312044c8431c59c792c'});

Now we can start writing programs in JavaScript that access Bitcoind. You can use the same RPC commands you would usually use via bitcoin-cli, except they need to be in camelCase. For example, getblockhash would be getBlockHash instead.

Print the Newest Block

To print the newest block number along with its hash, we can first call getBlockCount, print it, then pass the block number to getBlockHash and then print the latest hash. Add this code to server.js:

agent.getBlockCount(function (err, blockCount) {
  if (err)
    throw Error(JSON.stringify(err));
  console.log(blockCount.result);
  agent.getBlockHash(blockCount.result, function (err, hash) {
    if (err)
      throw Error(JSON.stringify(err));
    console.log(hash.result);
  })
});

You can run it with $ node server.js. You should get an output similar to this:

1773373
0000000000000083d29c524d4cfc257adfab8fa9b6f0d207d1d0f1b63e1de11e

The BCRPC functions can accept inputs. For example, getBlockHash takes blockCount.result as an input. The result of the BCRPC functions is a JSON object containing information about any errors and the id of the request. When accessing our result, we add .result to the end of it to specify that we are interested in the actual result, not information about errors. This is what output of the above example would look like if we replaced console.log(blockCount.result); and console.log(hash.result); with console.log(blockCount); and console.log(hash);, respectively:

{ result: 1774686, error: null, id: null }
{
  result: '00000000000000d980c495a2b7addf09bb0a9c78b5b199c8e965ee54753fa5da',
  error: null,
  id: null
}

Look Up Your Wallet

You can also lookup your wallet and view your balance, transaction count et cetera:

agent.getWalletInfo(function (err, walletInfo) {
  if (err)
    throw Error(JSON.stringify(err));
  console.log(walletInfo.result);
});

When you run it, you should get an output similar to this:

{
  walletname: '',
  walletversion: 169900,
  balance: 0.0011,
  unconfirmed_balance: 0,
  immature_balance: 0,
  txcount: 2,
  keypoololdest: 1591844503,
  keypoolsize: 999,
  keypoolsize_hd_internal: 1000,
  paytxfee: 0,
  hdseedid: '6b9ccb7d96c45a3ca407a3f3b0e9b42501f05c49',
  private_keys_enabled: true
}

Instead of printing all the details associated with your wallet, you can print specific information such as your balance. Since a JSON object is being accessed, this can be done by changing the line console.log(walletInfo.result); to console.log(walletInfo.result.balance);:

0.0011

Create an Address

We can pass additional arguments to RPC commands as well. Here is an example for generating a new legacy address, with the -addresstype flag.

agent.getNewAddress('-addresstype', 'legacy', function (err, newAddress) {
  if (err)
    throw Error(JSON.stringify(err));
  console.log(newAddress.result);
});

Output:

mtGPcBvRPZFEHo2YX8un9qqPBydhG82uuZ

This example shows how we can use the same flags as bitcoin-cli in BCRPC. The example above would look like this from the command line:

$ bitcoin-cli getnewaddress -addresstype legacy
mtGPcBvRPZFEHo2YX8un9qqPBydhG82uuZ

In BCRPC getnewaddress is in camelCase (getNewAddress) and the that flags are normally separated by spaces are instead put in strings and separated by commas.

List transactions

We can list our previous transactions and view information about transactions such as amount and number of confirmations:

agent.listTransactions(function (err, transactions) {
  if (err)
    throw Error(JSON.stringify(err));
  console.log(transactions.result);
});

We can also examine a transaction based on its txid:

agent.getTransaction('1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df', function (err, transaction) {
  if (err)
    throw Error(JSON.stringify(err));
  console.log(transaction.result);
});

You should get an output similar to this:

{
  amount: 0.001,
  confirmations: 4776,
  blockhash: '000000006628870b0a8a66abea9cf0d4e815c491f079e3fa9e658a87b5dc863a',
  blockindex: 117,
  blocktime: 1591857418,
  txid: '1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df',
  walletconflicts: [],
  time: 1591857343,
  timereceived: 1591857343,
  'bip125-replaceable': 'no',
  details: [
    {
      address: 'mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha',
      category: 'receive',
      amount: 0.001,
      label: '',
      vout: 0
    }
  ],
  hex: '02000000000101e9e8c3bd057d54e73baadc60c166860163b0e7aa60cab33a03e89fb44321f8d5010000001716001435c2aa3fc09ea53c3e23925c5b2e93b9119b2568feffffff02a0860100000000001976a914600c8c6a4abb0a502ea4de01681fe4fa1ca7800688ac65ec1c000000000017a91425b920efb2fde1a0277d3df11d0fd7249e17cf8587024730440220403a863d312946aae3f3ef0a57206197bc67f71536fb5f4b9ca71a7e226b6dc50220329646cf786cfef79d60de3ef54f702ab1073694022f0618731902d926918c3e012103e6feac9d7a8ad1ac6b36fb4c91c1c9f7fff1e7f63f0340e5253a0e4478b7b13f41fd1a00'
}

Get Amount Received by an Address

A useful function when accepting Bitcoin is checking the received Bitcoin of a specific address in your wallet. For example, if you were running an online store accepting Bitcoin, for each payment from a customer, you would generate a new address (as we did with getNewAddress function), show that address to the customer, then check the balance of the address after some time, to make sure the correct amount has been received:

agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', function (err, addressInfo) {
  if (err)
    throw Error(JSON.stringify(err));
  console.log(addressInfo.result);
});

By default this functions checks the transactions that have been confirmed once, however we can increase this to a higher number such as 6:

agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', 6, function (err, addressInfo) {
  if (err)
    throw Error(JSON.stringify(err));
  console.log(addressInfo.result);
});

Output:

0.0011

Sending coins

We can send coins to an address using the sendToAddress function:

agent.sendToAddress('n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi', 0.00001, function(err, txid) {
  if (err)
    throw Error(JSON.stringify(err));
  console.log(txid.result);
});

This should print the txid of the transaction:

6172d60d154cd4bbb5b6adeaffa191866f3904dd3f525c7a079154aea906b723

We can also use the getTransaction function to view how many confirmations it has, what fee we paid, et cetera.

Summary: Accessing Bitcoind with Node

With BCRPC we can do all the commands available through bitcoin-cli, in JavaScript. The BCRPC README has some examples which use promises (the examples in this document use callbacks). The JavaScript behind it is short and readable. Based on these examples you should be able to incorporate Bitcoin in a Node.js project and do things like sending and receiving coins.