了解开发 HD 钱包所涉及的 BIP32、BIP44 和 BIP39

imToken 是一款全球领先的区块链数字资产管理工具[ZB],帮助你安全管理BTC, ETH, ATOM, EOS, TRX, CKB, BCH, LTC, DOT, KSM, FIL, XTZ 资产,同时支持去中心化币币兑换功能 ...

如果您仍然对 HD 钱包(分层确定性钱包)、BIP32、BIP44 和 BIP39 感到困惑,请查看这篇文章。

区块链比特币以太坊

数字钱包概念

比特币钱包和以太坊钱包

钱包是用来存钱的,在区块链中,我们的数字资产都与一个账户地址相关联,只有拥有该账户的密钥(私钥)的人才能消费资产(用私钥签署消费交易),私钥与地址的关系如下:

(图片来自《精通比特币》)一句话总结就是:私钥通过椭圆曲线生成公钥,公钥通过哈希函数生成地址,两个过程都是单向的。

所以其实数字钱包其实就是一个管理私钥(生成、存储、签名)的工具。注意钱包不存资产,资产都在链上。

如何创建一个帐户

创建账户的关键是生成私钥。私钥是一个 32 字节的数字。生成私钥本质上是选择一个 1 到 2^256 之间的数字。因此,生成密钥的第一步也是最重要的一步是找到一个足够安全的熵源,即随机源。只要选择的结果是不可预测或不可重复的,选择数字的具体方法并不重要。

比如,你可以抛一枚硬币256次,用纸和笔记录下正面和反面并转换成0和1,随机得到的256位二进制数可以作为钱包的私钥。

从编程角度来说,一般是从加密安全的随机源中取出一长串随机字节(不建议自己写随机数),然后使用哈希算法对其进行操作,这样就可以轻松生成一个 256 位的数字。

实际过程中需要比较是否小于n-1(n=1.158*10^77,略小于2^256),则有合适的私钥。否则,用另一个随机数重复。这样得到的私钥可以进一步按照上述方法生成公钥和地址。

BIP32

钱包也是私钥的容器,按照上面的方法,我们可以生成一堆私钥(一个人也要有很多个账户,这样才能更好的保护隐私),而如果每个私钥都需要备份就特别麻烦了。

最早的比特币钱包是这样的,有一个绰号:“Just a Bunch Of Keys”

为了解决这个问题,BIP32被提出:基于一个随机数种子,通过分层确定性推导得到n个私钥。这样,在保存的时候,只需要保存一个种子,就可以推导出私钥,如图:

(图片来自 )上图中的Sun key可以用来发出交易。

补充一下BIP:比特币改进提案,bip32是第32个改进提案,BIP32提案的名字是:,也就是我们说的HD钱包。

我们来分析一下这个分层推导的过程,第一步是推导主密钥:

根种子输入到 HMAC 算法中生成主私钥(m)和链码。这一步生成的秘钥(私钥或公钥)和链码加上一个索引号将作为 HMAC 算法的输入,派生出下一层私钥和链码,如下图所示:

推导方案其实有两种:一种是使用母私钥进行推导(称为增强推导方程),一种是使用母公钥进行推导。为了区分这两种不同的推导,索引号也是有区分的,小于 2^31 的索引号用于常规推导,2^31 到 2^32-1 之间的索引号用于增强推导。为了方便表示索引号 i',用 2^31+i 来表示。

因此,通过增加索引(水平扩展)并通过子密钥向下一级(深度扩展),可以无限地生成私钥。

注意,这个派生过程是确定性的(相同的输入,总是相同的输出)和单向的,子密钥不能用于派生同级的兄弟密钥,也不能用于派生父密钥。如果没有子链码,则无法派生孙密钥。现在我们对分层派生有了一定的了解。

一句话总结BIP32:提出了一种分层派生方案,以避免管理一堆私钥的麻烦。

密钥路径和 BIP44

从这种层级结构(树状结构)衍生出来的密钥通常用路径表示,每层之间用斜线隔开,而从主私钥衍生出来的私钥都以“m”开头。因此,第一个主密钥生成的子私钥是m/0。第一个公钥是M/0。第一个子密钥的子密钥是m/0/1,以此类推。

BIP44为这条路径规定了标准化的含义(同时也扩展了对多种货币的支持),指定了一个包含5个预定义树状层级的结构:m/'/coin'/'/m是固定的,也是固定的,值为44(或) 货币类型 这个代表的是货币,0代表比特币,1代表比特币测试链,60代表以太坊完整的货币列表 地址:代表这个币的账户索引,从0开始。常数0用于外部(接收地址),常数1用于内部(也叫找零地址)。外部用于钱包外可见的地址(比如用于接收付款)。内部链用于钱包外不可见的地址,用于返回交易找零。(所以一般都使用0) 这个是地址索引,从0开始,代表生成的地址数量,官方建议每个不要超过20个。

