ビットコインのウォレットとインターフェース設計 — 鍵管理、トランザクション構築、RPC

はじめに

本ページは設計文書シリーズL1 #8 — ウォレット設計 である。Bitcoin Core のアプリケーション層を扱う: ソフトウェアが鍵をどう管理し、アドレスをどう導出し、コインをどう選択し、トランザクションをどう構築・署名し、手数料をどう推定し、外部呼び出し元にどう機能を公開するか。トランザクション設計ページUTXO モデルとスクリプトタイプ、および暗号設計ページの鍵導出と署名の基本要素に依存する。

ウォレットはビットコインにおいて秘密鍵に触れる唯一のサブシステムである。他のすべてのコンポーネント — 検証、中継、ストレージ、合意形成 — は公開データのみで動作する。この非対称性が、ウォレットをノードバイナリー内の密結合モジュールから論理的に(そして次第に物理的にも)分離されたプロセスへと進化させる原動力となった。

サトシ時代の実装(v0.1、2009 年 1 月)と現代の Bitcoin Core(v27 以降を基準)で挙動が異なる箇所は、双方を記載する。

1. ウォレットアーキテクチャの概要

以下の図はウォレットの Bitcoin Core プロセス内での位置と、通信するインターフェースを示す。v27 以降ではウォレットは任意で IPC 経由でノードに接続する別プロセスとして動作できる。

ウォレット(同一または別プロセス)

Bitcoin Core ノードプロセス

外部呼び出し元

JSON-RPC

JSON-RPC / REST

HTTP GET

購読

メモリープール状態

新ブロック

tx 配信

UTXO 問い合わせ

手数料推定

新ブロック

bitcoin-cli

サードパーティアプリ

ZMQ 購読者

RPC サーバー

(HTTP 上の JSON-RPC)

REST インターフェース

(読み取り専用、

認証なし)

ZMQ パブリッシャー

(プッシュ通知)

検証エンジン

メモリープール

P2P ネットワーク層

チェーン状態

(UTXO セット)

鍵マネージャー

(記述子 + keypool)

コイン選択

トランザクションビルダー

署名者

(ECDSA / シュノア)

手数料推定器

ウォレットデータベース

(SQLite、v27 以降)

サトシ時代のアーキテクチャ

v0.1 ではウォレットはインターフェース境界なしにノードバイナリーに組み込まれていた。GUI、鍵ストア、マイナー、検証エンジンがすべて単一のプロセスと単一の Berkeley DB ファイル(wallet.dat)を共有していた。初回リリース時には RPC サーバーは存在せず、JSON-RPC は稼働開始後の最初の数週間以内に追加された。

2. 鍵管理

鍵管理はウォレットの最も重要な責務である。秘密鍵を失うことは、それが管理する資金を永久に失うことを意味する — 訴える先の復旧機関は存在しない。

レガシー鍵プール(v0.1〜v0.20)

サトシの v0.1 ウォレットは鍵を独立に生成していた: 各秘密鍵は wallet.dat に保存される新規乱数だった。100 鍵の事前生成プール(「鍵プール」)が先読みを提供し、今日取得されたバックアップが近い将来に生成されるアドレスもカバーできるようにしていた。しかし、最後のバックアップ以降に作成された鍵は、ウォレットファイルが破壊されると失われた。

記述子ウォレット(v0.21 以降、v23 以降で既定)

現代の Bitcoin Core はレガシー鍵モデルを出力記述子(BIP 380〜386)で置き換える: ウォレットがアドレスをどう導出し、自身の出力をどう認識するかを完全に指定する合成可能な式。

生のシードエントロピー

(BIP 32 マスターシード)

記述子:

