BIP-322: 通用消息簽章
定義適用於所有 Bitcoin 腳本類型的通用消息簽章格式,取代傳統簽章方式。
322
Standards Track
Draft
2020-09-10
摘要
BIP-322 定義了一個通用的消息簽章標準,可以用於任何 Bitcoin 腳本類型, 包括 P2PKH、P2SH、P2WPKH、P2WSH、P2TR 等。它取代了傳統的「Bitcoin Signed Message」格式, 提供更靈活和強大的簽章能力。
動機
傳統簽章的限制
傳統的 Bitcoin 消息簽章(「Bitcoin Signed Message:」前綴)只支援 P2PKH 地址:
傳統格式的問題
- • 僅支援 P2PKH:無法為 SegWit、多簽或 Taproot 地址簽章
- • 無法證明腳本能力:只證明擁有私鑰,不證明能花費
- • 格式不一致:不同錢包實作略有差異
- • 安全疑慮:可能被用於構建惡意交易
BIP-322 的優勢
通用性
支援所有標準和非標準腳本類型,包括多簽、時間鎖和自定義腳本。
可證明性
證明簽章者確實能夠花費該地址的資金,而不僅僅是知道私鑰。
標準化
提供統一的格式,減少錢包間的相容性問題。
可擴展
支援完整簽章和簡單簽章兩種模式,適應不同需求。
核心概念
虛擬交易
BIP-322 的核心思想是創建一個「虛擬交易」來證明對地址的控制權:
簽章過程: 1. 構建「to_spend」交易(虛擬 UTXO) ┌─────────────────────────────────────────┐ │ 輸入:特殊的空輸入 │ │ 輸出:要證明的地址(scriptPubKey) │ │ 輸出金額:0 │ └─────────────────────────────────────────┘ 2. 構建「to_sign」交易(簽章交易) ┌─────────────────────────────────────────┐ │ 輸入:引用 to_spend 的輸出 │ │ 輸入簽章:證明控制權的簽章 │ │ 輸出:OP_RETURN(空) │ └─────────────────────────────────────────┘ 3. 簽章結果 = to_sign 交易的見證資料
消息哈希
消息被包含在 to_spend 交易的 scriptSig 中: to_spend.vin[0].scriptSig = OP_0 OP_PUSH32 <message_hash> 其中: message_hash = SHA256(SHA256( tag || tag || message )) tag = "BIP0322-signed-message" 這確保消息無法被重新用於其他目的。
簽章類型
簡單簽章(Simple)
適用於單一簽章者的簡單腳本:
簡單簽章格式: • 適用:P2PKH, P2WPKH, P2TR(單一密鑰) • 格式:Base64 編碼的見證堆疊 • 大小:約 64-73 bytes 範例(P2WPKH): witness = [ <signature>, // 64-72 bytes <pubkey> // 33 bytes ] 簽章 = Base64(serialize(witness))
完整簽章(Full)
適用於複雜腳本,如多簽:
完整簽章格式: • 適用:P2SH, P2WSH, 多簽, 自定義腳本 • 格式:完整的 to_sign 交易 • 包含:所有輸入的簽章和見證資料 範例(2-of-3 多簽): witness = [ OP_0, // 多簽 bug <sig1>, // 第一個簽章 <sig2>, // 第二個簽章 <redeem_script> // 贖回腳本 ] 簽章 = Base64(serialize(to_sign_tx))
各地址類型支援
| 地址類型 | 傳統簽章 | BIP-322 | 簽章模式 |
|---|---|---|---|
| P2PKH (1...) | 支援 | 支援 | Simple |
| P2SH (3...) | 不支援 | 支援 | Full |
| P2WPKH (bc1q...) | 不支援 | 支援 | Simple |
| P2WSH (bc1q...) | 不支援 | 支援 | Full |
| P2TR (bc1p...) | 不支援 | 支援 | Simple/Full |
| 多簽 | 不支援 | 支援 | Full |
驗證流程
驗證 BIP-322 簽章: 1. 解析輸入 address = "bc1q..." message = "I own this address" signature = "Base64..." 2. 重建 to_spend 交易 to_spend = create_to_spend(address, message) 3. 重建 to_sign 交易 to_sign = create_to_sign(to_spend, signature) 4. 驗證交易 • 檢查 to_sign 是否正確花費 to_spend • 驗證簽章是否有效 • 驗證腳本是否滿足 5. 結果 valid = script_verify(to_spend, to_sign)
Taproot 簽章
BIP-322 對 Taproot 地址有特殊支援:
Key Path 簽章
使用內部密鑰直接簽章,產生 Simple 格式的簽章。 見證只包含 64 bytes 的 Schnorr 簽章。
Script Path 簽章
使用腳本路徑簽章,產生 Full 格式的簽章。 包含腳本、控制塊和相關簽章。
應用場景
身份驗證
證明你控制某個 Bitcoin 地址,用於登入、身份驗證或所有權證明。 例如:在論壇或社交媒體證明你是某個地址的擁有者。
法律文件
簽署合約或協議,提供不可否認的加密證據。 結合時間戳服務可以證明簽章時間。
多簽協調
在多簽設置中,各方可以簽署消息來協調決策, 而不需要實際創建鏈上交易。
儲備證明
交易所或託管商可以證明他們控制聲稱的地址, 提供更可靠的 Proof of Reserves。
安全考量
注意事項
- 重放攻擊:簽章可以被重複使用。如果需要防止重放, 應在消息中包含時間戳或 nonce。
- 消息解讀:確保用戶清楚知道他們簽署的內容。 惡意應用可能誘導用戶簽署誤導性消息。
- 腳本複雜度:複雜腳本的簽章可能揭露腳本結構, 影響隱私。
實作狀態
總結
BIP-322 通過使用虛擬交易的概念,提供了一個適用於所有 Bitcoin 腳本類型的通用消息簽章標準。 它解決了傳統簽章格式的限制,特別是對 SegWit 和 Taproot 地址的支援, 為身份驗證、合約簽署和儲備證明等應用場景提供了強大的工具。
延伸閱讀: 查看 GitHub 上的完整 BIP-322 文件