精通以太坊5:钱包

精通以太坊5:钱包

钱包,在以太坊中代表几种不同的东西

抽象一些来说,钱包主要是一个用户界面。钱包控制对以太币的访问,管理私钥和地址,跟踪账户的余额,创建并签名交易。另外,有些以太坊钱包还可以跟智能合约交互,比如管理ERC20代币。

从更聚焦的角度而言,根据是从程序员的角度,钱包这个词特指用来存储和管理用户密钥的系统。每个钱包都包含一个密钥管理系统。针对一些钱包,可能这就是它唯一的模块。有些钱包可能在此基础上有更广的功能,例如;担当基于以太坊去中心化应用或者DApp的入口。目前并无针对钱包各种分类的明确的定义和界限。

5.1 钱包技术概述

在设计钱包时,一个关键的考量就是权衡便利性与隐私性。最方便的以太坊钱包就是单一私钥和对应地址,在每个场合中都使用同一个地址。但是,这样的解决方案就是隐私上的噩梦,因为任何人都可以轻松跟踪你的交易并将他们关联起来。为每一笔交易都使用一个新私钥对隐私性来说当然是最好的了,但这样就很难管理私钥。最佳平衡点并不容易把握,但这也解释了为什么钱包的设计是最重要的。

一个针对以太坊钱包的常见误解是认为钱包中包含以太币或者代币。实际上,钱包中只保存了密钥。以太币和其他各种代币都保存在以太坊区块链上。用户使用钱包中保存的密钥来签名交易,进而控制属于他们的以太币或代币。简单的说,以太坊钱包就是一个钥匙圈。话虽如此,因为钱包保存的私钥便是将以太币以及代币发送给他人唯一需要的东西,所以这种定义上的差别在实际上就变得无关紧要了。这种差别真正重要的地方是改变一个人将钱包当作传统银行的中心化系统的心态(认为只有你及银行可以看到你账户中的钱,要转账时,只需告诉银行你确实有此愿望),转变为将其当成区块链平台的去中心化系统。系统中的每个人都可以看到账户余额,虽然他们可能不知道账户的主人是谁,而主人要转账时需要说服每一个人。在实践中,这就意味着有一种独立的方式可以检查账户余额,无须通过主人的钱包。并且,如果你不喜欢自己一开始用的钱包,大可将钱包中的账户转移到另一个钱包上。

以太坊钱包内含密钥,而不是以太币或代币。钱包就是包含了一对私钥和公钥的钥匙圈。用这些私钥签名交易,用户就可以证明自己对以太币的所有权,以太币本身就是保存在区块链之上的。

钱包主要分两类,取决于它所保存的密钥之间是否存在关联。

第一类是非确定性钱包,其中保存的每一个私钥都是通过不同的随机数相互独立生成的。私钥之间没有任何关联。这类钱包被称为JBOK(Just a Bunch Of Keys)钱包。

第二类钱包是确定性钱包,其中所有的密钥都是从一个主密钥衍生而来的,这个主密钥就是种子密钥。这类钱包中所有的密钥之间都存在关联关系,如果获得了“种子密钥”,则可以重新生成所有密钥。确定性钱包有多种密钥派生方法。最常用的派生方法是使用一个类似树形的结构,我们称之为层级式确定性(hierarchical deterministic)钱包,或者简称为HD钱包。

为了让确定性钱包在对抗数据丢失事件(比如手机失窃)时,稍微安全一点,我们一般会将种子编码为一个英文词列表(当然也可以使用其他语言),你可以将其抄写下来并在意外发生时使用。这样的列表就是钱包助记词。当然,如果有人得到了这些助记词,他们也可以重建你的确定性钱包,进而控制你的以太币和智能合约。因此,妥善保存助记词!

最后写在纸上,不要进行电子存储。

5.2非确定性(随机)钱包

以太坊第一版钱包(用于以太币预售阶段)的钱包文件保存了一个随机生成的私钥。这类钱包正在被确定性钱包所取代,因为他们管理,备份和使用起来都非常麻烦。举个例子:

