# 安全生成助记词靓号钱包地址

By [Cocoa](https://paragraph.com/@hcocoa) · 2022-11-06

---

继[上篇文章](https://mirror.xyz/hcocoa.eth/sgSWg5z7nsIjX5LKjRlYooDKT_OiqeXOYr2XzTQrfD8)之后，我们继续说说助记词靓号钱包的事情（话说Cocoa到底对靓号有多执着啊……

1.一点背景
------

这篇文章的起因是余弦大大提到了一例钱包被盗案，主要原因是受害者在一个钓鱼网站输入了助记词，导致了该助记词下2个钱包内的余额被盗。

![](https://storage.googleapis.com/papyrus_images/93df61afbc7ef485f5325202c12fb37c6ba3b48f0fc78c311ca10a905c47601b.png)

[上篇文章](https://mirror.xyz/hcocoa.eth/sgSWg5z7nsIjX5LKjRlYooDKT_OiqeXOYr2XzTQrfD8)提到使用Profanity2工具生成靓号地址，最后得到的是钱包地址和对应的私钥，并不是助记词。

而大家知道，Metamask等工具在生成钱包时，首先会生成助记词，然后默认生成一个其钱包地址（Metamask叫账户）。如果有需要，可以点击“创建账户”按钮，继续创建第二个、第三个等等钱包地址，这些钱包地址都有各自的私钥。

那么助记词和私钥有什么关系呢？为什么助记词丢失，会导致Metamask下的所有钱包都被盗呢？

2.分层确定性钱包（HD Wallet）
--------------------

这里就涉及到一个概念“分层确定性钱包”（Hierarchical Deterministic Wallet，简称叫HD Wallet或者HD钱包）。

HD钱包的核心来自于三个标准：BIP32、BIP44、BIP39。这里BIP的意思是Bitcoin Improvement Proposals（比特币改进提案），类似于网络领域的RFC标准。

这三个标准具体内容有兴趣的朋友可以搜一下，我这里简单总结一下：

*   BIP32：通过一个随机数（被称为种子seed），按照事先确定的算法，派生出大量的私钥。这样一来，只要保管好种子，就可以管理成千上万的地址，降低的维护的成本。顺便一提，BIP32 的名称直接就叫做“分层确定性钱包”。
    
*   BIP44：这是对BIP32的改进，在原有只支持比特币的基础上，通过在钱包内部规定路径path的方式，使钱包可以支持多条公链（如狗狗币、莱特币、以太坊等），进一步拓展了HD钱包的应用范围。例如：Metamask上以太坊的path就是m/44’/60’/0’/0/x，其中x就代表是第几个账户。
    
*   BIP39：继续对HD钱包进行改进：由于种子冗长难记，BIP39提出了助记词的概念，将seed转换为12个或24个单词（也可以是日文、韩文甚至中文，只不过现在英文用的较多），叫做助记词。这样只要人类记住12个单词，就可以通过程序将助记词转化为种子seed，再通过种子seed根据不用路径path生成不同币种的私钥，这样就完成了从助记词到比特币、以太坊、狗狗币等各类钱包地址的逐级转化。
    

总结一下，HD钱包生成以太坊地址（或者账号）的步骤就是：

1.先按照BIP32要求生成种子，2.根据BIP39将种子转化为人类可读的助记词，3.通过种子产生多个以太坊私钥，从而派生出对应的地址。

其中种子和助记词其实本质是一样的，因此就不难理解上面兄弟遇到的问题：丢失了助记词后，由助记词产生（其实是种子产生）的多个以太坊地址都失窃了。

3.生成助记词靓号地址
-----------

知道了原理，我们就可以通过不停枚举助记词（其实是种子），来暴力搜索靓号地址了。

找了一下好像没有现成的工具，没关系，毛主席教导我们：自己动手，丰衣足食。

这里以Cocoa熟悉的Python为例，nodejs和java也有类似库可以参考。

首先要用到一个叫hdwallet的库，它里面已经集成好了HD钱包所需的BIP标准相关代码。如果是Python 3.10以下版本，直接使用如下命令安装即可。如果是最新的Python 3.11，会遇到一些问题报错，后面有机会再聊。

安装完成后，直接在代码里引入即可。

    #!/usr/bin/env python3
    from multiprocessing import Pool
    from hdwallet import BIP44HDWallet
    from hdwallet.cryptocurrencies import EthereumMainnet
    from hdwallet.derivations import BIP44Derivation
    from hdwallet.utils import generate_mnemonic
    from typing import Optional
    
    #线程数，一般几核CPU写几
    THREAD_NUM = 6
    #靓号地址前缀
    PREFIX = '0xc0c0a'
    #靓号地址后缀
    SUFFIX = '8'
    
    def to_work():
        while 1:
            # Generate english mnemonic words
            MNEMONIC: str = generate_mnemonic(language="english", strength=128)
            # Secret passphrase/password for mnemonic
            PASSPHRASE: Optional[str] = None  # "meherett"
            # Initialize Ethereum mainnet BIP44HDWallet
            bip44_hdwallet: BIP44HDWallet = BIP44HDWallet(cryptocurrency=EthereumMainnet)
            # Get Ethereum BIP44HDWallet from mnemonic
            bip44_hdwallet.from_mnemonic(
                mnemonic=MNEMONIC, language="english", passphrase=PASSPHRASE
            )
            # Clean default BIP44 derivation indexes/paths
            bip44_hdwallet.clean_derivation()
            # Derivation from Ethereum BIP44 derivation path
            bip44_derivation: BIP44Derivation = BIP44Derivation(
                cryptocurrency=EthereumMainnet, account=0, change=False, address=0
            )
            # Drive Ethereum BIP44HDWallet
            bip44_hdwallet.from_path(path=bip44_derivation)
            wallet_address=bip44_hdwallet.address()
            # 这里的例子是生成一个c0c0a开头8结尾的靓号地址，注意开头的0x不要忘记
            if (wallet_address.startswith(PREFIX) and wallet_address.endswith(SUFFIX)):
                print("Mnemonic:", bip44_hdwallet.mnemonic())
                print(f"{bip44_hdwallet.path()} {wallet_address} 0x{bip44_hdwallet.private_key()}")
            # Clean derivation indexes/paths
            bip44_hdwallet.clean_derivation()
    
    def main():
        po = Pool(THREAD_NUM)
        for i in range(THREAD_NUM):
            po.apply_async(to_work)
        po.close()
        po.join()
    
    if __name__ == "__main__":
        main()
    

这是一个简单的demo版本，主体部分是根据hdwallet的官方示例代码修改的，增加了靓号判断逻辑和多线程。

后续也有改进优化的地方，比如增加EIP 55大小写校验机制（可以生成自定义大小写的靓号地址）、找到一个地址后自动停止运行（现在除非手动结束会一直跑）、改造成GPU显卡加速等等。感兴趣的朋友可以自己试试。

小弟的twitter：[@featherye](https://twitter.com/featherye) ，欢迎各位大佬关注！

[https://embed.0xecho.com.ipns.page?color-theme=auto&desc=&has-h-padding=true&has-v-padding=true&modules=comment%2Clike%2Cdislike%2Ctip&receiver=hcocoa.eth&target\_uri=https%3A%2F%2Fmirror.xyz%2Fdashboard%2Fedit%2FUhSGLaJ9hWzqvysVx45K5WrsD2rtW7yovP1uloWUB0E&height=800&display=iframe](https://embed.0xecho.com.ipns.page?color-theme=auto&desc=&has-h-padding=true&has-v-padding=true&modules=comment%2Clike%2Cdislike%2Ctip&receiver=hcocoa.eth&target_uri=https%3A%2F%2Fmirror.xyz%2Fdashboard%2Fedit%2FUhSGLaJ9hWzqvysVx45K5WrsD2rtW7yovP1uloWUB0E&height=800&display=iframe)

---

*Originally published on [Cocoa](https://paragraph.com/@hcocoa/Qm1FKLfnXOIMGwMNBxJG)*
