Standards Track Draft
BIP-157: 輕客戶端區塊過濾器
定義輕客戶端向全節點請求和驗證區塊過濾器的 P2P 協議,提供隱私優先的同步方式。
Olaoluwa Osuntokun, Alex Akselrod, Jim Posen 2017年5月24日
BIP 編號
157
類型
Standards Track
狀態
Draft
創建日期
2017-05-24
摘要
BIP-157 定義了輕客戶端(如手機錢包)向全節點請求區塊過濾器的 P2P 協議訊息。 搭配 BIP-158 定義的過濾器格式,這套方案提供了比 BIP-37 更隱私的輕客戶端同步方式。
動機
BIP-37 的問題
BIP-37 定義的 Bloom Filter 方式有嚴重的隱私問題:
隱私洩露
- • 客戶端將 Bloom Filter 發送給伺服器,暴露感興趣的地址
- • 伺服器可以通過多次請求推斷出所有地址
- • 假陽性率不足以提供有意義的隱私保護
- • 研究表明可以以 70% 的準確率連結地址
Neutrino 方案
BIP-157/158 採用相反的方式:伺服器產生過濾器,客戶端在本地檢查。
BIP-37(Bloom Filter)
客戶端告訴伺服器「我關心這些地址」, 伺服器過濾後返回相關交易。
隱私差
BIP-157(Client Filters)
伺服器提供區塊過濾器, 客戶端本地檢查是否有相關交易。
隱私好
P2P 訊息
服務位元
NODE_COMPACT_FILTERS = (1 << 6) = 0x40 支援此服務的節點可以: • 提供區塊過濾器 • 響應過濾器頭和過濾器請求
訊息類型
| 訊息 | 方向 | 用途 |
|---|---|---|
| getcfcheckpt | 客戶端 → 伺服器 | 請求過濾器頭檢查點 |
| cfcheckpt | 伺服器 → 客戶端 | 過濾器頭檢查點列表 |
| getcfheaders | 客戶端 → 伺服器 | 請求過濾器頭 |
| cfheaders | 伺服器 → 客戶端 | 過濾器頭資料 |
| getcfilters | 客戶端 → 伺服器 | 請求實際過濾器 |
| cfilter | 伺服器 → 客戶端 | 過濾器資料 |
同步流程
1. 獲取檢查點(每 1000 區塊) 客戶端 ──getcfcheckpt──→ 伺服器 客戶端 ←──cfcheckpt───── 伺服器 2. 比較多個節點的檢查點,確保一致 3. 獲取過濾器頭 客戶端 ──getcfheaders──→ 伺服器 客戶端 ←──cfheaders───── 伺服器 4. 驗證過濾器頭鏈 • 每個頭 = SHA256(filter_hash || prev_header) • 形成可驗證的鏈 5. 獲取需要的過濾器 客戶端 ──getcfilters──→ 伺服器 客戶端 ←──cfilter────── 伺服器 6. 本地匹配檢查 • 對每個相關區塊,在本地檢查過濾器 • 如果匹配,請求完整區塊
過濾器頭
過濾器頭形成一條鏈,允許客戶端驗證過濾器的完整性:
filter_header[n] = SHA256(filter_hash[n] || filter_header[n-1]) 其中: • filter_hash = SHA256(filter_data) • filter_header[0] = SHA256(filter_hash[0] || 0x00...00) 這確保: • 客戶端可以驗證過濾器未被篡改 • 可以從多個節點獲取並比較 • 惡意節點無法提供錯誤過濾器而不被發現
隱私保護
伺服器不知道
- • 客戶端關心哪些地址
- • 客戶端的錢包餘額
- • 哪些交易與客戶端相關
仍可觀察到
- • 客戶端請求了哪些區塊(如果有匹配)
- • 可以使用 Tor 或多節點輪詢緩解
實作
btcd — Go 語言的全節點實作,原生支援
Bitcoin Core — 支援生成過濾器(需要 -blockfilterindex)
Neutrino — lnd 使用的輕客戶端庫
總結
BIP-157 定義了一套隱私優先的輕客戶端協議。通過讓伺服器提供過濾器而不是 客戶端暴露查詢條件,大幅改善了輕客戶端的隱私性。這對於手機錢包和 其他資源受限的環境特別重要。
延伸閱讀
延伸閱讀: 查看 GitHub 上的完整 BIP-157 文件
已複製連結