※図は Mastering Bitcoin (PDF) からの引用
- ビットコインウォレットの残高は、ビットコインネットワークから自分のビットコインアドレスが output になっているトランザクションの情報 UTXO (Unspent Transaction Output) を集めて金額を合計したもの
- ビットコインで支払うぞってなったら、集めて使おうとしてる UTXO が本当にまだ使われてないかをチェックする必要がある
- UTXO が使われていないかどうかの検証は、そのトランザクションより下の全てのブロックに含まれる全てのトランザクションをチェックする
- 全部集めるにはブロックチェーン全部をダウンロードして探索しないといけない?
- フルブロックチェーンを保持しないウォレットが作れる
- SPV クライアントがやりたいこと
- 自分に関係のあるトランザクションだけをダウンロードしたい → Bloom Filter
- トランザクションが二重使用された不正なものでないかを知りたい → Merkle tree
- 自分に関係のあるトランザクションだけを集めるための仕組み
- 自分に関係のあるトランザクションをリクエストするのに自分のアドレスを送ってしまうのはプライバシーの問題がある
- Bloom Filter
- 自分に関係のないトランザクションも含まれるけど、自分に関係のあるトランザクションは漏らさない
- 誤検知はあるけど検知漏れは無い
- false positive はあるけど false negative は無い
- ブロックに含まれているということは不正なトランザクションではないことが合意されているということなので、あるトランザクションがいずれかのブロックに含まれていることが分かれば良い
- SPV ノードは全てのトランザクション、完全なブロックチェーンをダウンロードしない
- あるトランザクションがブロックに含まれているかどうかを知りたいが自分ではわからない
- フルノードにトランザクションを渡して Merkle Path の証明を送ってもらうことで確実にブロックに含まれていることを知る
- SPV ノードはトランザクションがブロックに含まれているかどうかの確認にブロックヘッダと Merkle path という 1KB 以下のデータを受け取るだけでいい
- SPV ウォレットはフルノードに Bloom Filter を送る
- フルノードは Bloom Filter に合致するトランザクションのみを集め、Merkleblock message (ブロックヘッダと Merkle path) と共に SPV ウォレットに返してあげる
- SPV ウォレットはトランザクションハッシュ、ブロックヘッダの Merkleroot、Merkle path からそのトランザクションがブロックに含まれているかどうかを検証
- そのトランザクションがブロックに含まれて以降何ブロックできたか(何承認されたか)がわかって、よくあるクライアントだと6承認された時点でその UTXO を使用可能とする
※厳密にはちょっと違った。正しくは → https://gist.github.com/morishin/95696b41b1c81e218f4e74ae54bfb7b4#gistcomment-2302556
- Mastering Bitcoin P153 PDF
- Bitcoin Wiki - Protocol Rules
https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki#Motivation