跳至主要內容
進階

Transaction Broadcast

深入了解 Bitcoin Core 的交易廣播機制,包括傳播策略、隱私保護和故障排除。

10 分鐘

交易廣播概覽

當你發送比特幣交易時,它需要被廣播到網路中的其他節點,最終被礦工打包進區塊。 Bitcoin Core 使用精心設計的廣播策略來平衡速度、可靠性和隱私。

廣播流程

交易廣播過程:

1. 本地驗證
   ├── 檢查交易格式
   ├── 驗證簽名
   ├── 檢查輸入是否存在
   └── 驗證手續費足夠

2. 加入本地 Mempool
   ├── 通過所有策略檢查
   └── 存儲在記憶體中

3. 向節點公告
   ├── 發送 inv 消息
   ├── 包含交易 ID
   └── 使用 Dandelion 隱私(可選)

4. 節點請求交易
   ├── 發送 getdata 消息
   └── 接收完整交易

5. 傳播到全網
   └── 節點重複步驟 3-4

廣播方法

# 方法 1:使用錢包發送(最常用)
bitcoin-cli sendtoaddress "bc1q..." 0.1

# 方法 2:廣播已簽名的原始交易
bitcoin-cli sendrawtransaction "0200000001..."

# 方法 3:通過 PSBT 流程
bitcoin-cli finalizepsbt "cHNidP8..." true
# 返回 {"hex": "...", "complete": true}
bitcoin-cli sendrawtransaction "hex..."

# 方法 4:使用 testmempoolaccept 先測試
bitcoin-cli testmempoolaccept '["0200000001..."]'
# 輸出
[
  {
    "txid": "abc123...",
    "wtxid": "def456...",
    "allowed": true,
    "vsize": 141,
    "fees": {
      "base": 0.00001410
    }
  }
]

# 確認可接受後再廣播
bitcoin-cli sendrawtransaction "0200000001..."

INV 機制

交易公告(INV)流程:

發送節點                           接收節點
    │                                  │
    │──── inv (txid) ────────────────→│
    │                                  │
    │←─── getdata (txid) ─────────────│
    │                                  │
    │──── tx (完整交易) ──────────────→│
    │                                  │

為什麼使用 INV 而不是直接發送交易?
├── 節省頻寬(可能已有該交易)
├── 防止 DoS 攻擊
└── 允許接收者控制下載時機

INV 類型:
├── MSG_TX (1):交易
├── MSG_BLOCK (2):區塊
├── MSG_FILTERED_BLOCK (3):過濾區塊
├── MSG_CMPCT_BLOCK (4):緊湊區塊
└── MSG_WTX (5):witness 交易(v0.21+)

隱私保護

交易廣播隱私措施:

1. 隨機延遲(Poisson Timer)
   ├── 不立即廣播
   ├── 平均延遲 ~5 秒
   └── 防止時間分析

2. 隨機節點選擇
   ├── 不向所有節點同時公告
   ├── 分批公告
   └── 隱藏交易來源

3. 交易來源保護
   ┌─────────────────────────────────────────────────────────────┐
   │ 問題:觀察者可以通過「誰先公告」推斷交易來源                   │
   │                                                             │
   │ 解決:                                                       │
   │ ├── 隨機選擇首個公告節點                                     │
   │ ├── 使用不同的 outbound 連接                                 │
   │ └── 通過 Tor/I2P 增強匿名性                                  │
   └─────────────────────────────────────────────────────────────┘

4. INV 批處理
   ├── 不單獨公告每筆交易
   ├── 批量公告多筆交易
   └── 混淆交易時間
# 增強隱私的廣播方式

# 使用 Tor 連接
# bitcoin.conf
proxy=127.0.0.1:9050
listen=0

# 或使用 -walletbroadcast=0 禁用自動廣播
# 然後手動通過其他方式廣播
bitcoin-cli -walletbroadcast=0 sendtoaddress "bc1q..." 0.1
# 獲取原始交易
bitcoin-cli gettransaction "txid" | jq -r '.hex'
# 通過其他節點/服務廣播

重新廣播

錢包交易重新廣播:

情況:交易發送後未被確認

自動重廣播:
├── 錢包定期重新廣播未確認交易
├── 間隔約 10-15 分鐘
├── 直到交易被確認或過期
└── 可通過 -walletbroadcast=0 禁用

