Pradyuman's Blog

Pradyuman's Blog

Getting started with Bcoin (JavaScript Implementation of Full Node)

Getting started with Bcoin (JavaScript Implementation of Full Node)

A Beginner's Guide

Subscribe to my newsletter and never miss my upcoming articles

In this article, we will walk through "how to install and run a full node of Bitcoin using Bcoin."

We will create a wallet, send some coins and mine some blocks in regtest mode. So, let's start.

Introduction

The Bitcoin blockchain is designed as a decentralised P2P network where nobody owns or controls Bitcoin, and everyone can participate. A full node is a program that fully validates transactions and blocks. By running a Bitcoin full node, you are supporting the Bitcoin network to become more decentralised and fostering the growth of Bitcoin.

What is Bcoin?

'Bcoin' is an alternative implementation of Bitcoin protocol built with Javascript. A full node can be used for full blockchain validation and is aware of all known consensus rules. It is easier to use, faster to learn and more well-documented than competing implementations.

Installation

Bcoin is meant to be installed via Git for security purposes, as there are security issues when installing via npm.

Installing via Git

$ mkdir Bcoin && cd Bcoin
$ git clone https://github.com/bcoin-org/bcoin
$ cd bcoin

You can also verify signatures using:

$ git log --show-signature
<press q to exit signature log>

Public key fingerprints needed for the verification are available here.

Build and install globally with npm:

$ npm rebuild
$ npm install --global

In Nodejs projects, it's common to use npm install, which will fetch all the dependencies mentioned in the dependency tree. We are worried about npm as a single central point of failure and how the downloaded source code can be verified. (there have been dependency attacks on Nodejs projects before) So it's a bit strange but what we do now in bcoin is COMMIT the node_modules directory directly to the bcoin main repository. Because of this, the npm install command is not necessary now. npm rebuild still is, though, because what that does is compile the native source code (code written in C/C++ in bcrypto and level DB) for the operating system in use.

Run the test locally

So, what are these tests?

The tests are used for several things:

  1. Preventing regression (if a contributor opens a pull request that breaks a test, there is something wrong with their code that we will likely NOT want to merge)
  2. Documentation. I know this one seems funny, but sometimes the best way to understand a module is to look at the test. For example, if you read through, you should get a great overview of how to encode and decode Bitcoin addresses using bcoin.

From inside the Bcoin repo directory, Run

$ npm run test

or you can run a single test also

$ npm run test-file test/address-test.js

Now, we are ready to run our bcoin full node.

Starting up your first bcoin node

If bcoin is installed globally, bcoin should be in your PATH. If not, the bcoin bootstrap script resides in /path/to/bcoin/bin/bcoin. We will be running the full node in regtest mode.

$ bcoin --network=regtest

This will start a bcoin full node in a local test mode with no peers and 0-difficulty mining. The bcoinfull node will be launched with default options by reading through the configuration guide above, and you can see what other settings are available.

Now in the second terminal, use the bcoin-cli tool to get node info.

$ bcoin-cli --network=regtest info

You can also set an environment variable, and then you don't need to pass --network=regtest to every command:

$ export BCOIN_NETWORK=regtest

Now you can run the same command without using --network=regetest

$ bcoin-cli info

Playing with the wallet

By default, the Bcoin software runs a wallet, and that wallet is initialized on the first launch. The wallet is called primary and has one account called default.

Bcoin uses BIP44 for its wallet structure, and Bcoin also uses BIP39 seed phrases for its wallets.

Get your wallet's seed phrase

$ bwallet-cli master --id=primary

This command will return a JSON containing information about your wallet master key.

{
  "encrypted": false,
  "key": {
    "xprivkey": "tprv8ZgxMBicQKsPfNKy1Wf9EV1cTmz1Cmm6MVrvYdgcR6Hf8sEDUAzhnnoiVbw5jejp4EZWXynQEJhB62oSfANpHRAJqfiZarh1gVMowcJZ2Mn"
  },
  "mnemonic": {
    "bits": 128,
    "language": "english",
    "entropy": "e35833c318d677945ec21efff032bb64",
    "phrase": "today screen valid coyote guess sketch kitchen duck zoo light put siege"
  }
}

Write down that seed phrase and keep it safe! If this were mainnet, that phrase is how you can backup and restore your wallet!

Get your wallet's current receive address

$ bwallet-cli --id=primary --account=default address

It will return a JSON response about your current receiving address.

{
  "name": "default",
  "account": 0,
  "branch": 0,
  "index": 3,
  "witness": false,
  "nested": false,
  "publicKey": "03af169e5a186bbd7b380cb4553c72af243e18f243785b1597f192bbedd4a94fc3",
  "script": null,
  "program": null,
  "type": "pubkeyhash",
  "address": "n2eoT9D8txT5ZymDvCFPA8PHs2CmTV6oJT"
}

Now you have a receiving address, so we can mine some dummy blocks in the current (regtest) network to fund our wallet.

$ bcoin-cli rpc generatetoaddress 10 n2eoT9D8txT5ZymDvCFPA8PHs2CmTV6oJT

this command will mine 10 blocks in the regtest network with the address as your coinbase address. Now we can check our wallet balance.

Check your wallet balance

$ bwallet-cli --id=primary balance --account=default

it will return a JSON response with your account balance

{
  "account": 0,
  "tx": 307,
  "coin": 287,
  "unconfirmed": 1122500000000,
  "confirmed": 1122500000000
}

Now let's create a second wallet, one that uses Segregated Witness. A brief explanation of this wallet type is here but what is more valuable is the list of BIPs ( 141, 144 , 143, and 173) that describe all the technical protocol upgrades.

Creating segwit wallet

You can name this wallet whatever you want (here we are naming it test1).

$ bwallet-cli mkwallet test1 --witness=true

it will return a JSON response with details of your new wallet,

{
  "network": "regtest",
  "wid": 11,
  "id": "test1",
  "watchOnly": false,
  "accountDepth": 1,
  "token": "489d43e398dad34e69653e5edb5cb39b6d55be3364753c07d084d4b3d0292af7",
  "tokenDepth": 0,
  "master": {
    "encrypted": true,
    "until": 1571763677,
    "iv": "4e24f2a5908e20da0b8ba3e88dcda272",
    "algorithm": "pbkdf2",
    "n": 50000,
    "r": 0,
    "p": 0
  },
  "balance": {
    "tx": 0,
    "coin": 0,
    "unconfirmed": 0,
    "confirmed": 0
  }
}

Getting address for this new wallet,

$ bwallet-cli --id=test1 --account=default address

Now, we have our new wallet address, Let's send some coins from our first wallet to the second wallet.

Sending money

$ bwallet-cli send --id=primary --value=1000 --address=<your segwit wallet address>

Now, check the balance of our segwit wallet.

$ bwallet-cli --id=test1 balance

it shows a JSONresponse,

{
  "account": -1,
  "tx": 1,
  "coin": 1,
  "unconfirmed": 100000000000,
  "confirmed": 0
}

So, we have created two wallets and also sent some regtest coins from one wallet to another, we also mined some regtest blocks.

Thanks for the reading.

References

This post was written at Summer of Bitcoin 2021. Here is the list of references I used.

  1. Bcoin Api Docs
  2. Bcoin github page.

Special thanks to Matthew Zipkin for being an amazing mentor.

 
Share this