【虚拟货币钱包】从 BIP32、BIP39、BIP44 到 Ethereum HD Wallet
钱包是很多人第一次接触 Ethereum 或其他虚拟货币的地方。不管是用手机或浏览器的钱包,相信很多人都对一串陌生的单字感到好奇(而且很重要还要备份)。这是源自于 Bitcoin 中钱包的设计,采用这套机制的钱包通常称为 HD Wallet。本篇希望简述 HD Wallet 的架构,再使用 JavaScript 套件从头创建一个 Ethereum HD Wallet。
虚拟货币钱包
钱包顾名思义是存放$$$。但在虚拟货币世界有点不一样,我的帐户资讯(像是我有多少钱)是储存在区块链上,实际存在钱包中的是我的帐户对应的 key。有了这把 key 我就可以在虚拟货币世界证明我的身份、就可以更改我帐户的状态(像是送钱给别人)。这样来说,虚拟货币钱包实际上是管理和储存 key 的工具。这把 key 就是我的私钥,而帐户是从我的公钥衍伸出来。
![](http://upload-images.jianshu.io/upload_images/8659755-9b58232f03cd84e3.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/460/format/webp)
BIP32, BIP39, BIP44
BIP 全名是 Bitcoin Improvement Proposals,是提出 Bitcoin 的新功能或改进措施的文件。可由任何人提出,经过审核后公布在 bitcoin/bips 上。BIP 和 Bitcoin 的关系,就像是 RFC 之于 Internet。
而其中的 BIP32, BIP39, BIP44 共同定义了目前被广泛使用的 HD Wallet,包含其设计动机和理念、实作方式、实例等。
- BIP32:定义 Hierarchical Deterministic wallet (简称 "HD Wallet"),是一个系统可以从单一个 seed 产生一树状结构储存多组 keypairs(私钥和公钥)。好处是可以方便的备份、转移到其他相容装置(因为都只需要 seed),以及分层的权限控制等。
![](http://upload-images.jianshu.io/upload_images/8659755-ff1466bb139e2bf8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp)
-
BIP39:将 seed 用方便记忆和书写的单字表示。一般由 12 个单字组成,称为 mnemonic code(phrase),中文称为助记词或助记码。例如:
rose rocket invest real refuse margin festival danger anger border idle brown
-
BIP44:基于 BIP32 的系统,赋予树状结构中的各层特殊的意义。让同一个 seed 可以支援多币种、多帐户等。各层定义如下:
m / purpose' / coin_type' / account' / change / address_index
其中的
purporse'
固定是44'
,代表使用 BIP44。而coin_type'
用来表示不同币种,例如 Bitcoin 就是0'
,Ethereum 是60'
。
Ethereum HD Wallet
Ethereum 的钱包目前均采用以上 Bitcoin HD Wallet 的架构,并订 coin_type'
为 60'
,可以在 ethereum/EIPs/issues 中看到相关的讨论。举例来说,在一个 Ethereum HD Wallet 中,第一个帐户(这里的帐户指 BIP44 中定义的 account'
)的第一组 keypair,其路径会是 m/44'/60'/0'/0/0
。
创建 Ethereum HD wallet
使用的 JavaScript 套件包含:
- bip39:实作 BIP39,随机产生新的 mnemonic code,并可以将其转成 binary 的 seed。
- ethereumjs-wallet:产生和管理公私钥,我使用其中的 hdkey 子套件来创建 HD Wallet。
- ethereumjs-util:集合许多 Ethereum 需要的运算功能。
安装套件
npm install bip39 ethereumjs-wallet ethereumjs-util --save
汇入套件
var bip39 = require('bip39')
var hdkey = require('ethereumjs-wallet/hdkey')
var util = require('ethereumjs-util')
产生 mnemonic code
var mnemonic = bip39.generateMnemonic()
取得的 mnemonic code 会像:
rose rocket invest real refuse margin festival danger anger border idle brown
产生 HD wallet
先将 mnemonic code 转成 binary 的 seed。
var seed = bip39.mnemonicToSeed(mnemonic)
使用 seed 产生 HD Wallet。如果要说更明确,就是产生 Master Key 并记录起来。
var hdWallet = hdkey.fromMasterSeed(seed)
产生第一个 Ethereum Address
产生 Wallet 中第一个帐户的第一组 keypair。可以从 Master Key,根据其路径 m/44'/60'/0'/0/0
推导出来。
var key1 = hdWallet.derivePath("m/44'/60'/0'/0/0")
使用 keypair 中的公钥产生 address。
var address1 = util.pubToAddress(key1._hdkey._publicKey, true)
取得的 Address:
685ce4cbdd5c19b64ca008cb85b83947e5318efa
Encoding Address
Ethereum 很贴心,为了避免大家打错 address(导致把钱送错人),Ethereum 让 Address 变得比较难打?!总之一般会用 EIP55: Mixed-case checksum address encoding 再进行编码。许多钱包也支援用户输入没经过编码的 Address,那就会跳过 checksum 机制,建议还是使用编码过的 Address。
address1 = util.toChecksumAddress(address1.toString('hex'))
最后取得的 Address 会像:
0x685ce4CbDd5c19b64CA008cB85b83947e5318EFA
可以用 Mnemonic Code Converter 验证结果
![](http://upload-images.jianshu.io/upload_images/8659755-8af8ad4929c6cc22.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp)
![](http://upload-images.jianshu.io/upload_images/8659755-1bba5fe661f65d47.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp)
使用 Ethereum HD wallet
把 mnemonic code 记录下来好好保存,就会是一个冷钱包(指不连网路的钱包,所以安全很多)。可以使用产生出来的 address 收 Ether 或任何 REC20 Token。要送钱的话,可以汇入到任一个支援 Ethereum HD Wallet 的钱包。常用的 Ethereum HD wallet 像,在浏览器使用的 MyEtherWallet、MetaMask 和在手机使用的 imToken 等。
![](http://upload-images.jianshu.io/upload_images/8659755-815eb1cba142d07e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/359/format/webp)
题外话,MetaMask 如何在浏览器储存我们的 mnemonic code?
相信大家都了解了,有 mnemonic code 就可以产生 HD Wallet 中所有的 keys。有了 keys 就可以任意送钱包中的 Ether 或 Token 给别人。所以 mnemonic code 很重要!!!那这么重要的东西保存在浏览器不会很危险吗?我便研究下我常用的 MetaMask 浏览器钱包。MetaMask 将加密后的 mnemonic code 存在浏览器的 Local Storage(一块只存在 Local 且不会过期的资料区块)。加密使用用户另外输入的密码,再汇入时会要求用户设定密码(如上图),而每一次重新开启钱包都会要求输入密码。解密算法有 Open Source,也有线上 Live Demo。
![](http://upload-images.jianshu.io/upload_images/8659755-5ed24e93dfbcb1ff.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp)
References
其他相关 Ethereum JavaScript 套件
作者:安德森_Anderson
链接:https://www.jianshu.com/p/54a2b14dfdf2
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。