wpkh([fp/84h/0h/0h]xpub.../0/*)

記述子:

tr([fp/86h/0h/0h]xpub.../0/*)

記述子:

pkh([fp/44h/0h/0h]xpub.../0/*)

導出 keypool

(P2WPKH アドレス:

bc1q...)

導出 keypool

(P2TR アドレス:

bc1p...)

導出 keypool

(P2PKH アドレス:

1...)

SQLite ウォレットデータベース

特性レガシーウォレット記述子ウォレット(v27 以降)
鍵の出所独立した乱数鍵記述子からの決定性導出
バックアップモデル新しい鍵のたびに wallet.dat をエクスポート1 回のシードバックアップで将来のすべての鍵をカバー
スクリプトタイプ認識ウォレットが鍵のコンテキストからタイプを推測記述子がスクリプトタイプを明示的に宣言
監視専用サポート別の監視専用ウォレットをインポートxpub のみ(秘密鍵なし)の任意の記述子が監視専用になる
マルチスクリプト対応暗黙的(BIP 44/49/84/86 規約)明示的 — 各記述子が個別の導出規則
ストレージバックエンドBerkeley DB(wallet.datSQLite(新形式の wallet.dat
移行パスmigratewallet RPC でレガシー → 記述子に変換

3. アドレス生成

ビットコインアドレスはロックスクリプトのペイロードをユーザー向けにエンコードしたものである。ウォレットはアクティブな記述子からアドレスを生成し、アドレスが払い出されるたびに鍵プールを循環させる。

P2PKH

P2WPKH

P2TR

有効な記述子

例 wpkh(xpub.../0/*)

次の未使用インデックス

(例: インデックス 7)

インデックス 7 で

BIP 32 子鍵を導出

公開鍵

(圧縮、33 バイト)

Hash160

→ 20 バイトハッシュ

Base58Check

→ 1...

Hash160

→ 20 バイトハッシュ

Bech32

→ bc1q...

Taproot 鍵調整 (tweak)

(x-only 鍵)

Bech32m

→ bc1p...

ウォレットはギャップリミット — 最後に使用されたアドレスの先に導出する連続未使用アドレスの数 — を維持する。インデックス n のアドレスを使用するトランザクションが検出されると、ウォレットは常に未使用アドレスが利用可能になるよう鍵プールを拡張する。これにより、シードフレーズからの復元時に、トランザクションが見つからなくなるまでギャップリミット分を前方走査することで、すべての資金付きアドレスを再発見できる。

鍵導出の暗号学的詳細(BIP 32 HMAC-SHA512、強化導出と通常導出、secp256k1 スカラー乗算)およびエンコード形式(Base58Check、Bech32、Bech32m)は暗号設計ページで扱う。

4. コイン選択

ウォレットがトランザクションを構築する際、どの UTXO を入力として使用するかを選択しなければならない。コイン選択の問題は手数料最適化、プライバシー、UTXO プールの健全性の交差点に位置する。トランザクション設計ページで戦略を紹介した。本節では現代の選択パイプラインを詳述する。

選択パイプライン(v27 以降)

厳密一致あり

厳密一致なし

支払い要求

(額面 + 手数料率)

候補 UTXO をフィルター

(承認済、未ロック、

ダスト閾値超)

分枝限定法 (BnB) 探索

(厳密一致、おつりなし)

無駄指標で採点

ナップサック選択

(ランダム試行、

超過を最小化)

無駄指標で採点

単一ランダム抽選

(目標到達までシャッフル

して累積)

無駄指標で採点

最低無駄の

候補を選択

トランザクション構築

(入力 + 出力 +

必要に応じておつり)

浪費指標

浪費指標は、選択されたコインを今使う場合のコストと、仮想的な長期手数料率で使う場合のコストを比較して各候補選択を採点する。不必要なお釣り出力にはペナルティを与え、完全一致(お釣りなし)の解には報酬を与える。計算式は 3 つの要素のバランスをとる:

要素計測対象効果
入力コスト選択された入力のウェイト × (現在の手数料率 − 長期手数料率)長期レートに対して過払いの場合に正; 現在の手数料が低い場合に負(統合の好機)
お釣りコストお釣り出力の作成と後の使用にかかるコスト常に正 — お釣りは今の追加出力と後の追加入力
超過分お釣りなしトランザクションで手数料として失われる目標超過額分枝限定法のわずかな超過分を手数料に充てる解にのみ適用

浪費スコアが低いほど良い。ウォレットは異なる戦略からのすべての候補選択を評価し、最も低い浪費の選択を採用する。

5. PSBT ワークフロー

部分署名ビットコイントランザクション(BIP 174 / BIP 370)はトランザクション構築と署名を分離する。PSBT は署名者が必要とするすべてのメタデータ — UTXO データ、導出パス、償還スクリプト — を持ち運び、ブロックチェーンへのアクセスがないデバイスでも署名できるようにする。

ノードファイナライザー署名者 2(ハードウェアデバイス)署名者 1(ホットウォレット)更新者作成者ノードファイナライザー署名者 2(ハードウェアデバイス)署名者 1(ホットウォレット)更新者作成者未署名 PSBT を作成(入力、出力、署名なし)PSBT を渡すUTXO データ、導出パス、sighash 種別を追加更新済み PSBT を渡す自身の入力に署名(部分署名を追加)部分署名済み PSBT を渡す画面で出力を検証、残りの入力に署名完全署名済み PSBT を渡す部分署名を結合し、最終 scriptSig/witness を組立、ネットワーク用トランザクションを生成生トランザクションを配信検証して中継

PSBT の役割

役割処理内容通常の担当者
作成者入力と出力を定義; 未署名 PSBT を生成ウォレットソフトウェア、createpsbt RPC
更新者UTXO 詳細、導出情報、スクリプトを添付同じウォレットまたはコーディネーター; walletprocesspsbt RPC
署名者管理する入力に部分署名を追加ハードウェアウォレット、エアギャップマシン、または walletprocesspsbt
結合者複数署名者からの部分署名を 1 つの PSBT に統合combinepsbt RPC
完了者すべての署名から最終的な scriptSig / witness を組み立てfinalizepsbt RPC
抽出者完了済み PSBT から完成したネットワーク送信可能なトランザクションを取り出すfinalizepsbt(PSBT と生の 16 進数の両方を返す)

PSBT が重要な理由。 BIP 174 以前は、マルチデバイス署名にはアドホックな形式やベンダー固有のプロトコルが必要だった。PSBT は、準拠するどのウォレットでも生成、更新、署名、完了できる単一のポータブルで自己記述的なコンテナーを提供する。ハードウェアウォレット統合、マルチシグワークフロー、CoinJoin 調整、トランザクションを構築するデバイスが鍵を保持するデバイスではないあらゆるシナリオの基盤である。

6. 手数料推定

ビットコインのトランザクションは限られたブロック空間を競う。ウォレットは目標ブロック数以内でトランザクションが承認される可能性の高い手数料率(仮想バイトあたりのサトシ数)を推定しなければならない。

推定メカニズム

Bitcoin Core の estimatesmartfee はトランザクションがメモリープールに入った時の手数料率を追跡し、各トランザクションが承認までに何ブロック待ったかを記録する。トランザクションは手数料率でバケットに分類され、各バケットについて推定器は成功率 — その手数料率のトランザクションのうち n ブロック以内に承認された割合 — を維持する。指定された承認目標に対する推定値は、成功率が閾値(経済的モードで 85%、保守的モードで 95%)を超える最低手数料率バケットである。

モード閾値挙動典型的な用途
経済的85% 成功率低手数料、承認がやや遅れるリスク緊急でない支払い
保守的95% 成功率高手数料、より確実な承認時間に敏感な支払い

手数料推定の進化

側面サトシ時代(v0.1)現代の Bitcoin Core、v27 以降基準
手数料の要件トランザクションは無料; 手数料は任意必須; 手数料なしのトランザクションはメモリープールポリシーで拒否
推定なし — 手数料市場が存在しなかったバケットベースのメモリープール追跡(estimatesmartfee
手数料引き上げ利用不可RBF(bumpfee RPC)、CPFP(低手数料出力を高手数料の子で使用)
最低中継手数料0.01 BTC(後に引き下げ)1 sat/vB 既定(minrelaytxfee

7. RPC・REST・ZMQ インターフェース

Bitcoin Core は外部呼び出し元に 3 つのインターフェースを公開する。それぞれ異なるアクセスパターンに対応する。

インターフェース

呼び出し元

bitcoin-cli

(コマンドライン)

Web アプリ

ストリーミング購読者

(インデクサー、

モニター)

JSON-RPC

(ポート 8332)

認証あり、

読み書き

REST

(ポート 8332)

認証なし、

読み取り専用

ZMQ

(設定可能ポート)

プッシュ通知、

リクエスト不要

RPC コマンドカテゴリー

カテゴリーコマンド例処理内容
ブロックチェーンgetblockchaininfogetblockgettxoutsetinfoチェーン状態、ブロックデータ、UTXO セット統計の問い合わせ
ウォレットgetnewaddresssendtoaddresslistunspentwalletprocesspsbt鍵管理、トランザクション構築、コイン選択
トランザクションgetrawtransactiondecoderawtransactionsendrawtransaction生のトランザクションの検査、作成、ブロードキャスト
マイニングgetblocktemplatesubmitblockgetmininginfoブロックテンプレート構築と提出(プール運営者向け)
ネットワークgetpeerinfoaddnodegetnetworkinfoピア管理、接続状態、帯域幅統計
制御stopuptimelogginggetmemoryinfoノードのライフサイクルと診断
手数料estimatesmartfee目標承認ウィンドウに対する手数料率推定
PSBTcreatepsbtwalletprocesspsbtcombinepsbtfinalizepsbt秘密鍵に直接触れない完全な PSBT ワークフロー

インターフェース比較

特性JSON-RPCRESTZMQ
プロトコルHTTP POST(JSON 本文)HTTP GET(URL パス)TCP プッシュ(パブ/サブ)
認証クッキーまたはユーザー名/パスワード(rpcauthなし(設計上読み取り専用)なし(ローカルネットワーク前提)
方向要求 → 応答要求 → 応答サーバーがサブスクライバーにプッシュ
書き込みアクセスあり(トランザクション送信、ウォレット管理)なしなし(通知のみ)
データ形式JSONJSON、バイナリー、または 16 進数(呼び出し元の選択)生のバイナリー(ブロックハッシュ、トランザクションハッシュ、または完全なシリアライズされたブロック/トランザクション)
典型的な呼び出し元bitcoin-cli、ウォレットアプリ、取引所バックエンドブロックエクスプローラー、軽量モニターインデクサー、リアルタイムダッシュボード、Lightning ノード
ZMQ トピックhashblockhashtxrawblockrawtxsequence

8. ノードからのウォレット分離

サトシの v0.1 はウォレット、マイナー、GUI、検証エンジンを単一のバイナリーにコンパイルしていた。現代の Bitcoin Core はウォレットをノードから漸進的に分離してきた。

v27 以降基準

IPC

(Cap'n Proto)

bitcoind

(ノードのみ)

bitcoin-wallet

(任意で別プロセス)

wallet.dat

(SQLite)

v0.17–v0.20

bitcoind

(ノード + ウォレットモジュール)

ウォレットモジュール

(内部、

リンクライブラリー)

wallet.dat

(Berkeley DB)

v0.1 (2009)

単一バイナリ

(ウォレット + ノード + マイナー + GUI)

wallet.dat

(Berkeley DB)

マイルストーンバージョン変更内容
ウォレットインターフェース定義v0.17(2018 年)内部の interfaces::Wallet 抽象化がウォレットロジックをノードロジックから分離
-disablewallet オプションv0.8(2013 年)ウォレットを読み込まずにノードを実行可能
マルチウォレット対応v0.17(2018 年)単一のノードが複数のウォレットファイルを同時に読み込み管理
記述子ウォレットv0.21(2021 年)新しいウォレット形式; v23 以降で新規ウォレットの既定
Berkeley DB 非推奨v26(2023 年)新規ウォレットは SQLite のみを使用; レガシー BDB ウォレットは移行可能だが BDB サポートはまだ完全には削除されていない
マルチプロセス化(実験的)v27 以降(2024 年)実験的な bitcoin-node / bitcoin-wallet プロセス分離(IPC は Cap’n Proto)。bitcoin-wallet CLI ツールはオフラインウォレット操作を処理; 完全な IPC ベースの実行時分離は進行中で既定ではない

分離が重要な理由。 ウォレットは秘密鍵 — システム内で最も機密性の高いデータ — を扱う。論理的分離(既に達成済み)と最終的な物理的プロセス分離により、鍵を保持するコンポーネントを制限された環境で動作させ、ノードは公開的に検証可能なチェーンデータを処理する。

9. 二つの時代の比較

機能サトシ時代(v0.1、2009 年 1 月)現代の Bitcoin Core、v27 以降基準
アーキテクチャウォレットが単一バイナリーノードに組み込み論理的に分離済み; 実験的マルチプロセス分離が進行中
鍵生成ランダム鍵プール(100 個の独立鍵)記述子ウォレット: マスターシードからの決定性導出
鍵ストレージBerkeley DB(wallet.datSQLite(新形式の wallet.dat
バックアップモデル新しい鍵のたびにファイルをエクスポート; バックアップ後の新しい鍵は復元不能記述子バックアップがすべての導出鍵をカバー(BIP 39 ではなく生の BIP 32 シード)
アドレスタイプP2PK、P2PKH のみP2PKH、P2SH、P2WPKH、P2WSH、P2TR
アドレスエンコードBase58CheckBase58Check(レガシー)、Bech32、Bech32m
コイン選択単純な最大額優先分枝限定法 + ナップサック + 単一ランダム抽出; 浪費指標による採点
トランザクション署名内部、同一プロセス内部、PSBT(BIP 174/370)、またはハードウェアウォレット(HWI 経由)
マルチデバイス署名未対応PSBT ワークフロー: 作成 → 更新 → 署名 → 結合 → 完了
手数料推定なし(大半のトランザクションが無料)バケットベースのメモリープール追跡; 経済的モードと保守的モード
手数料引き上げ利用不可手数料置換(bumpfee)、CPFP
インターフェースリリース時はなし; 直後に基本的な JSON-RPC を追加JSON-RPC(完全)、REST(読み取り専用)、ZMQ(プッシュ通知)
マルチウォレットノードあたり 1 ウォレット複数ウォレットを同時に読み込み; loadwallet / unloadwallet
暗号化利用不可encryptwallet — 保存時の秘密鍵を AES-256-CBC で暗号化
監視専用未対応xpub のみ(秘密鍵なし)の任意の記述子
プロセスモデル一体型(ウォレット + ノード + マイナー + GUI)モジュール型: bitcoind(ノード)、bitcoin-wallet(ウォレット)、bitcoin-qt(GUI)

10. 本ページの範囲

本ページは Bitcoin Core のウォレットとインターフェース層を扱う。以下のトピックは範囲外であり、設計文書シリーズ内のそれぞれのページで扱う:

  • トランザクション構造とスクリプト — 入力、出力、ロックスクリプトがプロトコルレベルでどう機能するか。トランザクション設計ページで扱う。
  • 暗号学的基本要素 — 楕円曲線数学、ハッシュ関数、HD 導出の内部(BIP 32 HMAC-SHA512)、署名アルゴリズム。暗号設計ページで扱う。
  • メモリープールポリシー — 中継規則、手数料率の下限、パッケージリレー、手数料置換の適用。ネットワーク設計ページで扱う。
  • マイニングとブロックテンプレート — マイナーがメモリープールからトランザクションを選択し候補ブロックをどう構築するか。合意形成設計ページで扱う。
  • サードパーティーウォレット — Electrum、Sparrow、ハードウェアウォレット、モバイルウォレットは Bitcoin Core リファレンス実装の外部のアプリケーション層ソフトウェア。
  • Lightning Network — ここで記述したトランザクションと PSBT の基本要素の上に構築されるが、別のプロトコルで動作するレイヤー 2 決済チャネル。