区块链 第9.1章 HD钱包 区块链 第9.1章 HD钱包

1天前

一、HD 钱包

在比特币的链上,实际上并没有账户的概念,某个用户持有的比特币,实际上是其控制的一组 UTXO,而这些 UTXO 可能是相同的地址(对应相同的私钥),也可能是不同的地址(对应不同的私钥)。

出于保护隐私的目的,同一用户如果控制的 UTXO 其地址都是不同的,那么很难从地址获知某个用户的比特币持币总额。但是,管理一组成千上万的地址,意味着管理成千上万的私钥,管理起来非常麻烦。

能不能只用一个私钥管理成千上万个地址?实际上是可以的。虽然椭圆曲线算法决定了一个私钥只能对应一个公钥,但是,可以通过某种确定性算法,先确定一个私钥 k1,然后计算出 k2、k3、k4……等其他私钥,就相当于只需要管理一个私钥,剩下的私钥可以按需计算出来。

这种根据某种确定性算法,只需要管理一个根私钥,即可实时计算所有“子私钥”的管理方式,称为 HD 钱包。

HD 是 Hierarchical Deterministic 的缩写,意思是分层确定性。先确定根私钥 root,然后根据索引计算每一层的子私钥:

https://file.lulublog.cn/images/3/2025/11/C1222HUW2gum1whUHB2I1GIWZj2LYU.png

对于任意一个私钥 k,总是可以根据索引计算它的下一层私钥 kn:

https://file.lulublog.cn/images/3/2025/11/l33f1n01gg1MB46r35tm451fRZ5RF1.png

即 HD 层级实际上是无限的,每一层索引从 0~2 的 32 次方,约 43 亿个子 key。这种计算被称为衍生(Derivation)。

现在问题来了:如何根据某个私钥计算下一层的子私钥?即函数 hdkey(k, n) 如何实现?

HD 钱包采用的计算子私钥的算法并不是一个简单的 SHA-256,私钥也不是普通的 256 位 ECDSA 私钥,而是一个扩展的 512 位私钥,记作 xprv,它通过 SHA-512 算法配合 ECC 计算出子扩展私钥,仍然是 512 位。通过扩展私钥可计算出用于签名的私钥以及公钥。

简单来说,只要给定一个根扩展私钥(随机 512 位整数),即可计算其任意索引的子扩展私钥。扩展私钥总是能计算出扩展公钥,记作 xpub:

https://file.lulublog.cn/images/3/2025/11/lyicY5ybjWiBQ9IVbQPBbVfvY2wGI4.png

从 xprv 及其对应的 xpub 可计算出真正用于签名的私钥和公钥。之所以要设计这种算法,是因为扩展公钥 xpub 也有一个特点,那就是可以直接计算其子层级的扩展公钥:

https://file.lulublog.cn/images/3/2025/11/Vk68I06V70fIaF2f66eIV220BZt2Ab.png

因为 xpub 只包含公钥,不包含私钥,因此,可以安全地把 xpub 交给第三方(例如,一个观察钱包),它可以根据 xpub 计算子层级的所有地址,然后在比特币的链上监控这些地址的余额,但因为没有私钥,所以只能看,不能花。

因此,HD 钱包通过分层确定性算法,实现了以下功能:

  • 只要确定了扩展私钥 xprv,即可根据索引计算下一层的任何扩展私钥;

  • 只要确定了扩展公钥 xpub,即可根据索引计算下一层的任何扩展公钥;

  • 用户只需保存顶层的一个扩展私钥,即可计算出任意一层的任意索引的扩展私钥。

从理论上说,扩展私钥的层数是没有限制的,每一层的数量被限制在 0~2 的 32 次方,原因是扩展私钥中只有 4 字节作为索引,因此索引范围是0~2 的 32 次方。

通常把根扩展私钥记作 m,子扩展私钥按层级记作 m/x/y/z 等:

https://file.lulublog.cn/images/3/2025/11/h7tQQQN8TqlIn6rTzGvFigvZct7ZrB.png

例如,m/0/2 表示从 m 扩展到 m/0(索引为 0)再扩展到 m/0/2(索引为 2)。

二、安全性

HD 钱包给私钥管理带来了非常大的方便,因为只需要管理一个根扩展私钥,就可以管理所有层级的所有衍生私钥。

但是 HD 钱包的扩展私钥算法有个潜在的安全性问题,就是如果某个层级的 xprv 泄露了,可反向推导出上层的 xprv,继而推导出整个 HD 扩展私钥体系。为了避免某个子扩展私钥的泄漏导致上层扩展私钥被反向推导,HD 钱包还有一种硬化的衍生计算方式(Hardened Derivation),它通过算法“切断”了母扩展私钥和子扩展私钥的反向推导。HD 规范把索引 0~2 的 31 次方作为普通衍生索引,而索引 2  的 31 次方~2 的 32 次方作为硬化衍生索引,硬化衍生索引通常记作0'、1'、2'……,即索引 0'=2 的 31 次方,1'=2 的 31 次方 +1,2'=2 的 31 次方 +2,以此类推。

因此,m/44'/0 表示的子扩展私钥,它的第一层衍生索引 44' 是硬化衍生,实际索引是2 的 31 次方 +44=2147483692。从 m/44' 无法反向推导出 m。

在只有扩展公钥的情况下,只能计算出普通衍生的子公钥,无法计算出硬化衍生的子扩展公钥,即可计算出的子扩展公钥索引被限制在0~2 的 31 次方。因此,观察钱包能使用的索引是0~2 的 31 次方 。

三、BIP-32

比特币的 BIP-32 规范详细定义了 HD 算法原理和各种推导规则,可阅读此文档以便实现 HD 钱包。

四、小结

HD 钱包采用分层确定性算法通过根扩展私钥计算所有层级的所有子扩展私钥,继而得到扩展公钥和地址;

可以通过普通衍生和硬化衍生两种方式计算扩展子私钥,后者更安全,但对应的扩展公钥无法计算硬化衍生的子扩展公钥;


通过扩展公钥可以在没有扩展私钥的前提下计算所有普通子扩展公钥,此特性可实现观察钱包。

阅读 17