前言
一般在接触加密货币的时候,基本上第一步都是先安装个钱包工具(各式各样),然后在过程中会接触到助记词(mnemonic phrases),私钥(private key),钱包地址(address)等概念,在理解这几个原理之前,再加上类似于metamask这样的工具对这几个概念的区分并不太清晰,导致理解起来非常困难。
困惑之路
就拿最流行的MetaMask来说吧, 安装好就开始导入或者创建账户了。这时候MetaMask只能对应一个助记词,所以把他理解成只有一个钱包应该没问题。所以MetaMask:钱包:助记词=1:1:1的概念,但是MetaMask又可以创建多个账户,那么也就是助记词:账户=1:N。但是当我们创建多个账户的时候,助记词早就有了,那么一个助记词是怎么恢复那么多账户的呢?
解释
上面的这个问题困扰了我好久,主要原因还是不懂钱包原理的缘故。
其实助记词只是生成钱包的种子,一个助记词可以生成无数个钱包。所谓从助记词来“恢复”钱包,这种说法是有歧义的。
助记词是“生成”钱包,而不是“恢复”钱包,只不过按照规则,生成的钱包都是一致的。
如果说你在一个钱包工具里生成很多个账户,当你再其它地方再次导入时,钱包工具其实并不知道你原来的钱包工具里有多少个账户(有些工具会根据查询钱包地址是否有货币来帮你生成),你需要手动再次生成。
代码
用ethers.js来解释这个现象会比较容易理解以下。
钱包创建
1 | import { ethers, utils } from "ethers"; |
默认钱包生成
1 | const wallet2 = ethers.Wallet.fromMnemonic("museum...."); //默认path为"m/44'/60'/0'/0/0",也就是这个助记词的第一个钱包 |
第二个钱包以及之后的生成
1 | const wallet3 = ethers.Wallet.fromMnemonic("museum....", "m/44'/60'/0'/0/1"); //第二个钱包的path为"m/44'/60'/0'/0/1" |
也可以直接用HDNode来生成
1 | const hdNode = utils.HDNode.fromMnemonic('museum....'); |
总结
从上面可以看出其实钱包:账户是1:1的关系,而助记词:钱包是1:N的关系,虽然Metamask只能导入一个助记词,但是可以通过其它钱包密钥的形式,导入其它助记词生成的钱包。这个地方比较容易让人混淆。