高級
Mining RPC
了解 Bitcoin Core 提供的挖礦相關 RPC 命令,包括區塊模板和區塊提交。
10 分鐘
Bitcoin Core 提供了多個 RPC 命令用於挖礦操作,從獲取區塊模板到提交新區塊。 這些接口主要供礦池和獨立礦工使用。
getblocktemplate
獲取區塊模板,包含待打包的交易和區塊頭信息。
# 獲取區塊模板
bitcoin-cli getblocktemplate '{"rules": ["segwit"]}'
{
"capabilities": ["proposal"],
"version": 536870912,
"rules": ["csv", "segwit", "taproot"],
"vbavailable": {},
"vbrequired": 0,
"previousblockhash": "000000000000000000...",
"transactions": [
{
"data": "02000000...",
"txid": "abc123...",
"hash": "def456...", // wtxid
"depends": [],
"fee": 12500, // satoshis
"sigops": 4,
"weight": 561
},
...
],
"coinbaseaux": {},
"coinbasevalue": 625012500, // 獎勵 + 手續費
"longpollid": "000000000000000000...123",
"target": "0000000000000000000a1b2c3d...",
"mintime": 1700000000,
"mutable": ["time", "transactions", "prevblock"],
"noncerange": "00000000ffffffff",
"sigoplimit": 80000,
"sizelimit": 4000000,
"weightlimit": 4000000,
"curtime": 1700000100,
"bits": "1703c8f9",
"height": 840001,
"default_witness_commitment": "6a24aa21a9ed..."
} submitblock
提交新挖到的區塊到網路。
# 提交區塊
bitcoin-cli submitblock "0200000000000000000..."
# 返回值:
# null - 成功
# "duplicate" - 區塊已存在
# "duplicate-invalid" - 區塊已知無效
# "inconclusive" - 驗證未完成
# "rejected" - 區塊被拒絕
# 提交區塊並獲取詳細結果
bitcoin-cli submitblock "0200000..." '{"dummy": true}' getmininginfo
獲取當前挖礦狀態信息。
bitcoin-cli getmininginfo
{
"blocks": 840000,
"currentblockweight": 3998456,
"currentblocktx": 2345,
"difficulty": 72006146478567.06,
"networkhashps": 5.234e+20,
"pooledtx": 45678,
"chain": "main",
"warnings": ""
} getnetworkhashps
估算網路的總算力。
# 使用最近 120 個區塊估算
bitcoin-cli getnetworkhashps
# 指定區塊數量和結束高度
bitcoin-cli getnetworkhashps 2016 840000
# 返回: 5.234567890123456e+20 (哈希/秒) prioritisetransaction
調整交易在區塊模板中的優先級。
# 增加交易優先級(增加虛擬費用)
bitcoin-cli prioritisetransaction <txid> 0 10000
# 參數:
# 1. txid - 交易 ID
# 2. dummy - 已棄用,填 0
# 3. fee_delta - 調整量(satoshis)
# 降低優先級
bitcoin-cli prioritisetransaction <txid> 0 -5000
# 用途:
# - 礦池優先打包自己的交易
# - 加速重要交易
# - 測試目的 generateblock (Regtest)
在 regtest 模式下立即生成區塊。
# 生成包含指定交易的區塊
bitcoin-cli -regtest generateblock <address> '["<txid1>", "<txid2>"]'
# 返回
{
"hash": "abc123..."
}
# 生成空區塊
bitcoin-cli -regtest generateblock <address> '[]' generatetoaddress (Regtest)
生成多個區塊並將獎勵發送到指定地址。
# 生成 100 個區塊
bitcoin-cli -regtest generatetoaddress 100 <address>
# 返回區塊雜湊列表
[
"block_hash_1",
"block_hash_2",
...
]
# 指定最大嘗試次數
bitcoin-cli -regtest generatetoaddress 1 <address> 1000000 generatetodescriptor (Regtest)
生成區塊並使用描述符指定輸出。
# 使用描述符生成區塊
bitcoin-cli -regtest generatetodescriptor 10 "wpkh([...]/0/*)"
# 支持複雜描述符
bitcoin-cli -regtest generatetodescriptor 1 \
"wsh(multi(2,[...]/0/*,[...]/0/*))" 挖礦工作流程
import hashlib
import struct
import json
import requests
def mine_block():
# 1. 獲取區塊模板
template = rpc_call("getblocktemplate", [{"rules": ["segwit"]}])
# 2. 構建 coinbase 交易
coinbase = build_coinbase(
height=template["height"],
reward=template["coinbasevalue"],
witness_commitment=template["default_witness_commitment"]
)
# 3. 構建交易列表
txids = [coinbase.txid()] + [tx["txid"] for tx in template["transactions"]]
# 4. 計算 Merkle Root
merkle_root = compute_merkle_root(txids)
# 5. 構建區塊頭
header = struct.pack("<I", template["version"])
header += bytes.fromhex(template["previousblockhash"])[::-1]
header += merkle_root[::-1]
header += struct.pack("<I", template["curtime"])
header += bytes.fromhex(template["bits"])[::-1]
# 6. 挖礦(找 nonce)
target = int(template["target"], 16)
for nonce in range(0xffffffff):
candidate = header + struct.pack("<I", nonce)
hash_result = hashlib.sha256(hashlib.sha256(candidate).digest()).digest()
if int.from_bytes(hash_result, 'little') < target:
# 找到有效區塊!
block = serialize_block(header + struct.pack("<I", nonce), txs)
return rpc_call("submitblock", [block.hex()])
return None # 需要更新模板重試 Long Polling
# 使用 longpollid 等待新工作
bitcoin-cli getblocktemplate '{
"rules": ["segwit"],
"longpollid": "000000000000000000...123"
}'
# 當以下情況發生時返回:
# - 新區塊到達
# - mempool 顯著變化
# - 超時(約 5 分鐘)
# 這允許礦工及時獲取新工作
# 而不需要持續輪詢 區塊模板模式
# 標準模式(獲取模板)
bitcoin-cli getblocktemplate '{"rules": ["segwit"]}'
# 提案模式(驗證區塊)
bitcoin-cli getblocktemplate '{
"mode": "proposal",
"data": "02000000..."
}'
# 返回:
# null - 區塊有效
# "rejected" - 區塊無效
# "inconclusive" - 需要更多檢查 安全注意事項
- RPC 安全:挖礦 RPC 應該只在安全網路中暴露
- 區塊模板緩存:不要過度緩存,區塊鏈狀態會變化
- 時間戳:使用合理的時間戳,過大會被拒絕
- 交易選擇:確保選擇的交易有效且無衝突
- Witness Commitment:SegWit 區塊必須包含正確的 commitment
相關 RPC 命令
| 命令 | 用途 |
|---|---|
| getblocktemplate | 獲取區塊模板 |
| submitblock | 提交新區塊 |
| submitheader | 提交區塊頭 |
| getmininginfo | 挖礦狀態 |
| getnetworkhashps | 網路算力 |
| prioritisetransaction | 調整交易優先級 |
| getblockstats | 區塊統計 |
已複製連結