在使用以太坊时,避免重用密钥是保护隐私的好方法,即每次接收资金时都要使用新地址(这样也需要新私钥)。你甚至可以每做一笔交易都使用一个新地址,虽然这样做费用不菲(如果有很多代币需要处理的话.但是,随机密钥的缺点在于当你创建了多个随机密钥之后,必须备份所有密钥。如果不小心弄丢了其中的一个私钥(硬盘损坏,喝醉酒,手机被偷等。就无法访问你的资金和智能合约了。

Type 0非确定性钱包并不是一个特别好的选择,尤其是在用户希望避免重用以太坊地址的情况下(即所有地址都是“一次性”的)每增加一个新地址都需要创建一个新的钱包文件

很多以太坊客户端软件中的钱包(包括geth)使用JSON格式的keystore文件来保存单独(随机生成)的私钥。这个文件使用额外的密码来进行加密,以确保安全。JSON文件的内容如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rZHkDdNU-1585387260029)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583575855720.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y1wBwarT-1585387260030)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583575872290.png)]

keyStore的格式遵循密钥导出函数(Key Derivation Function,KDF),这也被称为增强式密码算法,用于防止对文件的密码进行暴力,字典或彩虹表攻击。简单地说,JSON文件中的私钥并不是被密码直接加密的,相反,密码会通过连续的哈希运算进行扩展(然后再进行加密运算).哈希计算重复262144轮,这个参数可以在JSON的crypto.kdfparams.n参数中看到。任何企图暴力破解密码的尝试,都必须经过262144轮的哈希计算,这会极大地降低攻击的速度,在密码长度和复杂度足够的情况下,暴力猜测密码的攻击不再有效(密码本身复杂度x262144轮哈希,计算量会非常大)

有多种软件程序库可以读取和写入keystore格式,例如:JavaScript库Keythereum(https://github.com/ethereumjs/keythereum)

除非是简单的测试场景,否则不推荐使用非确定性钱包。这类钱包的备份和使用都非常麻烦。正确的选择是使用业界标准的,采用助记词进行种子密钥备份的层级式确定性钱包。

5.3确定性(种子密钥)钱包

确定性钱包或基于种子密钥的钱包,包含了从同一个种子密钥(或者叫主密钥)所派生的私钥。种子密钥是一个随机生成的数字,它与其他的数据(例如索引号或’链码’)一起用于生成私钥。在确定性钱包中,种子密钥就可以用来恢复所有的派生密钥,因此在创建钱包时备份种子密钥就足以保护资金和智能合约的安全了。种子密钥也可以用来进行钱包的导入或者导出操作,一次性把钱包中的所有派生密钥在不同的钱包软件中迁移。

这种设计也使得种子密钥的安全变得极端重要,因为只要拥有种子密钥就可以获得整个钱包的访问权限。但从另一个角度来说,将安全性相关的注意力集中到一段数据上也可以被视为一个优点。

5.4层级式确定性钱包(BIP-32/BIP-44)

开发确定性钱包的目的是让人们可以更容易地从单一的“种子”中衍生出多个密钥。,目前,确定性钱包最高级的形式便是由比特币的BIP-32标准的(http://bit.ly/2B2vQWs)定义的HD钱包。HD钱包可以保存用树状结构推导的多个密钥,比如:一个私钥可以推导出一系列子密钥,每个子密钥都可以推导出一系列孙子密钥,以此类推至于无穷。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p53zzUuJ-1585387260031)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583579330726.png)]

相比随机非确定性钱包,HD钱包有两个主要好处。首先,树形结构可以用来表示组织结构的含义,例如:一组密钥专门用来收款,另外一组专门用来付款。也可以把这样的结构跟公司的组织架构对应,把树形结构的分支跟部门,取悦,具体的职能或公司内部的账户分类相匹配。

第二个好处是 HD钱包的用户可以创建一系列公钥,这个过程不需要访问对饮搞得私钥。这样就允许HD钱包被用在相对不安全的服务器上,或者专门用于收款,这时候钱包中不需要保存可以操作以太币的私钥信息。

5.5种子密钥和助记词(BIP-39)

要安全的备份和恢复私钥有很多种方法。当前最受好评的方法是使用一组有序的单词,只要可以将这些单词组成正确的序列,就可以重建出一把独一无二的私钥。这就是我们说的助记词,这一方法由BIP-39标准化了。今天,很多以太坊钱包软件(包括其他数字货币的钱包软件0都使用这个标准。支持使用助记词进行种子密钥的导入导出和备份恢复

要理解这一方法是如何流行起来的。我们先看一个例子:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xuhRC6ni-1585387260032)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583579860534.png)]

