高級
Transaction Standardness
了解比特幣交易的標準性規則,區分共識有效性與節點策略。
12 分鐘
交易標準性(Standardness)是 Bitcoin Core 的策略層規則,與共識規則分開。 標準交易會被節點中繼和包含在區塊模板中,非標準交易雖然可能共識有效, 但不會被大多數節點傳播。
共識 vs 標準性
共識規則 (Consensus):
- 所有節點必須遵守
- 違反會導致區塊/交易被拒絕
- 變更需要硬分叉或軟分叉
- 例: 簽名必須有效、不能雙花
標準性規則 (Standardness/Policy):
- 只影響未確認交易的傳播
- 節點可以自行配置
- 變更只需軟體升級
- 例: 最小交易大小、腳本類型限制
範例:
交易使用 OP_NOP6:
- 共識: 有效(OP_NOP6 什麼都不做)
- 標準性: 非標準(不允許使用 NOP)
- 結果: 不會被中繼,但礦工可以自己挖 標準交易類型
被認為「標準」的輸出類型:
1. P2PKH (Pay to Public Key Hash)
OP_DUP OP_HASH160 <hash> OP_EQUALVERIFY OP_CHECKSIG
地址: 1...
2. P2SH (Pay to Script Hash)
OP_HASH160 <hash> OP_EQUAL
地址: 3...
3. P2WPKH (Pay to Witness Public Key Hash)
OP_0 <20-byte-hash>
地址: bc1q...
4. P2WSH (Pay to Witness Script Hash)
OP_0 <32-byte-hash>
地址: bc1q... (較長)
5. P2TR (Pay to Taproot)
OP_1 <32-byte-pubkey>
地址: bc1p...
6. Nulldata (OP_RETURN)
OP_RETURN <data>
最大 80 字節數據
7. Multisig (裸多簽,已不推薦)
m <pubkeys> n OP_CHECKMULTISIG 標準性規則
交易大小限制
// 交易大小規則
最大標準交易大小:
MAX_STANDARD_TX_WEIGHT = 400,000 WU
= 100,000 vBytes
最小交易大小:
MIN_STANDARD_TX_NONWITNESS_SIZE = 82 bytes
// 防止 CVE-2017-12842 攻擊
輸出大小:
最小非粉塵輸出值(見 dust 規則)
OP_RETURN 數據:
MAX_OP_RETURN_RELAY = 83 bytes
// OP_RETURN + push + 80 bytes data 腳本規則
// 腳本標準性
允許的操作碼:
- 大多數標準操作碼
- 禁止: OP_CAT, OP_SUBSTR, OP_LEFT, OP_RIGHT 等
P2SH 限制:
- RedeemScript 最大 520 bytes
- 最多 15 個公鑰(多簽)
P2WSH 限制:
- Witness script 最大 3600 bytes
- 最多 20 個公鑰
Taproot:
- 更寬鬆的限制
- 允許任意腳本(受共識限制)
// 標準性比共識更嚴格
// 為未來升級留出空間 簽名規則
// 簽名標準性
ECDSA 簽名:
- 必須是低 S 值(BIP-146)
- 必須是嚴格 DER 編碼
- 不允許不必要的零填充
Schnorr 簽名 (Taproot):
- 必須是 64 或 65 字節
- 嚴格的編碼要求
公鑰:
- 必須是壓縮格式(33 字節)
- 除非是舊 P2PK 輸出
// 這些規則防止可延展性
// 並為將來的腳本升級做準備 非標準但有效的交易
// 這些交易共識有效但非標準
1. 使用未知見證版本
OP_16 <data> // 版本 16
// 為未來軟分叉保留
2. 超大 OP_RETURN
OP_RETURN <200 bytes data>
// 共識允許,但超過標準限制
3. 非標準腳本類型
OP_TRUE // 任何人可花費
// 有效但不會被中繼
4. 非壓縮公鑰
<65-byte uncompressed pubkey>
// 舊格式,仍然有效
5. 過小的交易
< 82 bytes(非見證部分)
如何確認這類交易?
- 直接提交給礦工
- 礦工自己挖掘
- 使用特殊中繼服務 為什麼要標準性?
標準性規則的目的:
1. 安全緩衝
- 限制新功能的暴露
- 允許漸進式測試
- 發現問題後可以收緊
2. DoS 防護
- 限制複雜腳本
- 防止 CPU 密集型驗證
- 保護節點資源
3. 未來升級
- 保留 OP_NOP 為軟分叉
- 保留見證版本為升級
- 不會被現有交易佔用
4. 可延展性修復
- 強制低 S 簽名
- 嚴格編碼
- 減少 TXID 變化風險
5. 網路效率
- 減少區塊大小浪費
- 統一腳本驗證
- 優化傳播 配置選項
# bitcoin.conf 中的相關選項
# 接受非標準交易(不推薦主網)
acceptnonstdtxn=1 # 默認 0
# 允許裸多簽
permitbaremultisig=1 # 默認 1
# OP_RETURN 數據限制
datacarriersize=83 # 默認 83 bytes
# 數據載體
datacarrier=1 # 默認 1,允許 OP_RETURN
# 粉塵限制
dustrelayfee=0.00003 # sat/vB
# 測試網上更寬鬆
# testnet/regtest 默認 acceptnonstdtxn=1 測試非標準交易
# 使用 testmempoolaccept 檢查標準性
bitcoin-cli testmempoolaccept '["<raw_tx_hex>"]'
{
"txid": "...",
"allowed": false,
"reject-reason": "non-standard"
}
# 常見拒絕原因
"scriptpubkey" # 非標準輸出類型
"scriptsig-size" # ScriptSig 太大
"scriptsig-not-pushonly"# ScriptSig 包含非 PUSH 操作
"scriptpubkey-size" # ScriptPubKey 太大
"dust" # 輸出值太小
"tx-size" # 交易太大或太小
"non-mandatory-script-verify-flag" # 腳本驗證失敗
# 在 regtest 上測試
bitcoin-cli -regtest sendrawtransaction <hex> 標準性的演進
歷史變化:
2010: 最初的標準性規則
- 限制腳本類型
- 保護網路
2012: P2SH 成為標準
- BIP-16 軟分叉
- 標準性先於共識啟用
2015: CLTV/CSV 標準化
- 新操作碼添加到標準集
2017: SegWit 標準化
- P2WPKH, P2WSH 成為標準
- 見證版本 0
2021: Taproot 標準化
- P2TR 成為標準
- 見證版本 1
未來:
- 新的見證版本 (2-16)
- 新的操作碼
- 標準性會逐步放寬 對開發者的影響
- 使用標準類型:優先使用 P2WPKH, P2WSH, P2TR
- 測試交易:使用 testmempoolaccept 驗證
- 了解限制:腳本大小、公鑰數量等
- Regtest 測試:非標準交易可在 regtest 測試
- 關注升級:新版本可能放寬標準性
相關概念
- Mempool Policy:完整的 mempool 接受規則
- Script Validation:腳本驗證過程
- Dust Limits:粉塵輸出限制
- ScriptPubKey Types:輸出腳本類型
已複製連結