ビットコイン・インスティテュート

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

濃紺の背景に描かれた技術図解で、三つの区画に分かれている。左では鍵の種が記述子を経て複数のアドレス形式へ枝分かれし、中央では役割ごとの円形アイコンが斜め線でつながれ、書類を順々に受け渡す流れを表す。右では複数の選択経路が一つの円へ収束し、そこから複数のインターフェース枠へ広がる。下部には処理の流れを示す横棒がある。

はじめに

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

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

サトシ時代の実装(v0.1、2009年1月。Forensicxsによる2024年のコードウォークスルーが行単位で調査済み)と現代のBitcoin Core(v27以降を基準)で挙動が異なる箇所は、双方を記載する。

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

以下の図はウォレットのBitcoin Coreプロセス内での位置と、通信するインターフェースを示す。実験的なマルチプロセスのビルドでは、ウォレットは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が加わったのはリリースから約13か月後、v0.2.6(2010年2月)のことで、その年の7月のv0.3リリースで初めて主要機能に格上げされた。

2. 鍵管理

鍵管理はウォレットの最も重要な責務である。秘密鍵を失うことは、それが管理する資金を永久に失うことを意味する。訴える先の復旧機関は存在しない。この永久性が実際にどう現れるかは、アーカイブのビットコイン象徴的損失概観が、ステファン・トーマスのIronKeyロックアウトやジェームズ・ハウエルズの埋立地行きハードドライブを含めてまとめている。ウォレットデータベース (wallet.dat、Berkeley DBまたはSQLite) は、合意データ (ブロックファイルとUTXO集合) とは別のストレージパスであり、ストレージ設計ページに記録されている。一方を失っても、もう一方には影響しない。

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

サトシのウォレットは当初、鍵を独立に生成していた: 各秘密鍵はwallet.datに保存される新規乱数で、先読みはなく、最後のバックアップ以降に作成された鍵は、ウォレットファイルが破壊されると失われた。このwallet.datは、トランメルにバックアップ対象を尋ねられたサトシ自身が名指ししたファイルであり、トランザクション対応のデータベースDBM(Berkeley DB)に保存されていた。この欠落はv0.3.12(2010年9月)まで続いており、同リリースが持つバックアップ手段は手動でファイルをコピーする新しいbackupwallet RPCコマンドのみだった。サトシが実際にこの欠落を解消したのは翌月のv0.3.14(2010年10月)で、100鍵の事前生成プール(「鍵プール」)により、今日取得したバックアップが近い将来に生成されるアドレスもカバーできるようになった。この欠落は理論上の懸念にとどまらなかった。実際、ダスティン・トランメルは2009年1月の時点で、まさにこのリスクをサトシに指摘していた。鍵プールがその欠落を解消する2年近く前のことである。

記述子ウォレット(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.dat)SQLite(新形式のwallet.dat)
移行パス—migratewallet RPCでレガシー → 記述子に変換

3. アドレス生成

ビットコインアドレスはロックスクリプトのペイロードをユーザー向けにエンコードしたものである。ウォレットはアクティブな記述子からアドレスを生成し、アドレスが払い出されるたびに鍵プールを循環させる。具体的には、BIP 32子鍵導出により次の未使用インデックスで新しい鍵を導出し、得られた鍵素材(Taprootではさらに調整を加える)を以下のようにエンコードする。

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

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

支払者ごとに新規アドレスを割り当てるという発想の根拠は、この仕組みそのものより古くから存在する。サトシは2009年1月にダスティン・トランメルへ宛てたメールで、支払者ごとに固有の受信アドレスを生成するという発想には「現実世界にあまり似たものがない」と述べている。これはまさに、上述のギャップリミットに支えられた鍵プールが解決しようとしている使い勝手の課題である。

4. コイン選択

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

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

厳密一致あり

手数料率が 長期の手数料率の

3 倍を超える(既定は 30 sat/vB 超)

支払い要求

(額面 + 手数料率)

候補 UTXO をフィルター

(承認済、未ロック、

ダスト閾値超)

分枝限定法 (BnB) 探索

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

無駄指標で採点

ナップサック選択

(ランダム試行、

超過を最小化)

無駄指標で採点

単一ランダム抽選

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

して累積)

無駄指標で採点

CoinGrinder

(入力の重さを最小化)

無駄指標で採点

最低無駄の

候補を選択

トランザクション構築

(入力 + 出力 +

必要に応じておつり)

無駄指標

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

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

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

5. PSBTワークフロー

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

