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

前言

数月前我换手机后还原加密钱包时,发现当初备份的助记词缺少 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、公号【编码美学】。

相关推荐
笃行3506 分钟前
集中式与分布式,KingbaseES 的四种形态共用一套内核
前端
陈随易1 小时前
Vue 编译器换掉 source map,快了三四成
前端·后端·程序员
ZhengEnCi3 小时前
12 种高级 UI 交互效果及对应 AI 提示词:从按压回弹到底部抽屉的物理感教学
前端·css·交互设计
IT_陈寒5 小时前
Redis大key删除为什么会导致服务卡顿?我的线上事故复盘
前端·人工智能·后端
系统集成-鹰翔5 小时前
ERP图片改名后仍命中识别缓存:缓存键、十分钟到期与调用计数
javascript·经验分享·后端
用户2705077725246 小时前
MCP 最小 Server 实测:3 个 JSON-RPC 报错与修法
前端
用户499335025076 小时前
一人VIP账号多人共用:Web 代理里的会话共享怎么实现
前端
用户老李6 小时前
无线电自学教程 05:第一台收音机——从矿石机到 SDR
前端
IPIPD6 小时前
Node.js请求遇到503怎么重试?先解析Retry-After,再做有上限退避
前端
葡萄城技术团队6 小时前
dsh-spreadjs-editor 的集成链路:把 SpreadJS Designer 嵌进 Agent 工作台
前端