Understanding Btcd: Part 1 - BTCD Overview
The Whitepaper of Bitcoin cover some basic implements and design aspects of Bitcoin but to deeply understand how a Bitcoin client works is another level of studies and practices.
I myself heard of Bitcoin in late 2016 and began to dive into Bitcoin source code and tutorial to get more understanding of how it works since. One of the great books I’ve read is “Mastering Bitcoin” by Andreas Antonopoulos. That’s a great resource for someone want to technically understand Bitcoin and I highly recommend it.
The original Bitcoin Client is Bitcoin Core (https://github.com/bitcoin/bitcoin), which is written in C++, by Satoshi Nakamoto and now having contributed by BlockStream Developers. This is the most trusted client and has a leading role in most development of Bitcoin. But C++ is somewhat hard and complicated to compile and read. And I prefer Golang for this purpose. Golang is very small, simple, and minimalist.
And luckily we have BTCD, a full node bitcoin client written in Golang. This series of posts will cover some implement of Bitcoin in BTCD, help you understand how a Bitcoin client works and how multiple parts of Bitcoin components works together.
BTCD Components
A Bitcoin full node maintains the blockchain and helps validate and relay transactions. But how does it do that? In a smaller scale, what are those small jobs a full node need to do?
Basically, when a node starts, it has to connect to external peers. Communication now is done on over TCP, through a JSON-RPC interface. Then the node begins to send messages to other peers to propagate transactions and blocks. Btcd uses leveldb as database and flat file for block storage. Before each block and transaction got accepted, the client must verify the validity of each one. This validation process needs to go through Hashing and Elliptic Curve Digital Signature Algorithm to verify data. Finally, transactions and blocks are now saved in this database.
To do all these works, btcd client would have these components:
-
btcec: This package implements elliptic curve cryptography needed for working with Bitcoin. As you already knew, public and private key are derived from this cryptography algorithm. More than that, the signing and verify signatures of unspent transaction output would rely on this.
-
addrmgr: This package keeps track of connecting nodes. These nodes come and go and need to be stored, also removed when offline or behaving maliciously.
-
blockchain: This package implements bitcoin block handling and selection rules. A block is allowed into the blockchain or not must go through this.
-
btcjson: This package helps marshaling bitcoin JSON-RPC requests and responses.
-
chaincfg: Chain configuration, save many parameters specific for Bitcoin network. This package help bitcoin client know where it starts (mainnet or testnet), what is the genesis block, DNS Seeds, Checkpoints,…
-
cmd: Provides some of utility command that runs separately with btcd. Including bootstrap the blockchain, find checkpoint candidates, generate certificates for rpc client.
-
connmgr: Manage general connection strategy, such as number of outbound connections, banning, limiting max connection,…
-
database: This package provides storage for blocks, transactions and other metadata.
-
mempool: Provides an in-memory pool of fully validated transactions that ready to include in the new block.
-
netsync: Manage the block syncing operation. It performs initial block download, keeps the blockchain and mempool up to date, also broadcast new block added to the chain.
-
peer: This package provides the fundamental primitives necessary to speak Bitcoin wired protocol. It covers duplex read and write, handshake, message queueing and batching, …
-
rpcclient: This packet implements WebSocket-enabled Bitcoin JSON-RPC API, which helps to communicate with any other Bitcoin client.
-
txscript: Implements the bitcoin transaction scripts language, use for validating bitcoin transaction.
-
wire: Implements bitcoin wire protocol. All encoding and decoding of bitcoin messages are handled by this package.
The btcd documentation also covered all above package and deeper into their method at this repo: https://github.com/btcsuite/btcd. You can check out and start diving in.
Building btcd
-
If you are familiar with Go, it is simple enough:
$ go get -u github.com/Masterminds/glide $ git clone https://github.com/btcsuite/btcd $GOPATH/src/github.com/btcsuite/btcd $ cd $GOPATH/src/github.com/btcsuite/btcd $ glide install $ go install . ./cmd/...
-
btcd (and utilities) will now be installed in $GOPATH/bin
Start btcd with Simnet
For testing purpose, btcd provides a simulation network (–simnet), with low difficulty and mining is really fast.
This Simnet is running in a private network, which means peer and node discovery are all disabled. All chain and addresses are unique to real Bitcoin specification, for example a standard address would be start with uppercase ‘S’. So if you want to use btcwallet with Simnet, you also have to specify –simnet flag with it.
-
Start btcd on simnet:
$ btcd --simnet --rpcuser=youruser --rpcpass=SomeDecentp4ssw0rd
-
Create a new simnet wallet:
$ btcwallet --simnet --create
-
Start btcwallet on simnet:
$ btcwallet --simnet --username=youruser --password=SomeDecentp4ssw0rd
-
Create a new simnet bitcoin address:
$ btcctl --simnet --wallet --rpcuser=youruser --rpcpass=SomeDecentp4ssw0rd getnewaddress
-
Restart btcd with the mining address we’ve just generated:
$ btcd --simnet --rpcuser=youruser --rpcpass=SomeDecentp4ssw0rd --miningaddr=S....
-
Instruct btcd to generate enough initial blocks for the first coinbase to mature:
$ btcctl --simnet --rpcuser=youruser --rpcpass=SomeDecentp4ssw0rd generate 100
-
Check the wallet balance to ensure the coins are available:
$ btcctl --simnet --wallet --rpcuser=youruser --rpcpass=SomeDecentp4ssw0rd getbalance
Next tutorials in this series will cover details implements of these in btcd. Go through each package inside btcd, the most important functions will be highlighted and further discussed.