# 空投科学家 - 批量生成以太坊钱包地址

By [June](https://paragraph.com/@june023) · 2022-06-23

---

什么是以太坊地址
--------

*   在以太坊有两种类型的地址。外部拥有的地址（Externally Owned Address - EOA）和合约地址。
    
    *   外部拥有的地址指的是拥有公钥和私钥对的账户。
        
        *   公钥是一个42个字符（character）的十六进制地址， 地址是公钥的最后20个字节（bytes）得出，并在前面附加0x。例如: V神地址[0xd8da6bf26964af9d7eed9e03e53415d37aa96045](https://etherscan.io/address/0xd8da6bf26964af9d7eed9e03e53415d37aa96045)。
            
        *   通过私钥可以得到公钥，通过公钥不能得到私钥。
            
        *   `一般我们说的地址就是指的外部拥有的地址的公钥。转账是转到别人的公钥。`
            
    *   合约地址指的是在以太坊区块链上托管一个执行功能的代码集合的地址。当一个带有相关输入数据的交易（合约互动）被执行时，合约地址的这些功能就会被执行。
        

如何生成以太坊地址
---------

1.  生成私钥。私钥是指在\[1, 2^256-2^32-977- 1\]范围内随机选择的正整数（以长度为32的字节数组的形式表示）。
    
    1.  (2^256-2^32-977- 1) ~ 2^256 ~ 10^77。地球 原子数量 ～ 10^50。宇宙原子数量 ～ 10^80。
        
    2.  私钥的数量 几乎与整个宇宙中可见原子的总数差不多。因此生成两个相同私钥的概率低到可以忽略不计。
        
2.  私钥 → 公钥
    
    1.  用的 ECDSA（Elliptic Curve Digital Signature Algorithm），最后得到64字节的公钥。
        
3.  公钥 → 地址
    
    1.  公钥 开始是 128 字符 / 64 字节，
        
    2.  首先通过 Keccak-256 哈希加密，得到一个64个字符/32字节的字符串。
        
    3.  取出这个公钥的最后40个字符/20个字节。或者，换句话说，放弃前24个字符/12个字节。这40个字符/20个字节是地址。当前缀为0x时，它就变成了42个字符长。
        

借助Web3的包，生成地址就很简单了。如下：

    from web3 import Web3
    
    w3 = Web3()
    acct = w3.eth.account.create()
    private_key = acct.privateKey.hex()
    address = acct.address
    
    print(private_key)
    print(address)
    

得到的地址和私钥如下

    private_key = 0xa62317fe5058f49f67a20b97de58051e909da40fb4fee6a58d633e1cd2dee9c5
    address = 0xdF3e09bbBae78e651c52F0e0618c383fB5f93149
    

如何批量生成以太坊地址
-----------

可以用一个循环，多次调用 `w3.eth.account.create()` 就可以生产多个地址了。生成的地址可以json的形式存储起来，方便未来使用。

代码：

    from web3 import Web3
    import json
    
    NUM_OF_ADDRESSES = 3
    w3 = Web3()
    
    list_addresses = []
    for i in range(NUM_OF_ADDRESSES):
        acct = w3.eth.account.create()
        list_addresses.append(
            {"address": acct.address, "private_key": acct.privateKey.hex()}
        )
    with open("addresses.json", "w") as fp:
        json.dump(list_addresses, fp)
    

最后的json 文件如下。

    [    {        "address": "0x47F09a771ABbDB33b2Da41fA59112980c550D1Db",        "private_key": "0xb772a1a12f25a69021dcc1868e3fc27b1e84da436d002bd7d333cdc0ad682595"    },    {        "address": "0xa285352CC647fbc69c3C50733b960c6D802d853C",        "private_key": "0x022abf9151f4b3eb571f71fbe1c4dec6eee2f0c4926a5d10675d937e6cbb3544"    },    {        "address": "0xc47937F2B7bA0A7acFd9c6c54CBd96D50a9FE424",        "private_key": "0x43a2b6082abdafab2eebb77a0589abadbbf68f7e3173da1bc01eec7d6f301a9b"    }]
    

完整代码：

[https://github.com/June911/GenerateETHAddresses](https://github.com/June911/GenerateETHAddresses)

怎么验证我们的地址有效呢
------------

*   打开小狐狸钱包
    
*   点右上角，再点import account
    

![](https://storage.googleapis.com/papyrus_images/0cb88d683f1239ac71ff7dc7a267cf9487eb8ee2ece435c755737db12474a7a9.png)

*   把生成的私钥复制进去，点 import。
    
*   再点右上角，把account 拉到最下面，就可以看到新 import 的 账户了。
    
*   可以看看账户的地址和我们记录的地址一不一致，一致的话，就没啥问题了。
    

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

* * *

### 如何进行地址挖矿

假设我们有想要的地址格式，比如前面 六个0，我们就可以无限循环生成地址，直到最后得到符合我们要求的地址就OK了。我没试验过，不过感觉挺有意思的。

参考链接
----

[https://info.etherscan.com/what-is-an-ethereum-address/](https://info.etherscan.com/what-is-an-ethereum-address/)

[https://ethereum.stackexchange.com/questions/3542/how-are-ethereum-addresses-generated](https://ethereum.stackexchange.com/questions/3542/how-are-ethereum-addresses-generated)

* * *

下面是一些个人链接，欢迎大家关注。

[https://twitter.com/june023\_eth](https://twitter.com/june023_eth)

[https://github.com/June911](https://github.com/June911)

---

*Originally published on [June](https://paragraph.com/@june023/sEEKQex5ihsX83cB9hRa)*
