协议演进 / BIP/比特币改进提案 / BIP-145
BIP-145
扩展 getblocktemplate 挖矿接口,让区块模板能表达见证交易、权重上限与见证承诺的组装方式。本 BIP 目前处于已部署状态。
一、档案卡
| 编号 | BIP-145 |
|---|---|
| 标题 | getblocktemplate Updates for Segregated Witness |
| 作者 | Luke Dashjr <[email protected]> |
| 指定日期 | 2016-01-30 |
| 层级 | API/RPC(接口) |
| 类型 | Specification(规范类) |
| 状态 | Deployed(已部署) |
| 阅读版 | https://bips.dev/145 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki |
二、放在哪一族
挖矿接口族中专为隔离见证打的补丁。getblocktemplate(GBT)是矿工与矿池向节点索要“待挖区块模板”的 JSON-RPC 接口,基础规范在 BIP-22(基础)与 BIP-23(矿池挖矿);版本位与规则协商牵涉 BIP-9。
同族关系:
BIP-141:隔离见证(共识层),本篇是它在挖矿接口上的对应更新
BIP-22 / BIP-23:getblocktemplate 的原规范,本篇只做增补
BIP-144:隔离见证(对等服务),管节点间传输;本篇管节点与矿工之间的模板接口
三、它要解决什么
隔离见证实质改变了区块的结构:交易多出一份见证数据,区块的资源计量也从单纯的字节数变成“权重”。原文的动机说得很直接:区块结构变了,原来的 getblocktemplate 规范就不够用了;新的计量方式也必须能通过 GBT 正确传达给挖矿一方。
具体缺口有三处:
- 模板里没有字段告诉矿工“这个区块最多能装多少权重”;
- 模板中的交易条目分不清 txid 与包含见证的完整哈希,矿工无法正确组装;
- 见证承诺(witness commitment)需要放进 coinbase 交易,这个动作由谁做、放在哪个位置,原规范没有规定。
不补这三处,矿池软件就算连着支持 SegWit 的节点,也挖不出合规的见证区块。
四、规则本身
4.1 模板新增 weightlimit
模板对象新增一个可选键:
- weightlimit(Number,非必填):区块允许的总权重。
同时,“segwit”规则的启用方式被收紧:只要模板包含带见证数据的交易,模板的 “rules” 列表中就必须给 “segwit” 加上 “!” 前缀(表示强制规则)。
原文还留了向下兼容的口子:即便客户端提交的 “rules” 里没有 “segwit”,服务端也可以为老矿工生成不含见证的模板,此时 “segwit” 不加 “!” 前缀;但如果服务端在激活后已不能生成无见证模板,则必须在激活之前的 “vbavailable” 列表里就对 “segwit” 使用 “!” 前缀,让客户端提前知晓。
4.2 交易条目新增 txid 与 weight
模板 “transactions” 列表中的每个交易对象修订为包含:
- txid(String,十六进制):交易 ID;对带见证数据的交易为必填;
- weight(Number):该交易按区块 weightlimit 口径计算的权重;若该键缺失,表示权重未知,客户端不得假定为零,但可以自行计算;
- hash(String,十六进制):完整交易(含见证数据)哈希的反序编码,即 wtxid 口径。
并且:只有当模板的 “rules” 列表包含 “segwit” 时,带见证数据的交易才可以被放进模板。
4.3 sigops 按新口径计算
启用 “segwit” 规则的模板中,“sigoplimit” 与 “sigops” 两键必须使用 BIP-141 规定的新计算值,而不是旧的签名操作计数方式。
4.4 组装带见证交易的区块
不含见证交易时,组装方式与从前完全相同,本篇不作任何改变。包含见证交易时:
- 主默克尔根必须用各交易的 “txid” 字段计算,而不是 “hash”;
- 还必须按 BIP-141 的承诺结构算出第二棵默克尔根(见证承诺),插入 generation(coinbase)交易;
- 服务端不得把承诺预先放进模板的 “coinbasetxn” 键;客户端必须把承诺作为一个额外输出,加在最终 coinbase 交易的末尾;
- 唯一的例外:若模板的 “mutable” 键(见 BIP-23)包含 “generation”,客户端可以把承诺输出放在任意位置,前提是其后没有另一个输出与承诺的样式冲突。
原文为这些安排给了理由:承诺固定放在末尾,不允许修改 coinbase 输出的服务端就能在校验提交时先剥掉承诺、再逐字节比对输出;若由服务端预先塞进 coinbasetxn,客户端将失去构造承诺所需的信息,也与 GBT 作为去中心化挖矿协议、让客户端能看清区块内容的初衷相悖。
4.5 两个“为什么不顺手改名”的取舍
- 为什么不用 weightlimit 取代旧的 sizelimit?因为 sizelimit 已被客户端按交易 “data” 键的字节总和执行,而且服务端可能想同时独立限制区块的字节大小与权重。
- 为什么 sigoplimit 是重新定义而不是新设 sigopweightlimit?因为旧上限本来就是人为定的,客户端自己也算不出来;所谓“sigop 权重”只是人为公式的一次变更。
五、谁必须动
普通持币人:完全无感。本篇只发生在节点与挖矿软件之间。
钱包开发者:一般不需要处理;只有自建挖矿或矿池相关工具时才涉及。
全节点与矿工:提供 GBT 的节点服务端要按本篇返回 weightlimit、txid、weight 等字段,并执行 “segwit” 规则的前缀约定;矿池与挖矿客户端要按 4.4 的方式组装 coinbase、计算双默克尔根,否则提交的区块会不合规。
共识层:本篇不修改共识规则。它只是把 BIP-141 已经定下的权重、承诺结构等共识事实,翻译成挖矿接口上的字段与组装步骤。
六、现在算不算数,以及一个常见误读
状态为 Deployed(已部署)。作为接口规范,它的效力体现在实现之间:节点与矿池软件按同一套字段对话,SegWit 区块才能被正常构造。原文列出的参考实现包括 libblkmaker、Eloipool 的 segwit 分支与比特币核心的相应合并请求;本页不超出原文去断言今天各矿池的采用细节。
常见误读:
“BIP-145 提高了区块上限。”
不对。本篇没有设定任何新的上限数值,它只是新增 weightlimit 字段,把 BIP-141 引入的权重计量传达给矿工。把旧的字节口径换成权重口径的是共识层,GBT 只是“负责把话带到”。
七、延伸
- 阅读版:https://bips.dev/145
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki
- 相关:BIP-141 隔离见证(共识层)、BIP-22 getblocktemplate 基础、BIP-23 getblocktemplate 矿池挖矿、BIP-9 版本位
- 仓库总目录:https://github.com/bitcoin/bips
