進階
TestMempoolAccept
學習使用 testmempoolaccept RPC 在廣播前驗證交易是否會被 mempool 接受。
8 分鐘
testmempoolaccept 是 Bitcoin Core 提供的 RPC 命令,用於在不實際廣播交易的情況下 測試交易是否會被本地 mempool 接受。這對於交易驗證和調試非常有用。
基本用法
# 測試單個交易
bitcoin-cli testmempoolaccept '["<raw_tx_hex>"]'
# 返回結果
[
{
"txid": "abc123...",
"wtxid": "def456...",
"allowed": true,
"vsize": 141,
"fees": {
"base": 0.00001410
}
}
]
# 如果交易被拒絕
[
{
"txid": "abc123...",
"wtxid": "def456...",
"allowed": false,
"reject-reason": "insufficient fee"
}
] 測試交易包(Package)
從 Bitcoin Core 24.0 開始,支持測試交易包:
# 測試 CPFP 交易包
bitcoin-cli testmempoolaccept '[
"<parent_tx_hex>",
"<child_tx_hex>"
]'
# 返回結果包含 package 信息
[
{
"txid": "parent_txid...",
"wtxid": "parent_wtxid...",
"allowed": true,
"vsize": 110,
"fees": {
"base": 0.00000110
}
},
{
"txid": "child_txid...",
"wtxid": "child_wtxid...",
"allowed": true,
"vsize": 141,
"fees": {
"base": 0.00002820,
"effective-feerate": 0.00011678, // sat/vB
"effective-includes": ["parent_wtxid", "child_wtxid"]
}
}
] 常見拒絕原因
| reject-reason | 說明 |
|---|---|
| insufficient fee | 手續費低於 minrelaytxfee |
| mempool min fee not met | mempool 已滿,費率不夠 |
| txn-mempool-conflict | 與 mempool 中交易衝突 |
| missing-inputs | 找不到輸入 UTXO |
| bad-txns-inputs-missingorspent | 輸入已被花費 |
| too-long-mempool-chain | 超出祖先/後代限制 |
| non-BIP68-final | 相對時間鎖未滿足 |
| dust | 輸出低於灰塵限制 |
| scriptpubkey | 非標準腳本類型 |
參數詳解
testmempoolaccept ["rawtx",...] ( maxfeerate )
參數:
1. rawtxs (array, required)
- 原始交易的 hex 字符串數組
- 可以是單個交易或交易包
2. maxfeerate (numeric, optional, default=0.10)
- 最大可接受的費率 (BTC/kvB)
- 用於防止意外的高手續費
- 設為 0 表示不檢查
# 示例: 限制費率為 0.001 BTC/kvB
bitcoin-cli testmempoolaccept '["<hex>"]' 0.001 實際應用場景
1. 錢包交易驗證
import requests
import json
def validate_transaction(raw_tx):
"""在廣播前驗證交易"""
rpc_data = {
"jsonrpc": "1.0",
"method": "testmempoolaccept",
"params": [[raw_tx]],
}
response = requests.post(
"http://127.0.0.1:8332",
auth=("user", "password"),
json=rpc_data
)
result = response.json()["result"][0]
if result["allowed"]:
print(f"交易有效! vsize: {result['vsize']}")
print(f"手續費: {result['fees']['base']} BTC")
return True
else:
print(f"交易被拒絕: {result['reject-reason']}")
return False 2. 費率檢查
# 檢查交易是否會因費率問題被拒絕
# 獲取當前 mempool 最低費率
bitcoin-cli getmempoolinfo
{
...
"mempoolminfee": 0.00001000,
"minrelaytxfee": 0.00001000,
...
}
# 測試交易
result=$(bitcoin-cli testmempoolaccept '["<hex>"]')
# 檢查結果
if echo "$result" | jq -e '.[0].allowed' > /dev/null; then
echo "交易會被接受"
echo "費率: $(echo "$result" | jq '.[0].fees.base / .[0].vsize * 100000000') sat/vB"
else
echo "交易被拒絕: $(echo "$result" | jq -r '.[0]["reject-reason"]')"
fi 3. RBF 測試
# 測試 RBF 替換交易
# 原始交易已在 mempool 中
# 創建替換交易(更高費率)
# 測試替換交易
bitcoin-cli testmempoolaccept '["<replacement_tx_hex>"]'
# 如果返回 "txn-mempool-conflict",
# 需要確保:
# 1. 原交易有 RBF 信號 (nSequence < 0xfffffffe)
# 2. 新交易費用足夠高
# 3. 滿足 BIP-125 規則 與 submitpackage 的關係
# testmempoolaccept 是只讀的
# submitpackage 會實際提交到 mempool
# 工作流程
1. testmempoolaccept 驗證
2. 如果通過,使用 submitpackage 提交
3. submitpackage 返回更詳細的結果
# submitpackage 示例
bitcoin-cli submitpackage '["<parent>", "<child>"]' 注意事項
- 時效性:mempool 狀態隨時變化,測試結果可能很快失效
- 節點差異:不同節點可能有不同的 mempool 策略
- 非共識:通過 testmempoolaccept 不保證被礦工打包
- 費率波動:網路擁塞時最低費率會提高
調試技巧
# 啟用詳細日誌
bitcoin-cli logging '["mempool"]'
# 查看詳細的拒絕原因
tail -f ~/.bitcoin/debug.log | grep -i "reject\|accept"
# 檢查交易的具體問題
bitcoin-cli decoderawtransaction <hex>
# 驗證輸入 UTXO 是否存在
bitcoin-cli gettxout <txid> <vout>
已複製連結