BIP-350: Bech32m 地址格式
修正 Bech32 編碼的弱點,用於 SegWit v1+ (Taproot) 地址。
350
Standards Track
Final
2020-12-16
摘要
Bech32m 是 Bech32(BIP-173)的修正版本,用於 SegWit 版本 1 及更高版本的地址。 它修復了原始 Bech32 在特定長度變化時的錯誤檢測弱點。
為什麼需要 Bech32m?
Bech32 的弱點
研究人員發現 Bech32 編碼存在一個特定弱點:當地址最後一個字符是 p 時, 在其前面插入或刪除 q 字符可能不會被校驗碼檢測到。
範例:
bc1q...p 和 bc1q...qp 可能有相同的校驗碼!
這意味著某些類型的輸入錯誤可能無法被檢測到。
為什麼對 SegWit v0 沒問題?
SegWit v0 地址(P2WPKH 和 P2WSH)有固定長度(分別是 42 和 62 字符), 所以長度變化會立即被檢測到。但未來的 SegWit 版本可能有可變長度, 因此需要更強的錯誤檢測能力。
Bech32 vs Bech32m
| 特性 | Bech32 | Bech32m |
|---|---|---|
| 用途 | SegWit v0 (bc1q...) | SegWit v1+ (bc1p...) |
| 常數 | 1 | 0x2bc830a3 |
| 定義 | BIP-173 | BIP-350 |
| 長度變化檢測 | 有弱點 | 已修復 |
地址區分
如何判斷地址使用哪種編碼:
bc1q... (SegWit v0)
使用 Bech32
bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq
bc1p... (SegWit v1 / Taproot)
使用 Bech32m
bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297
技術變更
唯一的變更是校驗碼計算中的常數值:
# Bech32
checksum = polymod(data) ^ 1
# Bech32m
checksum = polymod(data) ^ 0x2bc830a3
錢包實作指南
- ✓ 生成地址:根據 witness version 選擇編碼
- ✓ 解碼地址:先嘗試 Bech32m,若失敗且是 v0 則嘗試 Bech32
- ✓ 驗證地址:檢查版本與編碼是否匹配
if witness_version == 0:
encoding = BECH32
else:
encoding = BECH32M 向後相容性
- ✓ 現有的 bc1q 地址繼續使用 Bech32,無需改變
- ✓ 新的 bc1p 地址使用 Bech32m
- ✓ 錢包需要同時支援兩種編碼
相關 BIP
延伸閱讀: 查看 GitHub 上的完整 BIP-350 文件