助记词顺序乱了不要急,有地址就可以找回

前言

数月前我换手机后还原加密钱包时,发现当初备份的助记词缺少 1 位单词,险些导致资产丢失,最后通过研究文档和实现原理,搞定了助记词的生成、加密钱包地址的生成算法,最终写了个程序找回了丢失的那个单词,详情记录在这篇博客里:加密钱包助记词丢失后的一天

后来有几个朋友找到我,说也遇到了助记词相关的问题,有丢失 1 位的,有丢失2位的,甚至有抄错好几个单词,还把最后两个单词漏掉的!我后面优化了好几个版本代码,都帮他们找回了。

正文

最近遇到了情况,就是12个助记词都在,但是导入时候提示无效助记词,然后随便换一下顺序就可以登录上去,说明单词本身都是有效的,对方觉得可能是助记词顺序抄错导致的,希望我能帮他把这 12 个助记词的所有可能的排列组合都计算出来并生成对应的地址,这样他用自己的地址匹配一下,就能找到正确的助记词了。

这就是个全排列问题,我算了一下,12 个助记词有 12! = 479,001,600 个组合,对现在的计算机来说这是小 case, 因为是 cpu 密集型计算,关键是还要对每个组合生成钱包地址,这个很耗时间,因为涉及第三方库 Api,属于 IO 密集型操作,需要异步等待,到底完整流程走完耗时多少心里也没谱,于是我做了个测试,在我的 macbook pro 14(m1 pro芯片)上,可以达到 1000次/秒,那么完整跑完程序需要 5.5 天时间,虽然慢了点,不过证明还是可行的,如果 1秒只能生成几个地址那才是真的完蛋。

初版程序写完后,先给朋友电脑上配好环境跑着,我自己又开始琢磨有没有办法提高 地址生成的效率,上网查了一通果然有收获,原来不同的算法实现效率不一样的,之前我用的是 ethereumjs-wallet 这个库提供的生成算法,在我电脑上只能跑到 1000次/秒。

js 复制代码
async function getAddressFromMnemonic(mnemonic) {
  const seed = await bip39.mnemonicToSeed(mnemonic);
  const hdk = hdkey.fromMasterSeed(seed);
  const addrNode = hdk.derivePath("m/44'/60'/0'/0/0");
  const wallet = addrNode.getWallet();
  return `0x${wallet.getAddress().toString('hex')}`;
}

听说还有个 ECDSA 椭圆算法 ,于是研究了下, 需要使用 ethers 这个库,并且注意如果是 6以上的版本,需要用 fromPhrase 方法。

js 复制代码
async function getAddressFromMnemonic(mnemonic) {
  const wallet = ethers.Wallet.fromPhrase(mnemonic);
  return wallet.address;
}

效果如下图所示,速度已经达到了 3500+ 次每秒,比初版程序快了 3 倍。

注意,以上说的时间是全部执行完,需要消耗的时间,实际上我们不需要完整跑完,每生成一个地址,就可以和我们自己的地址匹配一下,如果一样,就可以提前终止程序了,运气好的话(顺序错的是尾部的几个单词),几秒钟就找回也是有可能的。

当然还有进一步优化的空间,就是使用多线程,不过我用 node 写的,不知为何多线程跑起来速度没感觉有提升,容我后续再想想。


技术交流 v: 1032151090

文章更新平台:掘金知乎Github、公号【编码美学】。

相关推荐
jay神1 天前
基于SpringBoot的校园社团活动智能匹配与推荐系统
java·前端·spring boot·后端·毕业设计
一殊酒1 天前
【前端开发】Vue项目多客户配置自动化方案【一】
前端·vue.js·自动化
切糕师学AI1 天前
Vue 中 keep-alive 组件的生命周期钩子
前端·vue.js·keep-alive·生命周期·activated·deactivated
晚霞的不甘1 天前
Flutter for OpenHarmony 布局核心:Row 与 Column 深度解析与实战
android·前端·javascript·flutter
Mr__Miss1 天前
JMM中的工作内存实际存在吗?
java·前端·spring
huangql5201 天前
【图文讲解】JavaScript二进制数据处理:从内存到类型化视图
前端
xiaozenbin1 天前
关于tomcat9页面部分乱码的处理
前端·tomcat·firefox
ethan.Yin1 天前
element-plus 二次封装遇到的一点疑惑
javascript·vue.js·ecmascript
Shea的笔记本1 天前
MindSpore实战笔记:Pix2Pix图像转换复现全记录
笔记·算法·机器学习·web3
Ulyanov1 天前
Impress.js 3D立方体旋转个人年终总结设计与实现
开发语言·前端·javascript·3d·gui开发