《精通比特币》解读 第五章 - 钱包

“钱包”一词在比特币中有多重含义。
广义上,钱包是一个应用程序,为用户提供交互界面。 钱包控制用户访问权限,管理**和地址,跟踪余额以及创建和签名交易。
狭义上,即从程序员的角度来看,“钱包”是指用于存储和管理用户**的数据结构。
本章,我们将深入介绍第二层含义,即钱包是私钥的容器,一般是通过结构化文件或简单数据库来实现。

非确定性(随机)钱包
钱包只是随机生成的私钥集合

下图展示的是一个非确定性钱包
《精通比特币》解读 第五章 - 钱包

确定性(种子)钱包
确定性(种子)钱包包含从公共的种子通过单项离散函数生成的私钥。
下图展示了确定性钱包的逻辑图
《精通比特币》解读 第五章 - 钱包

分层确定性钱包(HD Wallets (BIP-32/BIP-44))
确定性钱包的*形式是通过BIP0032标准定义的HD钱包

下图展示了HD钱包
《精通比特币》解读 第五章 - 钱包

种子和助记词(BIP-39)
助记词(标准由BIP-39定义)可生产种子。
让我们从实际的角度来看以下哪种种子更容易抄录、阅读、导出以及导入。
16进制表示的种子: 0C1E24E5917779D297E14D45F14E1A1A
助记词表示的种子: army van defense carry jealous true garbage claim echo media make crunch

助记词
BIP-39定义了助记符码和种子的创建,我们在这里描述了九个步骤。 为了清楚起见,该过程分为两部分:
1-6步是创建助记词,7-9步是从助记词到种子。
一、创建助记词:
助记词是由钱包使用BIP-39中定义的标准化过程自动生成的。 钱包从熵源开始,增加校验和,然后将熵映射到单词列表:
1、创建一个128到256位的随机序列(熵)。
2、提出SHA256哈希前几位(熵长/ 32),就可以创造一个随机序列的校验和。
3、将校验和添加到随机序列的末尾。
4、将序列划分为包含11位的不同部分。
5、将每个包含11位部分的值与一个已经预先定义2048个单词的字典做对应。
6、生成的有顺序的单词组就是助记码。
下图展示了熵如何生成助记词:
《精通比特币》解读 第五章 - 钱包

表5-2表示了熵数据的大小和助记词的长度之间的关系:
《精通比特币》解读 第五章 - 钱包

二、从助记词生成种子
创建助记词之后的7-9步是:
7、PBKDF2**延伸函数的第一个参数是从步骤6生成的助记符。
8、PBKDF2**延伸函数的第二个参数是盐。 由字符串常数“助记词”与可选的用户提供的密码字符串连接组成。
9、PBKDF2使用HMAC-SHA512算法,使用2048次哈希来延伸助记符和盐参数,产生一个512位的值作为其最终输出。 这个512位的值就是种子。

下图显示了从助记词如何生成种子
《精通比特币》解读 第五章 - 钱包

由种子创造HD钱包
HD钱包从单个根种子(种子是一个128位、256位或者512位的随机数)中创建的,一般而言种子是由助记词产生的。

The process of creating the master keys and master chain code for an HD wallet:
《精通比特币》解读 第五章 - 钱包

根种子输入到HMAC-SHA512算法中就可以得到一个哈希结果,该哈希可用来创造一个主私钥(m)和一个主链码(c)。
该主私钥(m)可以通过椭圆曲线乘法m * G 生成一个对应的主公钥(M)
主链码(c)用于从母**中创造子**的那个函数中引入的熵,如下一节所示。

衍生出私有子**
HD钱包使用CKD(child key derivation)函数去从母**衍生出子**。
子**衍生函数是基于单项哈希函数。这个函数结合了:
一个母私钥或者母公钥(ECDSA未压缩**)
一个叫做链码(256 bits)的种子
一个索引号(32 bits)

母公公钥、链码以及索引号合并在一起并且用HMAC-SHA512函数散列之后可以产生512位的散列。所得的散列可被拆分为两部分。散列右半部分的256位成为了子链码,左半部分256位散列以及索引码被添加到母私钥上来衍生出子私钥。
《精通比特币》解读 第五章 - 钱包

使用衍生出的子**
子私钥不能从非确定性(随机)**中被区分出来。因为衍生函数是单向的,所以子**不能被用来发现他们的母**。子**也不能用来发现他们的相同层级的兄弟**。如果你有第n个子**,你不能发现它前面的(第n-1)或者后面的(第n+1)子**或者在同一顺序中的其他子**。只有母**以及链码才能得到所有的子**。没有子链码的话,子**也不能用来衍生出任何孙**。你需要同时有子**以及对应的子链码才能创建一个新的分支来衍生出孙**。

那子私钥自己可被用做什么呢?它可以用来产生公钥和比特币地址。之后它就可以被用来签署交易和支付任何东西。

扩展**
正如我们之前看到的,**衍生函数可以被用来创造**树上任何层级的子**,这只需要三个输入量:一个**,一个链码以及想要的子**的索引。**以及链码这两个重要的部分被结合之后,就叫做扩展**(extended key)。术语“extended key”也可被认为是“可扩展的**”,因为这种**可以用来衍生子**。
扩展**可以简单地被储存并且表示为将256位**与256位链码所连接成的512位序列。有两种扩展**:
扩展私钥是私钥以及链码的结合,它可以用来衍生出子私钥(子私钥可以衍生出子公钥)。
扩展公钥是公钥以及链码的结合,它可以用来衍生出子公钥,见“生成公钥”章节。

衍生出公共子**
正如之前提到的,分层确定性钱包的一个很有用的特点就是可以不通过私钥而直接从公共母**派生出公共子**的能 力。这就给了我们两种衍生子公钥的方法:或者通过子私钥,再或者就是直接通过母公钥。
下图阐述了扩展母公钥来衍生子公钥的传递机制。
《精通比特币》解读 第五章 - 钱包

硬化子**的衍生
《精通比特币》解读 第五章 - 钱包