从实用的角度来说,写下十六进制序列时出错的概率出奇的高。相反,常见单词的序列则非常容易处理。这主要是因为单词有很高的冗余性,尤其是英语单词。如果意外记录了“inzect”这个单词,在需要恢复钱包时,你很快就会意识到“inzect"不是单词,应该 "insect"才对。

助记词其实就是种子的代表,我们这样做(*写助记词而不记录种子),是因为这是惯例HD钱包的上佳选择:在数据丢失(无论是意外还是偷窃)的情况下,种子是恢复钱包唯一需要的东西,所以备份时应当非常谨慎。当然,种子必须保管的非常安全,因此绝对不应该使用电子备份,最好纸质备份。

总之,使用助记词列表编码HD钱包中的种子,给了我们一种极为简单的方式来安全的导出,描述,用纸记录并无误的阅读私钥,以及将他导入到另一个钱包中。

5.6钱包的最佳实践

数字货币的钱包技术和标准正在逐步成熟,一些行业标准也正在推动钱包软件之间更广泛的交互性和易用性,安全性和灵活性。这些标准也允许钱包软件从单一的种子密钥为多种数字货币派生密钥,这些标准包括:

》基于BIP-39助记词标准

》基于BIP-32的层级式确定性钱包标准

》基于BIP-43的多用途层级式确定性钱包结构

》基于BIP-44的多币种和多账户钱包

随着未来开发的推进,这些标准可能被改变,甚至可能被遗弃,但是目前而言,这些标准构成了一系列互相关联的技术,是大多数数字货币钱包实现的事实标准。

这些标准已经被大量的软件和硬件钱包所采用,使得这些钱包之间可以互相操作,导入导出。用户可以把其中一个钱包生成的助记词导出,导入到另一个钱包中,从而迁移所有的密钥和地址。

一部分支持这些标准的软件钱包包括Jaxx,MetaMask,MyCrypto和MyEtherWallet(MEW).一部分支持这些标准的硬件钱包包括Keepkey,Ledger 和 Trezor

如果你正在开发一款以太坊钱包,最好把它做成HD钱包,带有一个经过助记词编码的“种子密钥”用于钱包的备份,并遵循前面列出的这些标准(BIP-32,BIP-39,BIP-43和BIP-44)

5.7助记词标准(BIP-39)

助记词中的单词代表用来生成钱包的种子密钥中的内容。这一串助记词足够用来重新创建种子密钥,进而恢复整个钱包中所有从这个种子派生而来的密钥。实现了带有助记词功能的确定性钱包软件会在用户创建钱包后,展示一组12或24个单词组成的字符串。这一串字符就是用来备份钱包的助记词,可以用来在同样支持这些标准的钱包中恢复和重建所有的密钥。助记词让钱包的备份变得容易,因为相比之前的一串随机数,这些助记词更易读也更容易记录。

助记词通常会跟“脑钱包”(brainwallet)混淆在一起。这两个并不是一回事。主要的区别在于,脑钱包的’助记词’是由用户自己选择的,而确定性钱包中的助记词是由系统生成 并展示给用户的。这个区别使得确定性钱包的助记词更加安全,因为用户自己想出来的“助记词”通常不够安全。也许更重要的一点是,“脑钱包’'这个词暗示着你必须把助记词在脑子里记下来,但这其实并不是一个好办法,代替不了定期备份

