比特币钱包-btcwallet(三) 账户创建与地址创建
1 基础协议 BIP39、BIP32、BIP43、BIP44
1.1 BIP39 助记词
(这部分基本是翻译自BIP39的wiki,具体地址见参考文献)
BIP39 就是为了解决seed不好记忆的问题诞生的。其最终目标也是生成seed, 不过要先生成助记词,然后再有助记词生成seed 。下面我们看一下两步:
1.1.1 生成助记词
原理很简单,先有一个128~256位的熵,然后生成校验码 checknum , 然后将校验码添加到熵后面,形成一个拼接的字符串,接下来一步是每11位分隔一下,每个11位会对应一个单词(有一个单词列表)。这些单词最终就组成了助记词。
助记词生成.png图片来自 《精通比特币》
助记词的单词列表的几个特点:
(1)去除了易混的单词,比如build 跟built 。
(2)经过了排序,方便后续使用trie前缀树进行压缩。
1.1.2 由助记词生成seed
利用助记词 + salt ("mnemonic"+ 可选的密码短语) ,使用HMAC-SHA512 算法,使用2048次哈希来延伸助记词和salt 参数,产生一个512位的种子。
图片来自 《精通比特币》
可选的密码短语,使得助记词不能单独使用,避免助记词被盗后被利用。
1.2 BIP32 HD钱包
1.2.1 子密钥的产生
私有子密钥的产生:母密钥 + 链码 + 索引结合并散列可以生成子密钥。结果是512位的散列,右半部分是256位的链码,左半部分是子密钥。
母公钥衍生子私钥跟链码.png1.2.2 扩展密钥
密钥以及链码被结合之后,就叫扩展密钥。
扩展密钥 + 索引,就可以导出子密钥。
1.2.3 强化子密钥
因为扩展公钥包含链码,如果子密钥被知道或者被泄露,链码就可以用来衍生其他所有的子私钥。非常危险。为了应对这种风险,HD钱包使用了一种叫做强化衍生的替代衍生函数,打破了母公钥以及子私钥之间的关系。这个硬化函数使用了母私钥去推到子链码,而不能采用母公钥去推到链码。
通过母私钥,衍生出子私钥跟链码.png
1.2.4 HD钱包识别符(密钥路径)
由主私钥衍生出的私钥起始以”m“打头,由主公钥衍生出的公钥以"M"打头。比如m/x/y 是m/x 的第y个子密钥。
1.3 BIP43 多用途HD钱包结构
BIP43 是对BIP32的一种支持,其目的是为了大家生成的密钥路径都遵循相同的规范,其产物还是密钥。
不同人员开发的钱包可能会有不同的规定方式,这就导致了同一种路径可能有多个解释。为了避免混乱,BIP43中将第一层级的编号定义为“目的域”,不同的协议使用不同的编号。比如如果一个钱包结构满足BIP44,它的秘钥路径就应该是m/44’/*这样我们就知道对这个路径的理解方式应该按照BIP44里的规定。
BIP43中还规定了在一个数字后加撇号表示这是一个加固子秘钥,也就是说其真实的生成编号为i+2^31 ,比如上文中的44’,其真实对应的生成编号为2^31 +44,即0x8000002C。
1.4 BIP44 多币种和多账户钱包
BIP44在BIP43基础上,提出了多账户结构。其产物还是密钥。
BIP44的五层结构:
// 私钥
m/purpose‘/coin_type'/account'/change/address_index
// 账户
M/purpose‘/coin_type'/account'/change/address_index
其中每部分的含义是:
- m 表示私钥, M表示地址
- purpose 默认为44
- coin_type 特指币种,并且允许多元货币HD钱包中的货币在第二层级下有自己的子币种,比如比特币就有m/44'/0'、m/44'/1' m/44'/2'。
- account 账户, 就是为了组织结构的划分,比如某个钱包账户中,有多少子账户。方便统计管理。
- change ,有两种,一个是用来接收地址,一个是用来创造找零地址。
- address_index ,change 的下一级,用来指定是接收还是找零地址的第几个。
1.5 小结各钱包协议的关系
协议关系.png2 创建账户
1.1 创建账户指令
解锁
btcctl --simnet --rpcuser=rpcuser --rpcpass=rpcpass --wallet walletpassphrase "root" 600
解锁过程就是利用timeout 构造一个定时器,然后利用这个定时器创建了一个 unlockRequests, 然后向启动时定义的walletLocker routine 中发送unlockRequests 。
walletLocker 的routine来处理这个解锁逻辑。
创建账户
btcctl --simnet --rpcuser=rpcuser --rpcpass=rpcpass --wallet createnewaccount zp
1.2 创建账户流程
btcwallet 创建的账户是 BIP44类型的账户。
创建账户.png
其结果是生成当前账户BIP44格式的扩展公钥、扩展私钥信息以及索引信息。
如果按照BIP44的定义,生成账户的这一步应该是实现到了BIP44里面的 account 这一级。
// 私钥
m/purpose‘/coin_type'/account'/change/address_index
// 账户
M/purpose‘/coin_type'/account'/change/address_index
3 创建地址
btcctl --simnet --rpcuser=rpcuser --rpcpass=rpcpass --wallet getnewaddress zp
创建地址.png
4 小结
本文讲解了BIP39, BIP32,BIP43,BIP44基础协议,然后从源码角度分析了账户创建跟地址创建的流程。
5 参考文献
BIP32 BIP44 https://www.cnblogs.com/bytom/p/10410568.html
BIP39 助记词相关bitcorn 官方wiki https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
《精通比特币》第二版
BIP32 翻译 https://blog.csdn.net/pony_maggie/article/details/76178228
HD钱包 bip43 bip44 https://www.linksfin.com/article/244279
6 其他
本文是《循序渐进比特币》的第九篇-《btcwallet(三) 账户创建与地址创建》。
如果有疑问,可以直接留言,也可以关注公众号 “链人成长chainerup” 提问留言,或者加入知识星球“链人成长”~