Develop with pleasure!

福岡でCloudとかBlockchainとか。

BIP-380のKey Expressionで複数のディスクリプターを表現できるようにする追加仕様の提案(BIP-389)

最近追加されたBIP-389↓

https://github.com/bitcoin/bips/blob/master/bip-0389.mediawiki

は、BIP-380に対する追加仕様。BIP-380は、ウォレットのバックアップにアウトプット・ディスクリプターを使用する際の仕様↓

techmedia-think.hatenablog.com

この内、Key Expressionは、公開鍵または秘密鍵の情報を表すディスクリプター仕様で、拡張公開鍵や拡張秘密鍵のBIP-32鍵導出パスを表現できる。↓みたいに

[deadbeef/0h/1h/2h]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/3/4/5/*

ただ、実際にウォレットを使用するケースでは、受け取り用のアドレスとお釣り用のアドレスを分けて管理するケースも多い。BIP-44↓のようなマルチアカウントをサポートするBIP-32パスでは

techmedia-think.hatenablog.com

m / purpose' / coin_type' / account' / change / address_index

のように導出パスの中の1つのステップ(change部分)で、受け取り用(0)とお釣り用(1)のパスを分離している。

BIP-380のKey Expressionでこれを表現しようとすると、2つのディスクリプターが必要になる。こういうユースケース向けに、Key Expression内のステップの値としてタプル値をサポートすることで、複数のディスクリプターを1つのKey Expressionで表現できるようにKey Expressionを拡張しようというのがBIP-389の提案内容。

具体的には、ステップの値として以下のような形式をサポートする。

/<NUM;NUM;...;NUM>

↑の受け取りとお釣りのケースであれば/<0;1>という値になる。

以下、BIPの日本語訳↓

概要

このドキュメントは、BIP-380で定義されているディスクリプターのKey Expressionの変更を定義します。この変更により、Key Expressionは、複数の値を持つことができるBIP-32導出パスステップを示すことができるようになる。

動機

ディスクリプターは、ウォレットで使用されるスクリプトを記述することができるが、ウォレットでは多くの場合、監視するすべてのスクリプトについて2つのディスクリプターが必要になる。通常、ウォレットには受け取り用のアドレスを生成するためのディスクリプターと、お釣りアドレス用のディスクリプターがある。これらのディスクリプターは、非常に類似していることが多く、同じ種類のスクリプトを生成し、同じマスター鍵から鍵を導出し、ほぼ同一の導出パスを使用する。ディスクリプター間で導出パスのステップが1つ異なるのが唯一の違い。したがって、導出ステップの1つが値のペアになれば、両方のディスクリプターを1つのディスクリプターとして表すことができ便利だ。

仕様

Key Expressionの拡張鍵とその導出パスについて、BIP-380では以下のように定義されている:

  • (BIP-32で定義されている)xpubエンコードされた拡張公開鍵もしくは、xprvエンコードされた拡張秘密鍵は、
    • 指定された拡張鍵の後に、BIP-32導出ステップを示す0個以上の/NUMまたはNUMhパス要素が続く。
    • オプションで最終ステップとして単一の/*または/h*が続き、これはすべての直接の非強化/強化導出された子を示す。

これが以下のように変更される:

  • (BIP-32で定義されている)xpubエンコードされた拡張公開鍵もしくは、xprvエンコードされた拡張秘密鍵は、
    • 指定された拡張鍵の後に、BIP-32導出ステップを示す0個以上の/NUM(強化導出のステップを示すため、この後にhH'を付けることができる)パス要素が続く。
    • 指定された拡張鍵の後に、BIP-32導出ステップのタプルを示す0個以上の/<NUM;NUM(強化導出のステップを示すため、この後にhH'を付けることができる)パス要素が続く。
      • BIP-32導出パスの追加タプル値である0個以上の;NUM(強化導出のステップを示すため、この後にhH'を付けることができる)が続く。
      • 単一の>/が続く。
    • 指定された拡張鍵の後に、BIP-32導出ステップを示す0個以上の/NUM(強化導出のステップを示すため、この後にhH'を付けることができる)パス要素が続く。
    • オプションで最終ステップとして単一の/*(強化導出のステップを示すため、この後にhH'を付けることができる)が続き、これはすべての直接の非強化/強化導出された子を示す。

/<NUM;NUM;...;NUM>が登場した場合、パーサーは最初のディスクリプターが最初のNUMを使用し、2つめのディスクリプターが2つめのNUMを使用するなど、複数のディスクリプターの存在を考慮する必要がある。このNUMは、公開鍵、スクリプト、アドレスの生成およびディスクリプターのインポート/エクスポート操作で考慮される。それぞれが/<NUM;NUM;...;NUM>を持つ複数のKey Expressionを含むディスクリプターは、複数のKey Expression内の/*パスを処理するのと同じ方法で、ロックステップで導出されるように、正確に同じ長さのタプルを持つ必要がある。

この一般的なユースケースは、受け取り用のアドレスとお釣り用のアドレスを生成するためにディスクリプターを表現することである。このユースケースを解釈する場合、ウォレットは受け取り用アドレスの生成に最初のディスクリプターを使用し、お釣り用アドレスの生成に2つめのディスクリプターを使用する必要がある。このユースケースでは、要素は通常/<0;1>という値になる。

Key Expressionでは、1つの/<NUM;NUM;...;NUM>のみ使用できることに注意すること。

Test Vector

BIP参照

後方互換

これは、BIP-380で定義されたKey Expressionへの追加仕様である。BIP-380で定義されている形式を使用するKey Expressionは、この変更と互換性があり、これを実装するパーサーは、引き続きそのようなディスクリプターをパースできる。ただし、Key Expressionへの追加であるため、古いパーサーは、このディスクリプターをパースすることはできない。

Key Expressionに対するこの変更では、<;という2つの新しい文字を使用する。これらはディスクリプターの文字セットの一部であるため、チェックサムアルゴリズムでカバーされる。これらはこれまで使用されていなかった文字であるため、古いパーサーが別のものを示していると誤って認識することはない。

この提案は、単一の要素で複数の導出インデックスを許可するBIP-88などの同様の提案とは対照的である。この制限は、デプロイされるディスクリプターの数を削減し、ディスクリプターのデプロイ方法に関する混乱を回避し、ユーザーが予期しないディスクリプターの展開を回避するために存在する。

参照実装

bitcoin/bitcoin#22838