ビットコインのソースコード構造

どうも。
代表的な暗号通貨であるビットコイン（以下、 Bitcoin）は、当初よりプロトコルの改良が続けられ、現在ではそのソースツリーは巨大なものになっています。
Bitcoinにバグ修正のPRをしてみたい場合でも、ディレクトリの深さが壁になります。

と、いうことでBitcoinのソースコード構造を、一緒に見ていきましょう！

※自分でコードや文献を見ながらまとめたものです。間違っている可能性があるので注意してください。

# Bitcoinの実装

Bitcoin自体は、P2Pで動作するアプリケーションです。そのため、通信プロトコルさえあっていれば、パソコンで動作するBitcoinのソフト（ノード）が違う言語でも、違う作者のものでも正常に動作します。

有名なBitcoinのノードの実装では以下があります：

- [bitcoin/bitcoin](https://github.com/bitcoin/bitcoin) 通称「コア」が開発するC++実装。
- [bitcoinj/bitcoinj](https://github.com/bitcoinj/bitcoinj) Java実装。
- [bitpay/bitcore](https://github.com/bitpay/bitcore/) bitpay社が開発するNode実装。Insightのバックエンドとして使われる。
- [btcsuite/btcd](https://github.com/btcsuite/btcd) Go実装。
- [MetacoSA/NBitcoin](https://github.com/MetacoSA/NBitcoin) .NET/C#を使った実装。

bitocin/bitcoinは、Bitcoinの開発者であるナカモトサトシが、自信で実装した最小のビットコインクライアント（ノード）、通称「サトシクライアント」を元に、有志が開発してきた、リファレンス実装で、事実上の標準になっています。すべてのBIP、Bitcoinのプロトコルに対応しています。
今回、構造を見ていくのはこのbitcoin/bitcoinとなります。

# bitcoin/bitcoinのビルド成果物

bitcoin/bitcoinは、ビルドの結果以下の成果物を生成します。

- bitcoin-qt： GUIなアプリケーション。ウォレット兼ノードとして動作する。
- bitcoind： CUIなアプリケーション。ウォレット兼ノードとして動作する。ヘッドレスサーバーのデーモン用途。
- bitcoin-cli： bitcoin-qtやbitcoindが提供するAPI（JSON-RPC）に接続し、さまざまな情報を確認したり、実際に送金できる、コマンド。
- bitcoin-tx： JSON-RPCに接続し、トランザクションやブロックチェーンの情報を取得できるコマンド。
- test_bitcoin： JSON-RPCに接続し、サンプルのブロックチェーンを渡して、ブラックボックステストが行える。
- bench_bitcoin： JSON-RPCに接続し、ノードのベンチマークが行える。
- libbitcoinconsensus.h： ブロックチェーンの状態に関するライブラリ

それぞれ、`./configure`時にオプションを付けることで無効化/有効化できます。

# ダウンロード

手元で見ることが一番わかり易いので、まずは軽くcloneしてみましょう。

```
git clone --depth 1 -b master https://github.com/bitcoin/bitcoin
```

# 構造

機械的にツリー表示をすると、以下のようになります。

```
.
├── build-aux
│   └── m4
├── contrib
│   ├── debian
│   │   ├── examples
│   │   ├── patches
│   │   └── source
│   ├── devtools
│   ├── gitian-descriptors
│   ├── gitian-keys
│   ├── init
│   ├── linearize
│   ├── macdeploy
│   ├── qos
│   ├── rpm
│   ├── seeds
│   ├── testgen
│   ├── verify-commits
│   ├── verifybinaries
│   ├── windeploy
│   └── zmq
├── depends
│   ├── builders
│   ├── hosts
│   ├── packages
│   └── patches
│       ├── native_cdrkit
│       ├── qt
│       └── zeromq
├── doc
│   ├── man
│   └── release-notes
├── share
│   ├── pixmaps
│   ├── qt
│   └── rpcauth
├── src
│   ├── bench
│   │   └── data
│   ├── compat
│   ├── config
│   ├── consensus
│   ├── crypto
│   │   └── ctaes
│   ├── interfaces
│   ├── leveldb
│   │   ├── db
│   │   ├── doc
│   │   │   └── bench
│   │   ├── helpers
│   │   │   └── memenv
│   │   ├── include
│   │   │   └── leveldb
│   │   ├── issues
│   │   ├── port
│   │   │   └── win
│   │   ├── table
│   │   └── util
│   ├── obj
│   ├── obj-test
│   ├── policy
│   ├── primitives
│   ├── qt
│   │   ├── forms
│   │   ├── locale
│   │   ├── res
│   │   │   ├── icons
│   │   │   ├── movies
│   │   │   └── src
│   │   └── test
│   ├── rpc
│   ├── script
│   ├── secp256k1
│   │   ├── build-aux
│   │   │   └── m4
│   │   ├── contrib
│   │   ├── include
│   │   ├── obj
│   │   ├── sage
│   │   └── src
│   │       ├── asm
│   │       ├── java
│   │       │   └── org
│   │       │       └── bitcoin
│   │       └── modules
│   │           ├── ecdh
│   │           └── recovery
│   ├── support
│   │   └── allocators
│   ├── test
│   │   └── data
│   ├── univalue
│   │   ├── build-aux
│   │   │   └── m4
│   │   ├── gen
│   │   ├── include
│   │   ├── lib
│   │   ├── pc
│   │   └── test
│   ├── wallet
│   │   └── test
│   └── zmq
└── test
    ├── functional
    │   └── test_framework
    └── util
        └── data

```

# ルートディレクトリ

## CONTRIBUTING.md

実際にコードにコントリビュートする場合の方法・注意点がまとめられたドキュメントです。
フォークをすること、コミットはsquashすること、レビューの方法などが書かれています。

## COPYING

MITライセンスの表記がされています。

## INSTALL.md

「インストール方法はdoc/にあるよ」といった短い分が書かれています。

## README.md

Bitcoinの説明、テスト、開発プロセスへのリンクが貼ってあります。

## Makefile.am configure.ac autogen.sh

おなじみ、Autotools用の定義ファイルです。
Bitcoinは`autogen.sh && ./configure && make && make install`を経てビルドされます。

## libbitcoinconsensus.pc.in

bitcoinconsensus.hという、Bitcoinのプロトコルの状態を取得できるライブラリを提供するためのpkg-configファイルらしいです。（ただ、自信がないので間違っているかもしれません。

# src

メインのソースコードが入っています。

## bench

ベンチマークのためのコードが入っています。

## compat

メモリ関連の操作など、glibで提供される関数をラップしています。互換性を保つためだと思われます。

## config, obj, ovj-test

空です。謎。

## consensus

Bitcoinの根幹であるプロトコルの定義がされています。
マークルツリーの生成方法、BIPで起こる変化、トランザクションの整合性検査などのコードが入っています。

## crypto

暗号・ハッシュ関数に関するコードが入っています。
SHA1、SHA2、AES、HMAC、RIPMEDなどの実装がされています。
Litecoinなど、Bitcoinのフォークをしたコインでは、ここにScryptなどの新しいハッシュ関数のコードが置かれることが多いです。

## interfaces

GUIなウォレットで、画面表示のスレッドと、ネットワークに接続してノードになるスレッドの間の、通信規則を定義しています。

## leveldb

bitcoin-qtやbitcoindが、ブロックチェーンやトランザクションをローカルにファイルとして保存するときに使う、`LevelDB`というキーバリュー型のデータベースがあり、そのコードが入っています。
以前は`Berkeley DB`と呼ばれるDBが使われていましたが、今はこちらに移行されています。

## policy

手数料の計算や、レート、RBF（Replace By Fee）に関するコードが入っています。

## primitives

Bitcoinの一番最初のブロックや、最初のトランザクションなど、ソースコードに埋め込まなければ行けない原始的な情報を生成します。

## qt

GUIライブラリであるQTを使った、GUIアプリケーション（bitcoin-qt）のコードが入っています。アルゴリズム的な要素はほとんどなく、画面表示を担っています。

## rpc

bitcoin-qtやbitcoinは、ローカルのマシンなどに対して、送金や残高照会などのAPIを`JSON-RPC`と呼ばれるプロトコルで提供します。JSON-RPC自体は、簡単な認証機構がついたJSON形式のRPC通信です。
ここにはそのJSON-RPCのコードが入っています。

## script

Bitcoinの簡易スタック言語（スマートコントラクトの原始的な概念）であるScriptの、パーサーや、実行に関するコードが入っています。

## secp256k1

Bitcoinが使用している楕円曲線は、secp256k1と呼ばれる数式です。以下の式で表現できます。

```
y2 = x3 + 7
```

この楕円曲線を使い、楕円曲線暗号を使った電子署名（楕円曲線DSA, ECDSA）を利用するためのコードが入っています。

## support

何をしているかさっぱりわかりませんでした、わかる方がいれば、教えていただけると嬉しいです。

## test

他の関数に関する、単体テストのコードが入っています。base64や、Script、ハッシュ関数など、細部までテストが書かれています。

## univalue

JSONをC++から操作するためのライブラリのようです。

## wallet

お金の残高の管理、お釣りアドレス、ウォレット内のアカウントなど、ウォレットに関するコードが入っています。

## zmq

JSOn-RPCとはまた別の、zeromqと呼ばれる通信方式の実装です。

## .cpp , .h

軽く、需要なファイルを箇条書きします。

- base58.cpp : base58check encode/decode を実装しています。
- bloom.cpp : SPVウォレットなどで使用されるブルームフィルターの実装がされています。
- chainparams.cpp : チェーンのパラメーターを実装しています。BIP有効化のブロック高、tcp通信の判別記号、初期ノードのDNSアドレス、ジェネシスブロックのデータ、アドレスのprefixまで、コインに関するほとんどの定数がここで指定されています。regtest、testnet、mainetの3つの関数があります。
- key.cpp : 秘密鍵・公開鍵の導出をしています。
- pow.cpp : PoWのターゲットの計算、検証を実装しています。

# contrib

コントリビューション、つまり、開発をするときに使えるツールや、共同開発をする上で必要なツール、ビルドツールなどが詰まっています。

## README.md

各ツールの説明が書かれています。