一段脚本创立一条链:-signetchallenge 自建 signet 的机制账 图 1
一段脚本创立一条链:-signetchallenge 自建 signet 的机制账 · 图 1

比特币核心自带三个测试网络,其中 signet 常被描述成”带中央出块者的测试网”。这句话只说了官方那条公共链,忽略了参数表背后的机制:signet 的本质是一段写在共识参数里的脚本,任何人和一套密钥,都能据此发一条属于自己的链。本文按 v31.0 源码讲清 -signetchallenge 这条参数的机制账:它长什么样、决定什么、不决定什么。

出块权从哪来

源码把 signet 定义为”带额外共识参数的测试网络”。这段额外参数就是一串脚本,称为 challenge。每个新区块的 coinbase 交易的见证承诺里带着一段签名(见证保留值中一个以特定前缀标记的字段),节点验证区块时,把签名填入 challenge 脚本执行——执行成功,区块才有资格进链。公共 signet 的默认 challenge 是一个一签二门限脚本,两个公钥对应中央出块协调方持有的密钥。自己跑链时,你可以把 challenge 换成任意脚本:单个公钥、多签、甚至时间锁结构——出块权从此由你的脚本定义。

链身份的自动隔离

challenge 不只是出块脚本,它还参与定义网络身份:P2P 协议的消息魔数取 challenge 脚本双 SHA256 摘要的前四个字节。两段不同 challenge 的链,魔数几乎必然不同,节点握手时互相视对方为错误网络,自动断开;创世块则所有 signet 共用同一块(固定时间戳与难度位,魔数之外不做区分),链身份的重心完全压在魔数与出块脚本上。这条机制让”误连”——私有测试链的节点漂进别人的链——在协议层就被拦下,而不需要人工约定端口就够了。

参数怎么给,坑在哪

参数值是一段十六进制脚本,且只接受单值:重复传会直接启动失败,非十六进制同样报错。链上运行时会在日志打印当前 challenge,方便核对。私有链场景下有两件事必须自己补齐。其一是出块者:signet 仍然要求真实工作量证明加上合法 challenge 签名,没有协调方持续出块,链就停摆——自建链需要自己跑一个持有私钥的出块进程。其二是种子节点:不配 -signetseednode,新节点无从发现同伴。公共 signet 自带若干种子与默认 DNS 种子,私有链没有这份福利。

共识参数的另一面

signet 的难度调整与主网同源:目标出块十分钟,每两千零一十六块调整,难度上限被一条较高的最小难度界限约束(这就是协调方算力不大也能持续出块的原因),且不因低难度产生免签特权。补贴结构也与主网同表:减半周期二十一万块,初始五十枚,聪的换算一路照搬——换句话说,signet 上是真实运行的完整经济参数,只是资金没有市场价值。钱包、索引、共识参数升级在这条链上的表现,与主网的差距被刻意做到最小。

什么时候用它

相对 regtest 的单机构造,signet 面向多参与方:联合测试一个需要真实传播、真实确认时序、真实节点间博弈的场景,又不承担主网资金风险。相对 testnet4,signet 的出块与难度可控性更好,私有链身份完全自主。选择依据很朴素:单进程自测用 regtest,公开多参与者环境用 signet 或 testnet,生产验证用主网小额。

起链之后的第一步

私有链起步的验证动作很直白:启动日志里核对节点打印出的当前 challenge 与你给出的十六进制逐字一致;随后按 challenge 脚本要求的签名方式,把区块生产到受控地址;再拉一台参数完全相同、但没有出块私钥的第二节点,确认它接受你生产的区块——这一步通过,链才算真正开始运转。第二节点拒收时,先查两个最常见的源头:两侧 challenge 十六进制存在大小写或尾字节差异,以及出块方的私钥并不满足脚本门限。把这条最小验证链走通之后,才值得往上叠加钱包接入、索引部署等更厚的测试场景。

风险提示:本文讨论测试网络参数机制,不构成投资建议;机制描述以比特币核心 v31.0 源码为准,具体部署步骤请以所用版本文档为准。

参考来源