助记词是由BIP-39定义的,请注意BIP-39只是助记词标准的一种实现。Electrum比特币钱包和一些较早期的钱包还有其他的实现方法,采用的助记词清单也不一样。BIP-39标准是由硬件钱包厂商Trezor提出的,与以太坊的实现并不兼容。然而,BIP-39现在已经在业界广泛接授。有众多兼容的这个标准的钱包,因此可以被视为业界的事实标准。更进一步,BIP-39可以用来生成支持以太坊的多币种钱包,而Electrum的种子密钥是做不到的。

BIP-39定义了一个与种子密钥相对应的一组助记词,我们将在下面的步骤中一探究竟。为了清晰可见,我们把这些步骤分成两部分:

第一部分包含6个步骤,第二个部分包含3个步骤。

生成助记词

助记词是由钱包根据BIP-39所定义的标准流程自动生成。钱包从随机源获取一个随机数然后添加校验码,再把这个数字映射为一串英文单词:

1.创建一个 128比特或256比特的密码学强度的随机数,我们姑且称之为 S

2.取出S的SHA-256的哈希值的前(S的长度/32)比特,作为随机数S的校验值。

3.将上一步取得的校验值加到随机数S的末尾

4.以11比特为单位,将随机数S与校验值的结合数分成多个组

5.将每一个11比特的值都根据预先定义的字典映射为单词(这个字典包含2048个简单的英文单词,正好覆盖所有11比特的可能范围)

6.保持初始的次序,得出的单词字符串即我们所需的助记词。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7BhCodDG-1585387260033)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583584649950.png)]

表5-1显示了随机数据的长度与助记词数量之间的关系。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-02JNuTW6-1585387260035)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583584794417.png)]

从助记词到种子密钥

助记词代表128比特或256比特的随机数。使用密钥扩展算法。比如:PBKDF2,可以将这个随机数衍生成512比特长的种子,进而用来构建确定性钱包和派生其他密钥。

密钥扩展算法需要两个参数:助记词和盐(salt)加盐的目的是防止通过循环表格的方式来实现暴力破解。在BIP-39标准中,加盐还有另外一个目的:引入额外的密码来保护种子密钥

下面的步骤7~9跟在上述流程后面,推导出种子密钥;

7.PBKDF2密钥扩展算法的第一个参数是步骤6中产生的助记词

8.PBKDF2密钥扩展算法的第二个参数是“盐”,盐的内容是由用户提出,可以是一个可选的密码,并跟“

mnemonic"组合在一起

9.PBKDF2针对助记词和盐进行2048轮哈希运算,使用的是HMAC-SHA512算法,产生一个512 比特的数作为最终输出。这个数字就是种子密钥。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cX7wMKuk-1585387260036)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583585398931.png)]

密钥扩展算法使用2048轮哈希计算,在防止针对助记词或密码的暴力破解中可以起到一定的保护作用。它使得进行上千次密码和助记词的组合破解的计算大幅度上升,而且可能的种子范围非常巨大(2512,约为10154)-------远远大于宇宙中可见的原子数量(约为10^80)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yMg2ZAzk-1585387260037)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583594886001.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YNyPwXn2-1585387260038)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583594919203.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bx6s31a7-1585387260039)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583594929971.png)]

BIP-39中的可选密码

BIP-39标准允许用户在生成种子密钥的过程中使用可选密码。如果用户没有设定密码,那么默认使用字符串“mnemonic"进行助记词的密钥扩展运算。生成一个特定的512比特的种子密钥。如果用户提供了密码,那么对于同样的助记词,密钥扩展运算会生成完全不同的种子密钥。实际上,给定一组助记词,每个密码都会导致不同的种子密钥。特别是,这里没有正确的或者错误的密码,所有密码都可以生成用来衍生无数钱包地址的种子密钥。可能的钱包范围非常巨大(2^512),如果密码的复杂度足够强,那么暴力破解或猜测都没有可能实现。

在BIP-39中,没有正确的或者错误的密码。任何密码结合助记词都对应着一个钱包,如果这个钱包之前都没有使用过,那么他就是空的。

可选密码会带来两个重要的功能:

》作为助记词的第二道法防线:如果助记词备份泄露,密码是助记词和钱包种子密钥安全的第二道防线

》作为“干扰’钱包:密码指向的钱包只包含小额资金,用来把攻击者的注意力从真正包含大量资金的钱包上吸引开。

