Bitzuma

An Introduction to Bcoin

By Rich Apodaca | Updated

Bitcoin Core is widely-regarded as the reference protocol implementation. However, its primary purpose is to control nodes. As such, this software doesn’t always work well as a tool for developers building block chain applications or learning about the Bitcoin protocol. This article introduces an alternative that can increase your productivity.

Bcoin

Bcoin is an implementation of the Bitcoin protocol written in JavaScript. First released in 2014 by Fedor Indutny as an in-browser SPV wallet, bcoin has since been extended by Christopher Jeffrey at Purse.io. Bcoin now encompasses the full Bitcoin protocol specification, can be run as a full node, and has even been used to mine a block on mainnet. The ubiquity of JavaScript runtime environments means that bcoin can power a full or SPV node deployed from a browser or server.

Bcoin. Lead developer Christopher Jeffrey (JJ) explains the role of alternative node implementations and bcoin in particular.

On Alternative Node Implementations

The idea of creating alternative node implementations isn’t new. In 2010, Satoshi Nakamoto voiced concerns about the idea:

I don’t believe a second, compatible implementation of Bitcoin will ever be a good idea. So much of the design depends on all nodes getting exactly identical results in lockstep that a second implementation would be a menace to the network. The MIT license is compatible with all other licenses and commercial uses, so there is no need to rewrite it from a licensing standpoint.

He later refined his position, which appears to reflect the resource constraints of a fledgeling open source project:

A second version would be a massive development and maintenance hassle for me. It’s hard enough maintaining backward compatibility while upgrading the network without a second version locking things in. If the second version screwed up, the user experience would reflect badly on both, although it would at least reinforce to users the importance of staying with the official version. If someone was getting ready to fork a second version, I would have to air a lot of disclaimers about the risks of using a minority version. This is a design where the majority version wins if there’s any disagreement, and that can be pretty ugly for the minority version and I’d rather not go into it, and I don’t have to as long as there’s only one version.

One argument in favor of alternative node implementations is, ironically the same one often used against: security. A single implementation defect can bring down a homogeneous network. A heterogeneous network can, in contrast, continue running regardless of the hidden flaws in a particular implementation. Chris Jeffry demonstrated this point by showing how Bitcoin Core nodes could be shut down remotely. Although Jeffry’s approach to disclosure was criticized, the point remains that as late as 2017 an exploitable, critical implementation bug existed in Bitcoin Core.

Proponents of diversity also note that Bitcoin Core itself has undergone dozens of revisions. At any point in time, many of these previous version are still running. Each revision of Bitcoin Core introduces the risk of a chain-splitting consensus bug, exactly the condition that alternative node implementations are accused of promoting.

User Agents
User Agents. “Satoshi” nodes run Bitcoin Core, which has undergone numerous revisions. Many of these older revisions are still used today.

Whether considered a menace or prudent diversification, alternative node implementations have been running on mainnet for years. Examples include:

The most important reason for considering alternative node implementations is the unique features they offer. One of bcoin’s most useful features is modularity. This allows bcoin components to be re-used in a variety of context, as this and future posts will show.

Resources

Three main resources host relevant information about bcoin:

As an NPM package, bcoin can be installed either globally or locally. Global installation allows universal access to the bcoin binary and is useful for running a full node. Local installation allows convenient access to bcoin’s components for use in software development.

Running Bcoin as a Full Node

Bcoin can be run as a full node

$ npm install -g bcoin --production

where the -g flag makes bcoin available anywhere on your file system and the --production flag strips developer dependencies.

After installation, bcoin can be run from the command line.

$ bcoin --prefix {path}

where {path} is the path to bcoin’s data storage directory.

A bcoin node can also be established on testnet:

$ bcoin --network=testnet --prefix {path}

The --daemon flag will start bcoin as a daemon, running in the background until stopped. Like Bitcoin Core, bcoin supports communication through a JSON-RPC interface.

In my experience, sync time for a bcoin node compares well with that of a Bitcoin Core node. Expect a few hours for testnet and 2-4 days for mainnet, depending on the speed of your CPU and hard drive.

Using Bcoin as a Library

Bcoin’s most interesting applications use it as a library. To demonstrate, this section will set up a new Node.js project that will read the input script of the Genesis Block’s coinbase transaction.

Begin by creating a project repository.

$ mkdir test && cd test
$ npm init
$ npm install bcoin --save

The following script will create an in-memory mainnet chain store and from it read the Genesis Block.

'use strict';

const bcoin = require('bcoin').set('main');

let chain = new bcoin.chain({ db: 'memory' });

(async function () {
  await chain.open();

  let block = await chain.db.getBlock(0);

  // iterate over each input script opcode and print it
  for (let tx of block.txs) {
    for (let input of tx.inputs) {
      for (let opcode of input.script.toArray()) {
        console.log(opcode);
      }
    }

    // print Satoshi's message
    console.log(tx.inputs[0].script.toArray()[2].data.toString('utf8'))
  }
})();

The output from this script yields three opcodes. The last line decodes the buffer encoded by the last opcode.

Opcode { value: 4, data: <Buffer ff ff 00 1d> }
Opcode { value: 1, data: <Buffer 04> }
Opcode {
  value: 69,
  data: <Buffer 54 68 65 20 54 69 6d 65 73 20 30 33 2f 4a 61 6e 2f 32 30 30 39 20 43 68 61 6e 63 65 6c 6c 6f 72 20 6f 6e 20 62 72 69 6e 6b 20 6f 66 20 73 65 63 6f 6e ... > }
The Times 03/Jan/2009 Chancellor on brink of second bailout for banks

Notice that two opcodes precede the data push containing Satoshi’s famous “Chancellor” message. Future posts will explore this curious behavior and its implications using bcoin example code.

Conclusions

Bcoin is a well-documented and complete Bitcoin node implementation written in JavaScript. It can be used either as a standalone node, or more interestingly, as a suite of modular components. Future posts will use bcoin’s unique features in a variety of contexts.