【问题标题】:How to generate Bitcoin keys/addresses from a seed in Python?如何从 Python 中的种子生成比特币密钥/地址?
【发布时间】:2019-01-15 16:06:47
【问题描述】:

我正在尝试从基于 BIP0039 的助记符创建一组公钥/私钥。我正在使用 Python。

这是我目前的代码:

from mnemonic import Mnemonic
mnemon = Mnemonic('english')
words = mnemon.generate(256)
mnemon.check(words)
seed = mnemon.to_seed(words)

在 BIP0039 中,声明您应该能够使用种子获取密钥,但我无法在 Python 中使用 bip32utils 弄清楚它。有没有人有如何使用 bip32utils 将种子转换为私钥/公钥及其各自地址的示例?

【问题讨论】:

    标签: python cryptography bitcoin


    【解决方案1】:

    从助记词生成种子已经在贴出的代码中实现了。

    根密钥是从种子派生的:

    root_key = bip32utils.BIP32Key.fromEntropy(seed)
    

    对于 BIP32,子密钥是通过以下方式创建的:

    child_key = root_key.ChildKey(0).ChildKey(0)
    

    对于 BIP44:

    child_key = root_key.ChildKey(44 + bip32utils.BIP32_HARDEN).ChildKey(0 + bip32utils.BIP32_HARDEN).ChildKey(0 + bip32utils.BIP32_HARDEN).ChildKey(0).ChildKey(0) 
    

    BIP32Key 类封装了密钥,并提供了不同的方法来检索不同格式的密钥。


    BIP32 示例:

    from mnemonic import Mnemonic
    import bip32utils
    
    mnemon = Mnemonic('english')
    #words = mnemon.generate(256)
    #print(words)
    #mnemon.check(words)
    #seed = mnemon.to_seed(words)
    seed = mnemon.to_seed(b'lucky labor rally law toss orange weasel try surge meadow type crumble proud slide century')
    print(f'BIP39 Seed: {seed.hex()}\n')
    
    root_key = bip32utils.BIP32Key.fromEntropy(seed)
    root_address = root_key.Address()
    root_public_hex = root_key.PublicKey().hex()
    root_private_wif = root_key.WalletImportFormat()
    print('Root key:')
    print(f'\tAddress: {root_address}')
    print(f'\tPublic : {root_public_hex}')
    print(f'\tPrivate: {root_private_wif}\n')
    
    child_key = root_key.ChildKey(0).ChildKey(0)
    child_address = child_key.Address()
    child_public_hex = child_key.PublicKey().hex()
    child_private_wif = child_key.WalletImportFormat()
    print('Child key m/0/0:')
    print(f'\tAddress: {child_address}')
    print(f'\tPublic : {child_public_hex}')
    print(f'\tPrivate: {child_private_wif}\n')
    

    产生输出:

    BIP39 Seed: 487a440fb26cb376168b6b88a2e46699cb9967bdc4a107fab571f6fdeaab02ea95d149073b3319735c5eace5acafd362edd1ad4c3ac3f655aaa6468973999500
    
    Root key:
        Address: 15Zpz6hJkSkAiw1A5Sm9UoemCVBCuW1SSP
        Public : 036830d1cbcecf9e01ce1ddb154ccb754a6a765d06b3b48dced926861e03bd9485
        Private: KzKjSsprRaWBfVy3oPNwPJBAzVxLXU5AAT5Xe9EJh5pJjpJAqP7q
    
    Child key m/0/0:
        Address: 1AP5U7iDUrvH8B1m1qiarbkA31Ux7jX8YF
        Public : 03a78bb2b1fb86280b4091e5cdffc5d8c87430f5c0988e84a7c5d972bb3f1a1b93
        Private: L47DQmmwwc88oZLPmyZr7CQWn1RzayBmH6gSpnFoMRCCTsR5yRpN
    

    这可以使用网站https://iancoleman.io/bip39/#english 进行验证,方法是将上面示例中使用的助记符输入到BIP39 助记符 字段并选择BIP32 作为派生路径。


    可以使用BIP32Key#dump() 方法以不同格式转储密钥,例如:

    root_key.dump()
    

    提供以下输出:

    * Identifier
      * (hex):       b'3215de8b72f8c407682a6e9334ccd11ae17b1f9c'
      * (fpr):       b'3215de8b'
      * (main addr): 15Zpz6hJkSkAiw1A5Sm9UoemCVBCuW1SSP
    * Secret key
      * (hex):       5c9c29e08d1ee9d3c8295ba2a931a9f0166e4282cc01702549664736a16b3a89
      * (wif):       KzKjSsprRaWBfVy3oPNwPJBAzVxLXU5AAT5Xe9EJh5pJjpJAqP7q
    * Public key
      * (hex):       b'036830d1cbcecf9e01ce1ddb154ccb754a6a765d06b3b48dced926861e03bd9485'
    * Chain code
      * (hex):       b'43088cf562e569922e1c1d0d689144ca2b171cb3cc3b2fedaa198f63be7ec130'
    * Serialized
      * (pub hex):   b'0488b21e00000000000000000043088cf562e569922e1c1d0d689144ca2b171cb3cc3b2fedaa198f63be7ec130036830d1cbcecf9e01ce1ddb154ccb754a6a765d06b3b48dced926861e03bd9485'
      * (prv hex):   b'0488ade400000000000000000043088cf562e569922e1c1d0d689144ca2b171cb3cc3b2fedaa198f63be7ec130005c9c29e08d1ee9d3c8295ba2a931a9f0166e4282cc01702549664736a16b3a89'
      * (pub b58):   xpub661MyMwAqRbcFD9E5CavptgKf8JFbkynXnRui6zHDi7TveyV1vnebzqJ1UUDRbcWjBLNy29ABLUxgevE86Pmt3PNMDZFzLyRzQuebs5Kn1G
      * (prv b58):   xprv9s21ZrQH143K2j4kyB3vTkjb76TmCJFwAZWJuiaffNaV3reLUPUQ4CWpABQbzZoo1SvSbuykaZfwj241YvtCs9FVpeKMAFd9eXvQTZwxSNU
    

    顺便说一句,BIP32Key#dump() 的源代码也很好地描述了哪个方法返回哪个格式。

    编辑:
    mnemonic 库提供了 Mnemonic#to_hd_master_key() 方法,它返回按定义编码的扩展私钥 Base58,例如在bitcon/bipsxprv...。如果这对您来说已经足够了,那么您就不需要 bip32utils
    但是,据我所知,助记符 不支持从中派生私钥、链码、公钥或扩展公钥。这只是在 bip32utils 类中实现的。
    我不清楚您可以使用哪些库,哪些不能。您可能必须自己实现缺少的功能(付出相应的努力):
    链码和私钥可以从扩展私钥中确定。为此,您只需要了解格式(参见例如 bitcon/bips)。如果曲线已知(比特币为 secp256k1)(为此需要 ec 算法或 ec 库),则公钥可以从私钥导出,因此可以从扩展公钥中导出。 bip32utils 可以作为这方面的蓝图。

    【讨论】:

    • 看起来您为子密钥生成了公钥。我可以生成公共主密钥吗?
    • @GuerlandoOCs - 当然。主密钥与root_key 相同,也是BIP32Key,即它完全模拟工作,例如public_hex = root_key.PublicKey().hex()。通过root_key.dump(),您可以获得完整的概览。
    • @GuerlandoOCs - 我已经修改了帖子并添加了相应的输出。
    • 什么是import bip32utils
    • 没问题,答案让我学到了很多
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 2014-01-17
    • 2016-09-02
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多