手動重廣播:
├── 使用 resendwallettransactions(已棄用)
└── 使用 sendrawtransaction 重新發送

注意事項:
├── 重廣播可能暴露交易來源
├── 如果交易被其他節點丟棄,需要提高手續費
└── 使用 RBF 替換低手續費交易
# 交易卡住時的處理

# 1. 檢查交易狀態
bitcoin-cli gettransaction "txid"

# 2. 查看是否在 mempool
bitcoin-cli getmempoolentry "txid"

# 3. 如果支持 RBF,創建替換交易
bitcoin-cli bumpfee "txid"

# 4. 如果不支持 RBF,嘗試 CPFP
# 找到交易的找零輸出,創建子交易花費它
bitcoin-cli send '[{"bc1q...": 0.001}]' null "unset" null '{
  "inputs": [{"txid": "parent_txid", "vout": 1}],
  "fee_rate": 50
}'

# 5. 手動重新廣播
bitcoin-cli getrawtransaction "txid" | xargs bitcoin-cli sendrawtransaction

傳播速度

交易傳播統計:

典型傳播時間:
├── 到達 50% 節點:~1-2 秒
├── 到達 90% 節點:~5-10 秒
└── 到達 99% 節點:~30 秒

影響因素:
├── 網路連接數
├── 節點地理分佈
├── 交易大小
├── 手續費率(優先級)
└── 網路擁塞程度

加速傳播:
├── 連接更多節點
├── 使用多個獨立廣播源
└── 直接連接礦池節點(如果可能)

拒絕原因

# 常見拒絕原因

# 使用 testmempoolaccept 診斷
bitcoin-cli testmempoolaccept '["raw_tx_hex"]'

# 常見錯誤:

# 1. 手續費不足
{
  "allowed": false,
  "reject-reason": "min relay fee not met"
}

# 2. 輸入已被花費
{
  "allowed": false,
  "reject-reason": "missing inputs"
}

# 3. 交易已存在
{
  "allowed": false,
  "reject-reason": "txn-already-in-mempool"
}

# 4. 雙花
{
  "allowed": false,
  "reject-reason": "txn-mempool-conflict"
}

# 5. 非標準交易
{
  "allowed": false,
  "reject-reason": "non-standard"
}

# 6. 灰塵輸出
{
  "allowed": false,
  "reject-reason": "dust"
}
拒絕原因 解決方法
min relay fee not met 增加手續費
missing inputs 等待父交易確認或使用 CPFP
txn-mempool-conflict 使用 RBF 或等待沖突交易確認
dust 增加輸出金額或合併輸出
non-standard 修改交易結構符合標準規則

外部廣播

# 使用外部服務廣播(增強隱私)

# 通過 Blockstream API
curl -X POST -d "raw_tx_hex" https://blockstream.info/api/tx

# 通過 mempool.space
curl -X POST -d "raw_tx_hex" https://mempool.space/api/tx

# 通過 Tor
torsocks curl -X POST -d "raw_tx_hex" http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/api/tx

# 多源廣播腳本
#!/bin/bash
TX=$1
curl -s -X POST -d "$TX" https://blockstream.info/api/tx &
curl -s -X POST -d "$TX" https://mempool.space/api/tx &
bitcoin-cli sendrawtransaction "$TX" &
wait

監控廣播

# 啟用網路日誌
bitcoin-cli logging '["net"]'

# 監控交易廣播
tail -f ~/.bitcoin/debug.log | grep -E "inv|getdata|tx"

# 查看交易傳播
bitcoin-cli getmempoolentry "txid" | jq '.time'

# 查看節點是否收到
bitcoin-cli getpeerinfo | jq '.[] | {addr, last_transaction}'

# 使用 ZMQ 監控
# bitcoin.conf
zmqpubrawtx=tcp://127.0.0.1:28332

# 訂閱交易通知
import zmq
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect("tcp://127.0.0.1:28332")
socket.setsockopt_string(zmq.SUBSCRIBE, "rawtx")

總結

  • INV 機制:先公告再傳輸,節省頻寬
  • 隱私保護:隨機延遲和節點選擇
  • 重廣播:錢包自動重試未確認交易
  • 診斷:使用 testmempoolaccept 測試
已複製連結
已複製到剪貼簿