然而,使用密码的风险,需要特别注意;

如果钱包的所有人丧失行为能力或者去世,在没有人知道密码的情况下,这个助记词是没有用的,钱包中的资金将永远被锁定。

对应的,如果钱包的所有人把助记词和密码备份在一个地方,那么密码就失去了第二道防线的作用。

密码非常有用,他的备份和恢复必须被认真对待。需要考虑到密码持有人的意外情况。

使用助记词

BIP-39实现了针对多种编程语言的程序库

python-mnemonic(https://github.com/trezor/python-mnemonic)SatoshiLabs团队采用Python语言基于BIP-39的一个参考实现。ConsenSys/eth-lightwallet(https://github.com/ConsenSys/eth-lightwallet)使用BIP-39的Lightweight JS以太坊钱包,用于节点和浏览器环境。npm/bip3918(https://www.npmjs.com/package/bip39)BIP-39的JavaScript实现:助记词用于生成确定性密钥。也有通过网页实现的独立的BIP-39生成器(见图5-4),这对于测试和实验环境是非常有帮助的。Mnemonic CodeConverter(https://iancoleman.io/bip39)这个网站可以用于生成助记词、种子密钥和经过扩展的私钥。网站可以在离线的浏览器环境中使用,也可以在线上使用。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ys9WAhGf-1585387260040)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583596019967.png)]

5.8从种子密钥创建层级式确定性钱包

HD钱包是通过唯一的种子密钥创建的,这个密钥是一个128,256或者512比特的随机数。通常情况下,这个种子密钥是由之前介绍的助记词生成的。

HD钱包中的每一个密钥都是从这个种子密钥派生而来的,这使得可以通过相同的种子密钥在兼容的HD钱包中恢复所有的密钥。这使得即使包含了数千甚至上百万密钥的HD钱包的备份,恢复,导入,导出都变得容易,只需要在钱包之间迁移用来生成种子密钥的助记词即可。

5.9层级式确定性钱包标准(BIP-32)和路径定义标准(BIP-43/44)

大多数HD钱包都遵循BIP-32标准,这已经称为确定性钱包的事实性行业标准

我们不会在这里介绍BIP-32的细节,只讨论用于理解钱包如何工作的一些组件。最重要的部分就是

树形结构,这种结构使我们能够持有推导出的私钥。同样重要的是理解扩展密钥和增强密钥的概念,下文会逐一解释。

有很多基于不同编程语言且可以相互交互的BIP-32实现(软件库)。这些软件库大部分是为比特币钱包设计的,它们使用不同的方式实现比特币地址,但所用的密钥推导实现是一样的,包括以太坊的兼容BIP-32的钱包也是如此。

你可以使用为以太坊设计的钱包(https://github.com/ConsenSys/eth-lightwallet),或者使用比特币钱包但加入一个以太坊地址编码库。

也有作为独立网址(http://bip32.org/)的BIP-32生成器,对测试和实验来说都是很有用的。

这个独立的BIP-32生成器网站并不支持HTTPS。因此,使用这个工具并不安全。这只适用于测试环境,不应该在带有真正数字货币的生产环境中使用这个网址生成的密钥。

扩展的公钥和私钥

在BIP-32的术语中,密钥可以被扩展。使用正确的数学运算,经过扩展的“父”密钥就可以被用来推导出“子‘密钥,并因此产生密钥和地址的树状层级结构。父密钥不一定位于树的顶端,但无论位于哪一层级,它们都可以被抽离出来。扩展一把密钥包括取得这把密钥本身以及附加上一个独特的链码,链码是一段256比特的二进制字符串,与原密钥混合之后用来产生子密钥。

如果密钥是私钥,则扩展后就成为扩展密钥,用前缀xprv表示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dsno1DH5-1585387260040)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583642304360.png)]

扩展公钥则用前缀xpub表示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oFhkih6E-1585387260042)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583642341386.png)]

HD钱包的一个非常有用的特性就是可以从父公钥派生子公钥,而这个过程并不需要使用私钥。因此有两种方式可生成子公钥:既可以使用子公钥,也可以使用对应的父公钥。

