ethers.js如何通过助记词恢复兼容MyCrypto的钱包
ethers.js兼容MyCrypto带密码助记词恢复实现方案
核心问题说明
在12位助记词后追加第13个词作为密码的做法是错误的。MyCrypto导入助记词时要求填写的额外密码是BIP39标准定义的可选盐值(passphrase),不属于助记词本身的组成部分,直接拼接到助记词后会破坏BIP39校验规则,自然触发invalid mnemonic报错。
正确实现方式
ethers.utils.HDNode.fromMnemonic原生支持传入BIP39密码参数,方法签名如下:
HDNode.fromMnemonic(mnemonic, password?: string, wordlist?: Wordlist)
之前调用该方法时仅传入了助记词,等价于传入空字符串""作为密码,因此只能匹配MyCrypto留空密码时生成的地址。只要把用户输入的额外密码作为第二个参数传入,派生结果就会和MyCrypto完全一致。
可运行验证代码
使用提供的测试助记词和密码test验证,代码如下:
const ethers = require("ethers"); // 测试参数 const mnemonic = "federal train gather tumble service amount address need tail crunch better baby"; const DERIVATION_PATH = "m/44'/60'/0'/0"; const FIRST_ACCOUNT_INDEX = 0; // 无密码场景(对应MyCrypto密码留空) const hdNodeNoPwd = ethers.utils.HDNode.fromMnemonic(mnemonic); const firstAccountNoPwd = hdNodeNoPwd.derivePath(`${DERIVATION_PATH}/${FIRST_ACCOUNT_INDEX}`); const walletNoPwd = new ethers.Wallet(firstAccountNoPwd.privateKey); console.log("无密码首个地址:", walletNoPwd.address); // 输出: 0xd4E22d1ffe328d8b3F834fa5791f50C16E453a0d,与预期一致 // 密码为test场景(对应MyCrypto填写密码test) const extraPassword = "test"; const hdNodeWithPwd = ethers.utils.HDNode.fromMnemonic(mnemonic, extraPassword); const firstAccountWithPwd = hdNodeWithPwd.derivePath(`${DERIVATION_PATH}/${FIRST_ACCOUNT_INDEX}`); const walletWithPwd = new ethers.Wallet(firstAccountWithPwd.privateKey); console.log("密码为test首个地址:", walletWithPwd.address); // 输出: 0x3454Bd153214d900253812b4D47787eF23cD76e6,与MyCrypto生成结果完全匹配
注意事项
- BIP39额外密码的作用是参与种子生成的PBKDF2哈希计算,同一个助记词搭配不同密码会生成完全独立的种子,派生的地址链完全不互通,这是标准设计而非MyCrypto自定义逻辑。
- 若使用ethers v6版本,API路径有调整,对应创建HD钱包的写法为
ethers.HDNodeWallet.fromMnemonic(ethers.Mnemonic.fromPhrase(mnemonic, extraPassword), DERIVATION_PATH),派生逻辑保持一致。
参考截图


内容的提问来源于stack exchange,提问作者MrsBookik
相关产品推荐
相关产品推荐