ハードウェアデバイス(署名者2)は署名する前に自身の画面で出力を検証する。完了者が最終的な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以降基準
手数料の要件GetMinFee: ウォレットは10,000バイト未満なら手数料を付けなかった。マイナーが10,000バイト未満の取引の手数料を免じたのは、ブロックの取引が100件未満のあいだだけだった。それ以外は0.01 BTC ×(1 + バイト数 ÷ 1,000の切り捨て)必須; 手数料なしのトランザクションはメモリープールポリシーで拒否
推定なし — 手数料市場が存在しなかったバケットベースのメモリープール追跡(estimatesmartfee)
手数料引き上げ利用不可RBF(bumpfee RPC)、CPFP(低手数料出力を高手数料の子で使用)
最低中継手数料なし: メモリープールに入れるときのConnectInputsの最低手数料は0で、中継では手数料を確かめず、規則はウォレットが取引を作るときとマイナーがブロックを作るときにかかった1 sat/vB既定(minrelaytxfee)

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

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

インターフェース

呼び出し元

bitcoin-cli

(コマンドライン)

Web アプリ

ストリーミング購読者

(インデクサー、

モニター)

JSON-RPC

(ポート 8332)

認証あり、

読み書き

REST

(ポート 8332)

認証なし、

読み取り専用

ZMQ

(設定可能ポート)

プッシュ通知、

リクエスト不要

RPCコマンドカテゴリー

カテゴリーコマンド例処理内容
ブロックチェーンgetblockchaininfo、getblock、gettxoutsetinfoチェーン状態、ブロックデータ、UTXOセット統計の問い合わせ
ウォレットgetnewaddress、sendtoaddress、listunspent、walletprocesspsbt鍵管理、トランザクション構築、コイン選択
トランザクションgetrawtransaction、decoderawtransaction、sendrawtransaction生のトランザクションの検査、作成、ブロードキャスト
マイニングgetblocktemplate、submitblock、getmininginfoブロックテンプレート構築と提出(プール運営者向け)
ネットワークgetpeerinfo、addnode、getnetworkinfoピア管理、接続状態、帯域幅統計
制御stop、uptime、logging、getmemoryinfoノードのライフサイクルと診断
手数料estimatesmartfee目標承認ウィンドウに対する手数料率推定
PSBTcreatepsbt、walletprocesspsbt、combinepsbt、finalizepsbt秘密鍵に直接触れない完全なPSBTワークフロー

インターフェース比較

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

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.15(2017年)単一のノードが複数のウォレットファイルを同時に読み込み管理。実行中の読み込みと解除はv0.17から
記述子ウォレットv0.21(2021年)新しいウォレット形式; v23以降で新規ウォレットの既定
Berkeley DB非推奨v26(2023年)レガシーBDBウォレットの作成には非推奨の旗が要る; 新規ウォレットはSQLite
レガシーウォレットの撤去v30(2025年)BDBのレガシーウォレットは作成も読み込みもできなくなった; migratewalletでディスクリプターウォレットに変換する
マルチプロセス化(実験的)v27以降(2024年)実験的なbitcoin-node / bitcoin-walletプロセス分離(IPCはCap’n Proto)。bitcoin-wallet CLIツールはオフラインウォレット操作を処理; 完全なIPCベースの実行時分離は進行中で既定ではない

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

9. 二つの時代の比較

機能サトシ時代(v0.1、2009年1月)現代のBitcoin Core、v27以降基準
アーキテクチャウォレットが単一バイナリーノードに組み込み論理的に分離済み; 実験的マルチプロセス分離が進行中
鍵生成リリース時は独立乱数鍵; 100鍵の先読みプールはv0.3.14(2010年10月)で追加記述子ウォレット: マスターシードからの決定性導出
バックアップモデル新しい鍵のたびにファイルをエクスポート; バックアップ後の新しい鍵は復元不能記述子バックアップがすべての導出鍵をカバー(BIP 39ではなく生のBIP 32シード)
アドレスタイプP2PK、P2PKHのみP2PKH、P2SH、P2WPKH、P2WSH、P2TR
アドレスエンコードBase58CheckBase58Check(レガシー)、Bech32、Bech32m
コイン選択ちょうどの額、なければ無作為の部分和1,000回か目標額を上回る最小の硬貨(ナップサックの祖先)分枝限定法 + ナップサック + 単一ランダム抽出 + CoinGrinder; 無駄指標による採点
トランザクション署名内部、同一プロセス内部、PSBT(BIP 174/370)、またはハードウェアウォレット(HWI経由)
マルチデバイス署名未対応PSBTワークフロー: 作成 → 更新 → 署名 → 結合 → 完了
手数料推定なし(大半のトランザクションが無料)バケットベースのメモリープール追跡; 経済的モードと保守的モード
手数料引き上げ利用不可手数料置換(bumpfee)、CPFP
インターフェースリリース時はなし; JSON-RPCはv0.2.6(2010年2月、リリースから13か月後)に追加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決済チャネル。

トランザクション設計は、ここが終わるところから始まる。ウォレットが組み立てて署名したものが、トランザクション層の運ぶものである。

参照元の外部ソース

https://bitcoin.org/bitcoin.pdf