因此,扩展的公钥可以用来生成HD钱包对应分支中所有的公钥。

这样的捷径可以用来创建非常安全的公钥,只在服务器或者应用中部署公钥以作为扩展公钥,而不需要私钥。这类部署可以生成任意数量的公钥和以太坊地址,但是因为没有私钥,就不能花费任何转入这些地址的以太币。同时,在更加安全的服务器或者环境中保存的扩展私钥,可以用来生成地址对应的私钥并通过签名交易来花费这些地址上的代币。

这个方案的常见应用是把扩展的公钥安装在运行电子商务应用的WEB服务器上。WEB服务器可以使用扩展公钥的派生功能针对每一笔交易(例如客户的购物车)创建新的以太坊地址,而WEB服务器本身不会有任何可能导致以太币丢失的私钥。如果没有HD钱包,实现这种应用的唯一办法就是事先在一个隔离的安全服务器上生成数以千计的以太坊地址,然后把它们导入电子商务服务器上。这样流程非常繁琐,需要经常维护服务器才能确保密钥不会被用完。因此,推荐使用HD钱包的扩展公钥。

这个方案的另一项广泛应用是冷钱包或硬件钱包。在这类情况下,扩展私钥可以保存在硬件钱包中,扩展公钥可以放在网上。这样用户可以创建收款地址,同时对应的私钥被安全地保存在离线环境中。为了花费这些以太币,用户可以使用扩展私钥在线下或者硬件钱包设备上签名对应的交易。

增强的子密钥生成过程

从扩展公钥派生出分支公钥这个功能非常有用,但是也有潜在的风险。访问扩展公钥并不能对应子公钥的访问。然而,由于扩展公钥带有链码,如果子私钥被人获取或者泄露,那么结合链码1,就可以派生出所有其他的子私钥。通过泄露的子私钥和父链码,可以推算出所有的子私钥。更糟糕的是,子私钥和父链码结合在一起,可以推算出对应的父私钥。

为了消除这个风险,HD钱包使用了另外一种派生算法,称为增强派生,这个算法打破了父公钥和子链码之间的关联。增强派生算法使用父私钥来生成子链码,而不是父公钥。这样就在父子两个密钥序列之间建立了防火墙,通过链码无法推算父私钥及兄弟私钥。

简单地说,如果你想借助扩展公钥方便地派生一组子公钥,同时避免暴露链码的风险,那么就应该采用增强派生算法,而不是常规算法。作为最佳实践,第一层的密钥总是采用增强派生算法得来的,这样就可以保证最重要的种子密钥的安全。

普通和增强情况下的索引码

显然,我们希望能从给定的父密钥中推导出多个子密钥。为了管理这些子密钥,BIPP-32使用了索引码。每一个索引码只需要配合父密钥使用特定的子密钥派生方法,都可以产生一个不同的子密钥。在BIP-32的密钥推导函数中使用的索引码是一个32位的整数。为了方便地把通过派生方法和增强派生方法所产生的子密钥区别开来,索引码被分为两个范围:0和231-1之间的索引码(从0x0到0x7FFFFFFF)用于·普通派生算法,231和232-1之间的索引码(从0x80000000到0xFFFFFFFF)用于增强派生算法。因此,如果索引码小于231,那么这个子密钥就来自于普通派生算法,对应的,如果索引码等于或者大于2^31,那么这个子密钥就是经过增强派生算法得来的。

为了让索引码更容易读取和显示,增强子密钥的索引码也是从零开始显示,但是带有一个符号。第一个来自普通派生算法的索引码显示为0,而第一个来自增强派生算法的索引码(0x80000000)显示为0’.对应地,增强派生算法所得第二个子密钥的索引码是0x80000001,显示为1’,以此类推,如果你看到HD钱包上显示的索引码是 i’,那么就意味着是 2^31+i.

层级式确定性钱包的标识符(路径)

