getblocktemplate不是“给矿机一段区块头”这么简单。Bitcoin Core 31返回的是一个带规则协商、交易依赖和生命周期信号的候选区块模板。矿池若忽略depends、weight或longpollid,可能构造出交易顺序错误、超出限制或已经过期的候选块。
请求先声明模式与规则
最常见的是template模式,请求对象还应通过rules声明调用方理解的规则,例如segwit。proposal模式用于让节点检查一个候选区块,而不是返回完整模板。BIP 22定义基础语义,BIP 23补充长轮询等扩展;实现时仍应以当前Bitcoin Core RPC文档为字段基准。
{"rules":["segwit"],"mode":"template"}
节点可能根据链尖、内存池、规则和本地配置生成不同模板。不要缓存一个模板后无限复用,也不要假设两个节点在同一时刻返回完全相同的交易集合。
transactions不是普通交易数组
每个条目包含原始交易data、txid、wtxid语义下的hash、depends、fee、sigops与weight等字段。depends使用模板内交易的一基索引,表示当前交易依赖哪些更早条目。构建器必须确保父交易在子交易之前,不能按fee单字段重新排序后破坏依赖。
fee以聪为单位,可能在存在祖先或子交易包时与单笔直觉不同;weight用于检查区块权重;sigops是按当前模板规则计算的签名操作成本。选交易时至少要同时考虑依赖闭包、总费用、总权重和签名操作限制,而不是“费率最高优先”这一条。
选择候选交易
→ 补齐depends祖先
→ 按拓扑顺序排列
→ 累计weight与sigops
→ 计算coinbase和承诺
关于内存池交易包与费用关系,可结合getmempoolcluster怎么读;节点链状态和等待新区块逻辑可参考waitfornewblock超时算新区块吗。
coinbase和区块头看哪些字段
coinbasevalue给出模板允许的coinbase输出总价值,已经把区块补贴与所选交易费用计入。调用方若使用coinbasetxn,则要遵守节点给出的交易和可修改规则;自行构造coinbase时还需处理区块高度承诺、矿池标识、见证承诺和输出分配。
target是工作量目标,bits是紧凑表示,height是候选区块高度,previousblockhash把模板绑定到父块。curtime、mintime和noncerange约束时间与nonce搜索范围。mutable和capabilities说明调用方可以安全修改什么,不能把“字段存在”误解为任意改动都有效。
什么时候立即丢弃模板
previousblockhash变化代表链尖改变,旧模板通常应废弃。longpollid用于在链尖或交易集合发生值得更新的变化时等待新模板;调用方应为超时、断线和节点重启设置重试。若节点返回新的rules、version或限制,也应重新协商,而不是只替换交易数组。
提交前可用proposal模式或submitblock路径检查候选,但本地预检不保证最终成为主链区块。其他矿工可能先找到块,网络传播和节点策略也会影响结果。关于节点网络状态可参考getnettotals怎么计算实时流量。
最小验收清单
确认规则协商成功;depends全部指向更早交易;累计weight和sigops不超限;coinbase金额和见证承诺正确;父块、height、time与target一致;模板更新线程能响应longpoll;对拒绝原因留日志。测试还应包含父子交易、链尖切换、空内存池和节点重启。
本文基于Bitcoin Core 31与BIP 22/23,讲的是模板审计,不覆盖Stratum份额分发或矿池结算。版本升级后应重新核对字段和弃用项。
用固定测试向量防止升级回归
矿池升级Bitcoin Core或修改构块器后,应重放一组固定测试向量:含祖先子交易包、接近权重上限的模板、需要见证承诺的coinbase、链尖切换和长轮询断线。比较的不只是最终区块哈希,还包括交易顺序、费用合计、weight、sigops和拒绝原因。这样能发现字段新增、单位误读或排序算法变化造成的静默偏差。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。