钱包是用于发送和接受代币的客户端,就像我们使用邮箱来管理自己的邮件,我们需要一个客户端来管理自己的代币。钱包的本质是保管私钥的工具,私钥就是一串很长的数字和字母组合的字符串,这个字符串让你有权力把自己的数字货币送给别人,换句话说,无论谁知道你的私钥,都可以控制你的数字货币。私钥也用于生成你的代币地址 - 这就像邮箱地址,只有知道地址才能给别人发送代币。然而,尽管代币地址是通过私钥生成的,但是没有办法通过检查数字货币地址来确定私钥是什么。总而言之,钱包的核心功能是私钥的创建、存储和使用。
钱包的类型
私钥不同的生成方法,也对应着不同的钱包结构,通常可以分为非确定性钱包和确定性钱包。比特币最早的客户端(Satoshi client)就是非确定性钱包,钱包是一堆随机生成的私钥的集合。 客户端会预先生成 100 个随机私钥,并且每个私钥只使用一次。每个交易使用一个地址的概念是中本聪提出的。如果交易比较频繁,私钥可能会用光,然后再产生一批私钥,所以每次完成 100 个交易后,你必须备份新的 wallet.dat 文件,否则可能会丢失资产。这种钱包难以管理和备份。如果你生成很多私钥,你必须保存它们所有的副本。这就意味着这个钱包必须被经常性地备份。每个私钥都必须备份,否则一旦钱包不可访问时,无法找回钱包。
确定性钱包则不需要每次转账都要备份,确定性钱包的私钥是对种子进行单向哈希运算生成的,种子是一串由随机数生成器生成的随机数。在确定性钱包中,只要有这个种子,就可以找回所有私钥,只需备份种子就相当于备份您的所有钱包,所以这个种子也相当重要,一定要备份到安全的地方。
什么是 HD 钱包
HD 钱包是目前常用的确定性钱包 ,说到 HD 钱包,大家可能第一反应会想到硬件钱包 (Hardware Wallet),其实这里的 HD 是 Hierarchical Deterministic(分层确定性)的缩写。所谓分层,就是一个大公司可以为每个子部门分别生成不同的私钥,子部门还可以再管理子子部门的私钥,每个部门可以看到所有子部门里的币,也可以花这里面的币。也可以只给会计人员某个层级的公钥,让他可以看见这个部门及子部门的收支记录,但不能花里面的钱,使得财务管理更方便了。
分层确定性的概念早在 BIP32 提案提出。根据比特币核心开发者 Gregory Maxwell 的原始描述和讨论,Pieter Wuille 在2012 年 02月 11日整理完善提交 BIP32 。直到 2016年 6月 15 日 才被合并到 Bitcoin Core,目前几乎所有的钱包服务商都整合了该协议。BIP32 是 HD 钱包的核心提案,通过种子来生成主私钥,然后派生海量的子私钥和地址,但是种子是一串很长的随机数,不利于记录,所以我们用算法将种子转化为一串助记词 (Mnemonic),方便保存记录,这就是 BIP39,它扩展了 HD 钱包种子的生成算法。BIP43 对 BIP32 树结构增加了子索引标识 purpose 的扩展***m/purpose'/ **** 。 BIP44 是在 BIP43 和 BIP32 的基础上增加多币种,通过 HD 钱包派生多个地址,可以同时管理主网和测试网的比特币,BIP44 提出了5层的路径建议,如下:
m/purpse'/coin_type'/account'/change/address_index,
BIP44的规则使得 HD 钱包非常强大,用户只需要保存一个种子,就能控制所有币种,所有账户的钱包。
比特币 HD 钱包是如何生成的?
<figure style="margin: 1em 0px; color: rgb(26, 26, 26); font-family: -apple-system, system-ui, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif; font-size: medium; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;"></figure>
1. 生成一个助记词(参见 BIP39)
2. 该助记词使用 PBKDF2 转化为种子(参见 BIP39)
3. 种子用于使用 HMAC-SHA512 生成根私钥(参见 BIP32)
4. 从该根私钥,导出子私钥(参见 BIP32),其中节点布局由BIP44设置
可以看出 BIP39 生成助记词的过程非常重要, 大家肯定关心 BIP39 的安全性,如果一个 HD 钱包助记词是 12 个单词,一共有 2048 个单词可能性,如何算出随机的生成的助记词所有可能性是一个排列问题,根据公式: n!/( n - r )! ,既 2048!/(2048-12)! = 5.2715379713014884760003093175282 e+39 。
我们可以举个类比,地球上的沙子数量在大约是1 后面 18 个零。如果你可以每秒生成 一百万个助记词,那么一年可以生成 1000000606024365=3.1536e+13**,大约需要 1.6715937e+26年遍历所有助记词,这是多少年呢?
以太坊目前解决方案
以太坊在 EIP84 讨论,是否遵循 BIP32 和 BIP44,社区里提出来很多有意思的观点,比特币是基于 UTXO 的,所以可以使用 HD 钱包(BIP32)为每个交易分配一个新地址,以保护您的隐私。然而,以太坊是基于帐户,每个帐户都有一个地址,BIP 是比特币的提案,而且比特币的数据结构的设计是围绕改变地址的想法构建的,BIP 的一些提案可能并不适合以太坊。以太坊的模式和比特币UTXO 不同,以太坊转账不能改变地址,如果在以太坊上实现 UTXO ,用户还必须签名两个交易以将余额的一部分发送到一个地址,将余额的一部分发送到第二个地址 - 这将使成本增加一倍,而且第二个交易可能不会在同一个区块中,当然以太坊也可以通过智能合约的方式实现。另外,以太坊目前官方钱包采用 KDF 的形式,也就是我们常说的 Keystore 的形式。
在 EIP85 的讨论,以太坊社区似乎默认也采用了 BIP32 的做法,先来说一说 BIP32 的好处
1. 使用时间长,已经接受社区审查
2. 已经有多个编程语言的实现
3. 多个硬件钱包正在使用
4. 可以一个钱包,同时支持比特币和以太坊
EIP85 提议 HD 路径为 : m/44'/60'/a'/0/n
这里 的 a 表示帐号,n 是第 n 生成的地址,60 是在 SLIP44 提案中暂定的,因为 BIP44 只定义到 0 - 31。
目前已知以太坊客户端的具体实现:
- m/44'/60'/0'/0/x: BIP44,imToken(可以自定义路径),MetaMask,Jaxx,MyEtherWallet,TREZOR,Exodus
- m/44'/60'/x'/0/0:BIP44,KeepKey,MetaMask
- m/44'/60'/0'/x:Electrum,Ledger Chrome App,
- m/44'/coin_type'/account'/0:Coinomi
最后
使用单个地址钱包,你的所有交易都将与单个地址相关联,由于区块链所有的交易记录都是公开的,所以任何人都可以看到看到每个地址的所有交易记录以及账户余额。HD 钱包通过在发送和接收资金时能够生成新地址,大大提高隐私性,使你的交易难以追踪。当然匿名性是相对的,现在我们也有隐私性更好的零知识证明算法。HD 钱包是生成不重复使用地址的方法 ,记住一个种子就可以访问所有地址的钱而不需要每个地址都备份私钥。当然HD 钱包不仅适用于比特币,HD 钱包可以让一个钱包同时管理多资产成为可能性。