HD钱包中的密钥采用“路径”的命名规范进行标识,根据树形结构在每一层之间采用"/"分割。从主私钥派生出的私钥由m开头,而从主公玥派生出的公钥由M开头。因此,主私钥派生的第一个子私钥表示为m/0,主公玥派生的第一个子公钥表示为M/0,第一个子私钥的第二个下一级孙子私钥表示为m/0/1,以此类推

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RXHy8ZyQ-1585387260044)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583667874616.png)]

密钥的辈分是从右到左读的,只到读到派生的主密钥。例如:

标识符m/x/y/z表示私钥m/x/y的第z个子私钥,这也是私钥m/x的第y个子私钥,和主私钥m的第x个子私钥。

层级式确定性钱包的树状结构

HD钱包的树形结构提供了很大的灵活性。另一方面,它也支持无限的复杂性:每一个父级扩展密钥都可以派生大约40亿个下一级密钥:20亿个普通扩展密钥,20亿个增强扩展密钥。每一个这样的次级密钥又可以有40亿个次次级密钥,以此类推。树的深度是无限的,包含无穷无尽的后代。与此同时,在这个无穷尽的树中导航可能极为困难。

有两个BIP针对这样的复杂情况提供了解决方案。这两个BIP提出了HD钱包树状结构的标准。BIP-43提出,使用第一级增强扩展子密钥的索引码作为一个特殊的标识符,指定该分支的“用途”。基于BIP-43,一个HD钱包只应使用一个level-1层,这个索引码确定了剩余树的结构和命名空间,因此也确定了钱包的用途。例如:只使用m/i’/… .分支的HD钱包意在标识一个具体的用途,这个用途被记录在索引码i中。

在此基础上扩展,BIP-44提出了一个支持多币种账号结构的体系,该结构将“用途”索引码定为44’。所有遵循BIP-44标准的钱包都只使用树形结构的这个 m/44’/*分支

BIP-44 定义的结构中包含了5种预定义的树形层级:

m/purpose’/coin_type’/account’/change/address_index

第一层级的purpose’总是设定为 44’,

第二层级的coin-type’用来指定当前分支支持的币种,以此来实现HD钱包对多币种的支持,每一种类型的数字货币在第二层级的树状结构中都有一个自己的分支。货币的类型在一个名为SLIP0044

https://github.com/satoshilabs/slips/blob/master/slip-0044.md的文档制表符定义。例如:

以太坊是m/44’/60’,以太坊经典是 m/44’/61’,比特币是m/44’/0.

所有货币的测试网都是 m/44’/1’/

第三层级account’,允许用户把它们的钱包分成多个逻辑上的子账号,用于记账或管理。

例如,一个HD钱包可能包含两个以太坊’账户“: m/44’/60’/0’和 m/44’/60’/1’.每一个账户都是它对应分支的根

由于BIP-44源于比特币,它包含了一个跟以太坊无关的‘怪癖’;第四层的 change.

HD钱包中的“找零’分为两层:第一层用来创建接收地址,第二层用来创建找零地址。在以太坊中,只有接收地址这一层被用到,因为以太坊中并不存在找零的概念。请注意,无论上层使用的是普通派生还是增强派生,这一层都使用普通派生算法;。这样做的目的是允许这一层导出扩展公钥用于非安全的环境。可用地址就是从HD钱包第四层的密钥派生出来的,使得第五层成为address_index。例如,在一个以太坊钱包中,主账户的第三个用于收款的标识符对应的就是:m/44’/60’/0’/0/2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yGcVeIWP-1585387260045)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1583669982959.png)]

.

HD钱包中的“找零’分为两层:第一层用来创建接收地址,第二层用来创建找零地址。在以太坊中,只有接收地址这一层被用到,因为以太坊中并不存在找零的概念。请注意,无论上层使用的是普通派生还是增强派生,这一层都使用普通派生算法;。这样做的目的是允许这一层导出扩展公钥用于非安全的环境。可用地址就是从HD钱包第四层的密钥派生出来的,使得第五层成为address_index。例如,在一个以太坊钱包中,主账户的第三个用于收款的标识符对应的就是:m/44’/60’/0’/0/2

[外链图片转存中…(img-yGcVeIWP-1585387260045)]

你可能感兴趣的:(GO语言和区块链)