どうも。
代表的な暗号通貨であるビットコイン(以下、 Bitcoin)は、当初よりプロトコルの改良が続けられ、現在ではそのソースツリーは巨大なものになっています。
Bitcoinにバグ修正のPRをしてみたい場合でも、ディレクトリの深さが壁になります。
と、いうことでBitcoinのソースコード構造を、一緒に見ていきましょう!
※自分でコードや文献を見ながらまとめたものです。間違っている可能性があるので注意してください。
Bitcoinの実装
Bitcoin自体は、P2Pで動作するアプリケーションです。そのため、通信プロトコルさえあっていれば、パソコンで動作するBitcoinのソフト(ノード)が違う言語でも、違う作者のものでも正常に動作します。
有名なBitcoinのノードの実装では以下があります:
- bitcoin/bitcoin 通称「コア」が開発するC++実装。
- bitcoinj/bitcoinj Java実装。
- bitpay/bitcore bitpay社が開発するNode実装。Insightのバックエンドとして使われる。
- btcsuite/btcd Go実装。
- 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
各ツールの説明が書かれています。