跳至主要內容
Standards Track Final

BIP-350: Bech32m 地址格式

修正 Bech32 編碼的弱點,用於 SegWit v1+ (Taproot) 地址。

Pieter Wuille 2020年12月16日
BIP 編號

350

類型

Standards Track

狀態

Final

創建日期

2020-12-16

摘要

Bech32m 是 Bech32(BIP-173)的修正版本,用於 SegWit 版本 1 及更高版本的地址。 它修復了原始 Bech32 在特定長度變化時的錯誤檢測弱點。

為什麼需要 Bech32m?

Bech32 的弱點

研究人員發現 Bech32 編碼存在一個特定弱點:當地址最後一個字符是 p 時, 在其前面插入或刪除 q 字符可能不會被校驗碼檢測到。

範例:
bc1q...pbc1q...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

已複製連結
已複製到剪貼簿