1. Introduction

libbitcoin is a Bitcoin library targeted towards high end use. The library places a heavy focus around asychronicity. This enables a big scope for future scalability as each component has its own thread pool. By increasing the number of threads for that component the library is able to scale outwards across CPU cores. This will be vital in the future as the demands of the Bitcoin network grow.

Another core design principle is libbitcoin is not a framework, but a toolkit. Frameworks hinder development during the latter stages of a development cycle, enforce one style of coding and do not work well with other frameworks. By contrast, we have gone to great pains to make libbitcoin function as an independent set of mutual components with no dependencies between them.

The approach we took to our threaded design is built not around the data, but around tasks. On a finer level: operations. libbitcoin is a toolkit library that uses the proactor design pattern. It implements the proactor pattern through the use of completion handlers like in boost::asio.

  • Scalability. The library should facilitate the development of applications that scale to thousands of concurrent operations.
  • Model concepts in an intuitive manner. The library models different subsystems of Bitcoin in a clear and intuitive manner. We choose abstractions that allow designing a wide range of applications that rely on Bitcoin.
  • Basis for further abstraction. The library should permit the development of other libraries that provide higher levels of abstraction. For example, implementations of the Bitcoin protocol in other networks such as Tor.
  • No blocking. No blocking ever occurs waiting for another thread to complete (except possibly on a low level within boost dispatches- but that is uncommon).
  • UNIX approach. The library attempts to provide small units of functionality that perform one single task. Our philosophy is to break down higher level functionality into small parts and to simply provide those parts. The cost is inconvenience. The benefit is flexibility.

1.1. Design

libbitcoin follows a few basic code design principles that quality does not necessarily increase with functionality. There is a point where less functionality is a preferable option in terms of practicality and usability.

  • Simplicity. It is more important for the implementation to be simple than the interface. Simplicity is the most important consideration in a design.
  • Correctness. The design should be correct in all aspects.
  • Consistency. The design must not be overly inconsistent. Consistency can be sacrificed for simplicity in some cases, but it is better to drop those parts of the design that deal with less common circumstances than to introduce either complexity or inconsistency in the implementation.
  • Completeness. The design must cover as many important situations as is practical. Completeness must be sacrificed whenever implementation simplicity is jeopardized.

Unix and C are examples of this design. Small building blocks that are flexible in how they combine together.

Generally the API focuses on implementation simplicity and only implements the bare neccessary functionality. Keep implementation simple and don’t pollute class interfaces. Instead composed operations wrap lower level class methods to simplify common operations.

threadpool pool(1);
network net(pool);
handshake shake(pool);
// ...
connect(shake, net, "localhost", 8333, handle_handshake);

Composed operations take the services they wrap as their primary arguments before their function parameters.

Classes do not implement more functionality than is neccessary.

1.1.1. Dependency Injection

Dependency injection is a software design pattern that allows removing hard-coded dependencies and making it possible to change them, whether at run-time or compile-time.

Instead of having your objects creating a dependency or asking a factory object to make one for them, you pass the needed dependencies into the constructor.

threadpool pool(1);
leveldb_blockchain chain(pool);
// The dependencies for transaction_pool are passed into its constructor.
// We could instead pass in a bdb_blockchain.
transaction_pool txpool(pool, chain);

1.2. The Zen of libbitcoin

Readability over speed.
Beauty over convenience.
Simplicity over complexity.
Architected, not hacked.
Flat, not nested.
Explicit, not implicit.
Errors should be loud.
Never is better than right now.
Now is better than never.
Be flexible and configurable.
Build houses from bricks, software from modules.

1.3. Examples

Each section comes with its own example code listing. These can be found in the examples/ directory of the source libbitcoin package.

  • priv.cpp generates new private keys, shows a Bitcoin address and sign or verify data using the private key.
  • determ.cpp shows working with deterministic wallets, generating both public and private keys.
  • initchain.cpp, initialize leveldb_blockchain by creating a blank new database and adding the genesis block at height 0.
  • display-last.cpp fetches and displays the last block in a blockchain database.
  • satoshiwords.cpp displays the genesis block message from Satoshi.
  • accept.cpp listens for connections on port 8333, displaying the version’s user agent.
  • connect.cpp connects to localhost on port 8333, and sends a single version message.
  • proto.cpp joins to the p2p Bitcoin network.
  • txrad.cpp implements a simple transaction radar.
  • fullnode.cpp is a full node Bitcoin implementation. Blocks and unconfirmed transactions are validated.

To run the examples invoke make in the examples/ directory.

$ cd examples/
$ make

Table Of Contents

Previous topic

The libbitcoin Tutorial

Next topic

2. Quickstart

This Page