DockerでBitcoinテスト環境を構築しブロックチェーンを確認する

DockerでBitcoinテスト環境を構築しブロックチェーンを確認する Docker

本記事では、Docker Compose 上に Bitcoin CoreRegtest)と BTC-RPC-Explorer を立ち上げ、ローカルでビットコインの動作を確認する手順を解説しています。

  • Docker Compose:
    複数のDockerコンテナをまとめて定義・実行するためのツールです。
  • Bitcoin Core(Regtest
    Bitcoin Coreが提供するテストネットワークモードの一つで、開発やテストのためにブロックの生成などを自由にコントロールできる環境です。
    (ローカル完結型のテストチェーン。マイニング報酬やテスト送金が自由に行える。)
  • BTC-RPC-Explorer
    ビットコインのブロックチェーンデータ(ブロックやトランザクション)をウェブブラウザから探索・可視化するためのWeb UIツールです。
    通常、Bitcoin CoreのRPCインターフェースに接続してデータを取得します。

実行環境

この記事では、Windows 11にDocker Desktopをインストールし、WSL2の環境にUbuntuをセットアップして、作業しています。

ファイル作成とコンテナ起動

作業ディレクトリの作成

作業ディレクトリを作成し移動する。

docker-compose.yaml の作成

docker-compose.yaml設定内容

ファイル内容の解説

services セクション
Compose では複数のコンテナを「サービス」として定義します。
このファイルでは、bitcoind(Bitcoin ノード)とexplorer(Web UI)の2つを立ち上げます。

● bitcoind(Bitcoin ノード)
image
ruimarinho/bitcoin-core:latest を使い、Bitcoin Core の公式バイナリをコンテナ化して提供するイメージを指定。

command
起動時に bitcoind に渡すオプションのリストです。

-regtest:ローカル学習用のテストチェーンを使う

-printtoconsole:ログをコンソール出力

-rpcallowip=0.0.0.0/0:すべての IP から RPC 接続を許可

-rpcbind=0.0.0.0:RPC サーバーを全インターフェースで待受

-rpcuser/-rpcpassword:RPC 認証に使うユーザー名・パスワード

-fallbackfee=0.0002:送金時の手数料(BTC/KB)のデフォルト値

ports

"18443:18443":コンテナの RPC ポートをホストの同ポートへマッピング

"18444:18444":コンテナの P2P(ネットワーク)ポートをマッピング

volumes
ホスト側の ./data ディレクトリをコンテナ内の ~/.bitcoin(データ保存場所)へマウント。
ブロック情報やウォレットデータがここに永続化されます。

● explorer(Web UI)
image
tyzbit/btc-rpc-explorer:latest:Bitcoin Core ノードのブロック/トランザクションを可視化する Web アプリケーション。

env_file
.env ファイルから環境変数を読み込み。
ここに "BTCEXP_BITCOIND_USER", "BTCEXP_BITCOIND_PASS", "BTCEXP_NETWORK=regtest" などを記述しておくと、エクスプローラーがノードに接続できます。

ports
"3002:3002":Web UI が listen するポート 3002 をホストへ公開。<br>
ブラウザで http://localhost:3002 にアクセス可能に。

depends_on
bitcoind コンテナが先に起動するよう依存関係を指定。

ターミナル操作

.envファイルの作成

.envファイル設定内容

ファイル内容の解説

BTCEXP_BITCOIND_HOST:Docker Compose のサービス名 (bitcoind)

BTCEXP_BITCOIND_PORT:Regtest 用 RPC ポート(-regtest モードでは 18443)

BTCEXP_BITCOIND_USER/BTCEXP_BITCOIND_PASS:bitcoind 起動時の -rpcuser/-rpcpassword と合わせる

BTCEXP_NETWORK:regtest に指定することで Regtest チェーンとして動作

BTCEXP_HOST/BTCEXP_PORT:Explorer サーバーのバインド先(ブラウザアクセス用)

BTCEXP_LOG_LEVE:ログの「詳細度(verbosity)」を制御する環境変数
| レベル  | 説明                                    |
| :-----: | :------------------------------------ |
| `error` | 重大なエラーのみを出力。通常は運用環境で最低限のログを残したいときに使用。 |
|  `warn` | エラーに加え、警告レベルのメッセージも出力。                |
|  `info` | 通常の稼働状況(リクエスト受信、起動完了など)を出力。デフォルト値。    |
| `debug` | 開発時に便利な詳細情報を大量に出力。                    |
| `trace` | 最も詳細なトレース情報を出力。プロトコルレイヤーまで追跡可能。       |

ターミナル操作

コンテナの起動

bitcoind が Regtest モードで起動し、RPC ポート(18443)を待受ける。
explorer が 3002 ポートで可視化 UI を提供する。

ターミナル操作

ウォレットの作成

ターミナル操作

docker compose exec bitcoind
Docker Compose で定義した bitcoind サービスのコンテナ内で、以降のコマンドを実行する指定です。

bitcoin-cli -regtest
bitcoin-cli は Bitcoin Core の JSON-RPC クライアント。
-regtest オプションにより、「ローカル学習用のテストチェーン(Regtest)」を対象に操作します。

-rpcuser=bitcoinrpc -rpcpassword=your_rpc_password
RPC 認証情報を明示的に渡すオプションです。
docker-compose.yamlで設定したUSERとpasswordを指定。

以上に内容は、コンテナ内でコマンドを実行する際のターミナル操作も同様。

listwalletdir
ウォレットの一覧を取得するコマンド。
あくまでファイルとして存在するウォレット名の一覧を返すだけで、メモリ上にロードはしません
(ロードするには別途 loadwallet が必要)。
listwallets(現在ロード中のウォレット一覧)とは異なり、未ロードのものも含めてディスク上の全ウォレットが対象。

ブロック生成と報酬の確定

新規アドレス取得

ターミナル操作

コンテナ内で、新しいビットコインアドレスを発行し、その結果をシェル変数に格納してから表示する。

101ブロック生成

ターミナル操作

Regtest 環境の Bitcoin Core ノードに対して「指定したアドレスにコインベース報酬を送りながら 101 ブロックを採掘する」操作を行います。

generatetoaddress
Bitcoin Core の RPC メソッドのひとつで、「ブロックを採掘し、そのコインベース報酬を指定アドレスに送る」機能を持ちます。

101
採掘するブロック数を指定。ここでは 101 ブロックを一度に生成します。

"$ADDR"
先ほどシェル変数 ADDR に格納したビットコインアドレス。
各ブロックのコインベース報酬(Regtest 固定で 50 BTC)がこのアドレスへ入金されます。

generatetoaddress を実行すると、生成されたブロックそれぞれのハッシュを 以下のようにJSON 配列として返します。

#生成されたブロックのハッシュ。(実際のハッシュは環境によって異なります)
[
  "2fd5aaf5141a41017b3a88f53ea89949d8daf2d7e1991629d73faa2d915cf689",
  "072b6a51676eecd9db9d488c3a51331ff0c902619c4e6de1bb0b9e1722c4c1ba",
  "1f0e384ba79ff7bbc7c6d09f38ec195add37d884f1f35c137e65daa3125f3490",
  "08c28aca3bee83311ceacaab0995b0595a6a307b5419475f2f8025a337a664f0",
  … (以下 合計101個のブロックハッシュ) …
]
なぜ「101 ブロック」なのか?
  • コインベース報酬の成熟(Maturity)
    マイニング報酬は、ブロック生成直後は immature(未成熟)扱いとなり、100 ブロック確認を経て初めて spendable(使用可能)になります。
  • 合計 101 ブロック採掘
    最初の 1 ブロックで報酬を得て、さらに 100 ブロック分を掘ることで、最初の報酬が成熟し、ウォレット残高に反映されます。

このコマンドを実行すると、Regtest ノードは 101 ブロック分の Proof-of-Work を完了し、すぐにテスト用のBTC をウォレットに供給してくれます。

100ブロック生成の条件

マイニングに成功して報酬を得るには100ブロック生成が必要です。
この100ブロック生成の条件は、Bitcoin Coreのソースコード中にハードコーディングされています。

残高・トランザクション確認

残高確認

ターミナル操作

-rpcwallet=testwallet
操作対象のウォレット名(testwallet)を指定。

getbalance
RPC メソッド名。
指定したウォレット内で「成熟(mature)・使用可能」になっているコインベース報酬や送金受取分の合計額を BTC 単位で返す。

#出力内容
50.00000000
testwallet に 50 BTC の使用可能残高があることを示している。
ウォレットの残高全体を把握する場合

getwalletinfoメソッドを使うことで、balanceunconfirmed_balanceimmature_balance 状態を含めてウォレットの残高全体を一度に確認でます。

ターミナル操作

walletname:"testwallet"	
操作対象のウォレット名

walletversion:169900
ウォレットデータのフォーマットバージョン(内部バージョン)

format:"sqlite"
ウォレットデータベース形式(SQLite を使用)

balance:50.00000000
成熟済み(spendable)残高。コインベース報酬のうち1ブロック分(50 BTC)が成熟して使用可能になっている。
「最初に生成した 1 ブロック分」の報酬だけが成熟し、送金に使える状態。

unconfirmed_balance:0.00000000	
未承認トランザクションによる残高(現在はゼロ)

immature_balance:5000.00000000	
未成熟なコインベース報酬の合計(100 ブロック分×50 BTC = 5000 BTC)。
まだ 100 確認を経ていないため送金には使えない。

txcount:101	
ウォレットが保持するトランザクション数(ここではマイニングした 101 件)
マイニングした 101 ブロックそれぞれのコインベーストランザクションがカウントされている。

keypoolsize:4000	
外部向け(受信用)にプールされている鍵ペアの数

keypoolsize_hd_internal:4000	
内部向け(おつり用)にプールされている鍵ペアの数

paytxfee:0.00000000	
デフォルトの手数料設定(BTC/KB)

private_keys_enabled:true	
ウォレット内に秘密鍵が保持されており、自分で署名できる状態

avoid_reuse:false	
既使用アドレスの再利用を回避しない設定

scanning:false	
過去ブロックの再スキャン中かどうか(現在はスキャン完了)

descriptors:true	
記述子ウォレット(descriptor)モードで管理されている

external_signer:false	
外部署名デバイス(HSMなど)を使っていない

ブラウザでブロックチェーンを確認

Regtest Explorerを開く

ブラウザを開き、http://localhost:3002 にアクセスしRegtest Explorer(下記画面)を表示する。

Regtest Explorerでできること

  1. どんなブロックが生成されたか(高さ・時間・Tx数)
  2. 直近の送受金トランザクションの内容(ID・確認数・金額)

を直感的に把握でき、さらに詳細リンクから深掘りできます。

まとめ

Docker Compose と Regtest を組み合わせることで、外部ネットワークに影響を与えずに以下の操作を繰り返し学べます。

  • フルノード起動
  • ウォレット管理
  • マイニング(ブロック生成)
  • 残高・取引履歴確認
  • エクスプローラーでの可視化

参考

参考URL

【4分アニメ解説】ブロックチェーン原理だけ〜web3すっきり理解〜

ブロックとトランザクション

トランザクション(Transaction)

定義:ビットコインの「送金指示書」です。

役割

  • あるアドレス(口座)から別のアドレスへコインを移動する命令。
  • 入力(UTXO)と出力(新たな UTXO)を指定し、署名付きで送信される。

主な構成要素

  1. Inputs(入力)
    • 以前のトランザクションの出力(UTXO)を参照
    • そこに紐づく秘密鍵で署名して「このコインを使います」と証明
  2. Outputs(出力)
    • 受取側アドレスと金額
    • 新たに生まれる UTXO
  3. 署名(ScriptSig)
    • 秘密鍵所有を証明するデジタル署名

ライフサイクル
作成 → 2. ネットワークへブロードキャスト → 3. ノードが検証 → 4. マイナーがブロックに取り込む

ブロック(Block)

  • 定義:複数のトランザクションをまとめた「箱」です。
  • 役割
    • 取引履歴(トランザクション)を一定数まとめて承認・記録する単位。
    • 前のブロックとハッシュでつながり、改ざんを防止する。
  • 主な構成要素
    1. ヘッダー(Block Header)
      • 前のブロックハッシュ(連結ポイント)
      • マークルルート(そのブロック内のトランザクション一覧を要約したハッシュ)
      • タイムスタンプ
      • 難易度ターゲット
      • ナンス(Proof-of-Work 用の可変値)
    2. トランザクションリスト
      • そのブロックに含まれるすべてのトランザクション
  • ライフサイクル
    1. マイナーが複数の未承認トランザクションを集める
    2. ヘッダー情報をもとにハッシュ計算(PoW)を行い、正しいハッシュが見つかるまで繰り返す
    3. 正しいハッシュが見つかると「ブロック完成→ネットワークへブロードキャスト」
    4. 他ノードが検証してチェーンに接続

トランザクションとブロックの関係

[TX A]  
[TX B]  
[TX C]   ←───これら複数の「トランザクション」をまとめて  
[TX D]  
   ↓
┌───────────────────────────┐
│       Block #1000         │  ←───「ブロック」として確定  
│ Header:                   │
│  - prev_hash = ...        │
│  - merkle_root = H(TXs)   │
│  - timestamp, nonce, …    │
│ Txns: [A, B, C, D, …]     │
└───────────────────────────┘
   ↓
次の Block #1001 が「prev_hash=ハッシュ(Block #1000)」でつながる
タイトルとURLをコピーしました