根据EIP85提案的讨论,以太坊钱包也遵循BIP44标准,路径为m/44'/60'/a'/0/na,代表账号imToken下载,n为第n次生成的地址,60为提案中确定的以太坊代码。因此,如果我们要开发以太坊钱包,还需要了解比特币钱包提案BIP32和BIP39。

简而言之,BIP44 是:BIP32 分层路径定义的规范

BIP39

BIP32 提案允许我们保存一个随机数种子(通常用十六进制数表示),而不是一堆密钥,这确实更方便,但用户使用起来也比较麻烦(例如冷备份)。这就是 BIP39 的作用所在。它使用助记符来生成种子,因此用户只需记住 12 个(或 24 个)单词序列。单词序列与 HMAC 函数一起使用,创建一个随机种子作为 BIP32 种子。

你可以简单比较一下,看看下列哪一个更加用户友好:

// 随机数种子
090ABCB3A6e1400e9345bC60c78a8BE7
// 助记词种子
candy maple cake sugar pudding cream honey rich smooth crumble sweet treat

使用助记词作为种子其实包含两个部分:生成助记词和根据助记词得出随机种子。我们来分析一下这个过程。

生成助记词

助记词生成流程为:先生成一个128位的随机数,再对随机数加上4位的校验和,得到一个132位的数以太坊和比特币区块链钱包,再除以11位,得到12个二进制数,再用每个数去查找BIP39定义的单词表,这样就得到了12个助记词,流程如下图所示:

(图片来自网络)

以下是一段利用bip39生成助记词的代码:

var bip39 = require('bip39')
// 生成助记词
var mnemonic = bip39.generateMnemonic()
console.log(mnemonic)

从助记符中获取种子

此过程使用密钥拉伸函数,该函数用于增强弱密钥的安全性,是常用的密钥拉伸算法之一。其基本原理是使用随机函数(例如 HMAC 函数)将助记词明文和盐值作为输入参数,然后重复操作,最终生成更长(512 位)的密钥种子。然后此种子构建确定性钱包并派生其密钥。

密钥拉伸函数需要两个参数:助记词和盐。盐可以增加暴力破解的难度。盐由一个常量字符串“”和一个可选的密码组成。注意,如果使用不同的密码,拉伸函数在使用相同助记词时会生成不同的种子。这个过程如下图所示:

(图片来自网络)

使用同样代码来表达:

var hdkey = require('ethereumjs-wallet/hdkey')
var util = require('ethereumjs-util')
var seed = bip39.mnemonicToSeed(mnemonic, "pwd");
var hdWallet = hdkey.fromMasterSeed(seed);
var key1 = hdWallet.derivePath("m/44'/60'/0'/0/0");
console.log("私钥:"+util.bufferToHex(key1._hdkey._privateKey));
var address1 = util.pubToAddress(key1._hdkey._publicKey, true);
console.log("地址:"+util.bufferToHex(address1));
console.log("校验和地址:"+ util.toChecksumAddress(address1.toString('hex')));

校验和地址是 EIP-55 中定义的区分大小写的地址格式。

密码可以作为保护种子的额外安全因素,即使助记词备份被盗,也能保证钱包的安全(密码也要求有足够的复杂度和长度),但另一方面,如果我们忘记了密码,我们将无法恢复我们的数字资产。

简而言之,BIP39 是:通过定义助记符使种子备份更加用户友好

我给大家录制了一个视频:以太坊去中心化网页钱包开发,从如何创建账户开始,深入探讨BIP32,BIP44,BIP39等提案,以及如何存储私钥,发送离线签名的交易和代币。

概括

HD钱包( )是BIP32中提出的分层派生方案,避免了管理一堆私钥的麻烦。BIP44增强了BIP32分层的路径定义规范,并增加了对多种货币的支持。BIP39通过定义助记词使种子备份更加友好。

目前,市场上大多数以太坊和比特币钱包都遵循这些标准。

最后给大家推荐一个助记词账号生成

如果大家在学习过程中遇到任何问题,欢迎在区块链技术问答区提问,老师们将会为你解答。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

返回顶部
跳到底部

Copyright © 2002-2024 imToken钱包下载官网 Rights Reserved.
备案号:晋ICP备13003952号

谷歌地图 | 百度地图
Powered by Z-BlogPHP Theme By open开发