はじめに
『DApps開発入門』という本や色々記事を書いているかるでねです。
今回は、1つのウォレットで複数の仮想通貨・アカウント・アドレスを体系的かつ安全に管理できるようにするための、階層的なアドレス構造の標準を提案しているBIP44についてまとめていきます!
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
他に様々なEIPについてまとめています。
概要
BIP44は、BIP0032(以降BIP32)で定義されたアルゴリズムと、BIP0043(以降BIP43)で定義された目的(purpose)スキームに基づき、決定性ウォレット(Deterministic Wallet)のための論理的な階層構造を定義しています。
BIP43で提案された考え方を、特定の形で応用した仕様となっており、ウォレットのアドレスや鍵の生成・管理を体系的かつ一貫性のある方法で行えるように設計されています。
動機
BIP44で示される階層構造は、非常に包括的な設計を持っています。
これにより、単一のウォレットで複数の仮想通貨(コイン)を扱えるだけでなく、複数のアカウントを持ち、それぞれのアカウントで外部用・内部用のチェーンを分けて管理できます。
さらに、各チェーンにおいて数百万規模のアドレスを生成・利用することも可能になります。
このような設計により、ウォレット利用者やサービス提供者は、資産管理の柔軟性と拡張性を確保しつつ、標準化された方法で鍵やアドレスを安全に生成・整理できます。
パス階層(Path Levels)
このBIPでは、BIP32に基づいたウォレットの階層的な鍵生成構造を5つのレベルに分けて定義しています。
各レベルは以下の形式で表されます。
m / purpose' / coin_type' / account' / change / address_index
パス中にあるアポストロフィ('
)は「Hardened Derivation」を意味します。
Hardened Derivationは、セキュリティ上の理由から、親鍵から直接子鍵を導出できないようにする仕組みです。
Purpose
このレベルでは、パスがどの仕様に従っているかを示すための定数を使います。
BIP43の推奨に従い、Purposeは常に 44'
(16進で 0x8000002C
)と固定されています。
この値により、このノード以下の階層はBIP44の構造に従っていることを明示します。
ここではHardened Derivationが使用されており、安全性が強化されています。
Coin type(コインの種類)
1つのマスターシードから複数の仮想通貨(例えばBitcoin、Litecoin、Namecoinなど)の鍵を生成できますが、同じ階層空間を共有してしまうと異なる通貨でアドレスが重複したり、プライバシーの問題が発生する可能性があります。
このレベルでは、通貨ごとに別のサブツリーを用意することで、それらの問題を防ぎます。
つまり、BitcoinとLitecoinで別々のアドレス空間を確保できるということです。
各仮想通貨には、それぞれ固有のcoin_type
が割り当てられます。
通貨の開発者は未使用の番号を申請して登録することができます。
このレベルでも、セキュリティ上の理由からハード化導出が使用されます。
Account(アカウント)
このレベルはユーザーのアカウントを分離するための階層です。
例えば、1つのウォレット内で「貯蓄用」、「寄付用」、「支出用」などのアカウントを作成できます。
こうすることで、異なるアカウント間でコインの使用が混在するのを防ぎます。
アカウントは0から順番に番号が振られ、BIP32の子インデックスとして利用されます。
このレベルでもハード化導出が使われています。
また、ソフトウェアは「前のアカウントにトランザクション履歴がない場合(未使用の場合)は、新しいアカウントを作らせない」ようにすべきです。
外部からシードをインポートした際は、使用済みアカウントをすべて自動で発見する必要があり、その手法は別章「アカウント探索(Account discovery)」で説明されています。
Change(チェンジ)
このレベルでは、アドレスが「外部用」か「内部用(おつり用)」かを区別します。
外部用アドレス(インデックス0)は、受取人に公開されるアドレスで支払いの受け取りなどに使います。
一方、内部用アドレス(インデックス1)は、ユーザーにしか見えない「おつり用アドレス」として使われます。
これは、支払い後に残った残高を戻す時に利用され、プライバシー保護の一環で使用されます。
このレベルでは、ハード化導出ではなく、通常の公開導出(public derivation)が使われます。
Index(アドレスインデックス)
この最下層のレベルでは、実際のアドレスが順番に生成されます。
インデックスは0から始まり、連番で増えていきます。
このレベルも公開導出が使用されており、対応する公開鍵やアドレスを安全に生成することができます。
各アカウント内の外部・内部チェーンごとに、何百万ものアドレスを生成することが可能です。
アカウント探索(Account Discovery)
外部からマスターシード(復元用の種)をインポートした時、ウォレットソフトウェアは、使用されたアカウントやアドレスを自動的に見つける必要があります。
その時に用いられるのが「アカウント探索アルゴリズム」であり、以下のような手順で処理されます。
まず、インデックス0番のアカウントノードを導出し、そのアカウントに属する外部チェーン(通常の受取用アドレス群)をスキャンします。
この外部チェーンにおいて、トランザクションが1つも見つからなければ、それ以降のアカウントは使用されていないと判断して探索を終了します。
一方で、外部チェーンに少なくとも1つのトランザクションが見つかれば、次のアカウント(インデックス1)に進み、同様の探索を繰り返します。
この探索方法は、「トランザクション履歴が存在しないアカウントは作成を許可しない」というBIP44の原則に基づいて成立しています。
なお、探索の判断基準はアカウント残高ではなくトランザクション履歴であるため、たとえそのアカウントの残高がゼロであっても、過去にトランザクションが存在すれば探索対象となります。
アドレスのギャップ制限(Address Gap Limit)
アドレス探索においては、ギャップ制限(gap limit)という概念が適用されます。
これは、連続して未使用のアドレスが20個以上続いた場合、その先には使用されたアドレスが存在しないと仮定してスキャンを終了する仕組みです。
この制限により、無限にアドレスを生成・探索することを防ぎ、効率的なスキャンが実現されます。
また、ウォレットが新しいアドレスを生成する時、ギャップ制限を超えそうな場合にはユーザーに対して警告を出すべきとされています。
なお、スキャン対象は「外部チェーン」のみであり、「内部チェーン(おつりアドレス)」はスキャンしません。
なぜなら内部チェーンのアドレスは、関連する外部チェーンのアドレスに対する返金としてのみ使用されるからです。
登録済みコインタイプ(Registered Coin Types)
BIP44の階層構造において「コインタイプ(coin_type
)」は、仮想通貨ごとの識別子として使用されます。
この識別子はハード化導出された値であり、他の通貨とのアドレス空間を分離するために使われます。
以下は一部の代表的な登録済みコインタイプです。
インデックス | 16進表記 | 通貨名 |
---|---|---|
0 | 0x80000000 | Bitcoin |
1 | 0x80000001 | Bitcoin Testnet |
これらの情報はBIPの中で一部示されていますが、完全なリストはSatoshiLabsが管理している「SLIP0044」にて公開されています。
SLIP-0044 : Registered coin types for BIP-0044
新しいコインタイプを登録するには、すでにBIP44を実装しているウォレットが存在している必要があります。
その上で、上記リポジトリに対してPull Requestを送る形で登録申請を行います。
アドレスパスの具体例(Examples)
以下は、BIP44で定義されたパス構造に従って、ビットコインおよびビットコインテストネットにおけるアカウント、チェーン、アドレスごとのパス指定の例です。
この表は、アカウント(account
)、チェーンの種類(外部用 / おつり用)、およびアドレス番号に応じて、どのようなパスが生成されるかを示しています。
例えば、最初のビットコインアカウントの外部アドレス1番目は m / 44' / 0' / 0' / 0 / 0
というパスになります。
コイン | アカウント | チェーン | アドレス番号 | パス |
---|---|---|---|---|
Bitcoin | 1番目 | 外部 | 1番目 | m / 44' / 0' / 0' / 0 / 0 |
Bitcoin | 1番目 | 外部 | 2番目 | m / 44' / 0' / 0' / 0 / 1 |
Bitcoin | 1番目 | おつり | 1番目 | m / 44' / 0' / 0' / 1 / 0 |
Bitcoin | 1番目 | おつり | 2番目 | m / 44' / 0' / 0' / 1 / 1 |
Bitcoin | 2番目 | 外部 | 1番目 | m / 44' / 0' / 1' / 0 / 0 |
Bitcoin | 2番目 | 外部 | 2番目 | m / 44' / 0' / 1' / 0 / 1 |
Bitcoin | 2番目 | おつり | 1番目 | m / 44' / 0' / 1' / 1 / 0 |
Bitcoin | 2番目 | おつり | 2番目 | m / 44' / 0' / 1' / 1 / 1 |
Bitcoin Testnet | 1番目 | 外部 | 1番目 | m / 44' / 1' / 0' / 0 / 0 |
Bitcoin Testnet | 1番目 | 外部 | 2番目 | m / 44' / 1' / 0' / 0 / 1 |
Bitcoin Testnet | 1番目 | おつり | 1番目 | m / 44' / 1' / 0' / 1 / 0 |
Bitcoin Testnet | 1番目 | おつり | 2番目 | m / 44' / 1' / 0' / 1 / 1 |
Bitcoin Testnet | 2番目 | 外部 | 1番目 | m / 44' / 1' / 1' / 0 / 0 |
Bitcoin Testnet | 2番目 | 外部 | 2番目 | m / 44' / 1' / 1' / 0 / 1 |
Bitcoin Testnet | 2番目 | おつり | 1番目 | m / 44' / 1' / 1' / 1 / 0 |
Bitcoin Testnet | 2番目 | おつり | 2番目 | m / 44' / 1' / 1' / 1 / 1 |
このパスは、それぞれ以下の意味を持つ5階層で構成されています。
-
m
- マスターシードからの起点。
-
44'
-
BIP44仕様であることを示す
purpose
。
-
BIP44仕様であることを示す
-
coin_type'
- 仮想通貨の種類(Bitcoinは
0'
, Testnetは1'
)。
- 仮想通貨の種類(Bitcoinは
-
account'
- アカウント番号(
0'
,1'
など)。
- アカウント番号(
-
change
-
0
は外部チェーン(受取用)、1
は内部チェーン(おつり用)。
-
-
address_index
- 各チェーンでのアドレス番号(0から始まる)。
この構造により、複数通貨・複数アカウント・複数アドレスを安全かつ整理された形で管理できます。
ウォレット間で互換性を保つうえでも重要な設計です。
最後に
今回は「1つのウォレットで複数の仮想通貨・アカウント・アドレスを体系的かつ安全に管理できるようにするための、階層的なアドレス構造の標準を提案しているBIP44」についてまとめてきました!
いかがだったでしょうか?
質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!
他の媒体でも情報発信しているのでぜひ他も見ていってください!