术语表 /地址与密钥
链码
- 链码是什么?
- 链码是 HD 钱包中伴随每个密钥的32字节额外熵,会混入每一次子密钥推导,使人无法从同级密钥推测出其他密钥。
规定于 BIP-32。
每个扩展密钥的一半根本不是密钥。BIP-32将一个512位哈希拆分为256位密钥和256位链码,xpub 字符串同时包含两者,共111个字符。一旦您分享了 xpub,就等于同时分享了链码,接收方正是借此推导出您未来的地址。
运作方式
链码在一次 HMAC 调用中发挥作用。推导子密钥时,运行 HMAC-SHA512,以父链码作为密钥,以父公钥加上4字节的索引作为消息。64字节的结果从中间拆开:左边的32字节与父私钥相加后按曲线阶取模,得到子私钥;右边的32字节成为该子密钥自己的链码,用于推导它自己的子密钥。
这个盐值的意义在于决定谁能遍历这棵密钥树。单独的公钥推导不出任何东西,因为没有对应的链码,推导函数就无法运行。因此,扩展公钥并不只是名字更长的公钥,而是公钥加上其链码;把这一对数据交给他人,就把曲线上的一个点变成了您尚未使用的、可枚举且数量不限的一整支地址。
BIP-32记录了由此而来的一个隐患。如果攻击者持有您的扩展公钥,又拿到了某一个非硬化子私钥,减去推导出的偏移量就能还原出父私钥,进而得到所有同级密钥和所有后代密钥。硬化推导正是为切断这条路径而设:在硬化的步骤中,被哈希的消息包含的是父私钥而不是公钥,因此无论掌握多少公开材料,任何人都无法向上回溯。
在哪里会遇到它
您从不需要输入链码,也没有任何消费级钱包会单独显示它。链码包含在扩展密钥之内。以 xpub 或 xprv 开头的 Base58Check 字符串解码后为78字节,排列为:4字节版本、1字节深度、4字节父密钥指纹、4字节子密钥编号、32字节链码,最后是33字节密钥,因此一个 xpub 的文本长达111个字符。
在开发者工具中,这个字段才作为独立字段显现出来。Bitcoin Core 的 deriveaddresses RPC 处理的是嵌入了扩展密钥的描述符;python-bip32 等库会把链码作为单独的属性返回;签名设备为仅观察设置导出账户时,导出的正是这一对数据。
应有的谨慎程度,应当等同于对待完整交易记录,而不是对待密码。链码无法签名,因此单独泄露不会让您损失资金。但如果落入分析公司、云备份或任何把 xpub 粘贴进支持工单的人手中,该分支上过去和未来的每一笔付款都会暴露,而且事后无法撤销这一访问权限。
链码 vs 私钥
链码和私钥都是32字节看似随机的数据,但只有其中一个能够花费资金。私钥用于生成签名,链码除了产生更多推导之外什么也不产生,人们正因此低估了它:由于它无法转移资金,一些绝不会对私钥这样做的人,会把扩展公钥粘贴进共享表格、错误报告和手机应用。结果不是被盗,而是自己的财务状况从此永久暴露,这两种失误应当有不同的名称。