用語集 / ノードとソフトウェア
コンパクトブロックフィルター
- コンパクトブロックフィルターとは?
- コンパクトブロックフィルターとは、ブロックが生成し使用するアウトプットスクリプトをまとめた小さなGolomb符号化の要約であり、フルノードが公開することで、ライトウォレットは自身が保有するものを明かさずにブロックを検査できます。
BIP-158で規定されています。
1つのフィルターは1つのブロックに対応し、アドレス、金額、トランザクションIDではなく、アウトプットスクリプトを列挙します。BIP-158は基本タイプを0x00、Pを19、Mを784,931と定めているため、そのブロックに含まれない要素でも784,931回に約1回の割合で一致します。照合はお使いの端末上で実行されるため、フィルタを提供するノードがどのビットコインがあなたのものかを知ることはありません。
仕組み
コンパクトブロックフィルターは、ブロックが生成し消費するアウトプットスクリプトをハッシュ化して1つの数値範囲に収め、結果を並べ替え、それらの間の差分だけを記録することで構成されます。
要素の一覧は仕様で定められているため、正直な2つのノードは同じブロックに対してバイト単位で同一のフィルタを生成します。各トランザクションについて、フィルタはコインベース取引を除き、各インプットが消費する直前のアウトプットスクリプトと、各アウトプットのscriptPubKeyを取得します。1つのカテゴリは意図的に除外されています。OP_RETURNで始まるアウトプットです。BIP-158がこれらを除外するのは、ウィットネスコミットメントがすでにそうであるように、将来コインベースのOP_RETURNアウトプット内でフィルタへのコミットメントを行えるようにするためであり、その際にコミットメントが自分自身を対象に含める必要がないようにするためです。
ハッシュ化にはSipHashを使用し、cを2、dを4とし、ブロックハッシュの標準的なリトルエンディアン形式の先頭16バイトをキーとします。このキーはブロックごとに変わるため、同じスクリプトでもブロックごとに異なる位置に配置され、チェーン全体で通用するルックアップテーブルを誰も構築できません。続いて64ビットの各出力は、除算ではなく乗算とシフトによって0からN×Mの範囲に写像されます。
圧縮は名前が示すとおりです。並べ替えた値は連続する差分に置き換えられ、各差分は単進数の商とそれに続く19ビットの剰余になり、これがGolomb-Rice符号化です。出力はN×20ビットより小さくすることはできず、先頭に要素数NがCompactSizeとして付加されます。要素を持たないフィルタのブロックは、ゼロの単一バイトとして保存されます。これらのフィルタを提供する意思のあるノードは、1を6ビット左シフトしたものとして定義されるサービスビットNODE_COMPACT_FILTERSを通知します。
使われる場面
コンパクトブロックフィルタは、アドレス一覧を誰かのサーバーに渡すより、帯域を消費することを選ぶウォレットが採用する同期方法です。
Wasabi Walletは当サイトのレビューにおける例です。デスクトップ専用、ビットコイン専用、すべての接続はデフォルトでTor経由、そしてフィルタから同期するため、どのアドレスがあなたのものかをサーバーが知ることはありません。当サイトの評価は3.6で、注意の印を付けていますが、その理由は同期とは何の関係もありません。評価4.4のElectrumは別の道を選びます。誰でも運用できるインデックスサーバーに対してSPVで検証し、そのサーバーが最終的にあなたが保有するアドレスの一覧を保持することになります。
フィルタに頼る前に知っておくべき2つの制限があります。フィルタはスクリプトをキーとするため、トランザクションIDで検索することはできません。txidしかない場合は、依然としてノードかブロックエクスプローラーが必要です。またOP_RETURNアウトプットは構造上存在しないため、データを含むアウトプットを監視するソフトウェアは、この仕組みの上ではまったく構築できません。
コンパクトブロックフィルタvsコンパクトブロックリレー
コンパクトブロックフィルタは、あるブロックをダウンロードする価値があるかをウォレットに伝えます。BIP152で規定されているコンパクトブロックリレーは、2つのフルノード間をすでに移動中のブロックを小さくします。
対象とする利用者は異なります。フィルタはブロック単位で決定的であり、ブロックハッシュの先頭16バイトをキーとし、自前のチェーンを持たないクライアントによって取得されます。リレーは、ブロック内のトランザクションの大半を、ブロックヘッダーのハッシュと送信者が選ぶナンスを合わせてハッシュ化したものをキーとする48ビットの識別子に置き換えますが、それらのトランザクションをまだmempoolに保持していない受信者には何の節約にもなりません。一方はスマートフォンが不要なブロックをダウンロードするのを防ぎ、もう一方はノードが同じトランザクションを二度受信するのを防ぎます。共通する「コンパクト」という語が、類似点のすべてです。