Python

如何從python中的12個種子詞生成公鑰和私鑰對

  • February 29, 2020

我基本上按照這裡的說明How to generate mycelium address from the 12 words in python

所以我的程式碼是類似的:

from bip32utils import BIP32Key
from bip32utils import BIP32_HARDEN
from bip32utils import Base58
import os, bip39

strength_bits = 128
entropy = os.urandom(strength_bits // 8)
wallet_generator = bip39.Mnemonic('english')
mnemonic = wallet_generator.to_mnemonic(entropy)
assert wallet_generator.to_entropy(mnemonic) == entropy  # see, bijective!

# Or specify the mnemonic directly if you prefer:
mnemonic = 'aware report movie exile buyer drum poverty supreme gym oppose float elegant'
passphrase = 'test'

seed = bip39.Mnemonic.to_seed(mnemonic, passphrase=passphrase)
key = BIP32Key.fromEntropy(seed)
account_number = 0
i = 0
print "Address: " + key.ChildKey(44 + BIP32_HARDEN) \
        .ChildKey(0 + BIP32_HARDEN) \
        .ChildKey(account_number + BIP32_HARDEN) \
        .ChildKey(0) \
        .ChildKey(i) \
        .Address()

我使用<https://iancoleman.io/bip39/#english>驗證了生成的地址確實是該網頁生成的第一個地址。但是,我也想使用同一個庫獲取公鑰和私鑰對。我最初嘗試過:

print "Public Key: " + Base58.check_encode(key.ChildKey(44 + BIP32_HARDEN) \
        .ChildKey(0 + BIP32_HARDEN) \
        .ChildKey(account_number + BIP32_HARDEN) \
        .ChildKey(0) \
        .ChildKey(i) \
        .PublicKey())

print "Private Key: " + Base58.check_encode(key.ChildKey(44 + BIP32_HARDEN) \
        .ChildKey(0 + BIP32_HARDEN) \
        .ChildKey(account_number + BIP32_HARDEN) \
        .ChildKey(0) \
        .ChildKey(i) \
        .PrivateKey())

但是,這兩個呼叫的輸出與上面網站提供的相同地址的輸出不同。

所以我的問題是:我生成公鑰和私鑰對的正確方法是什麼?

編輯:為了澄清,對於上面的確切助記符和密碼,我用作參考的網站告訴我第一個地址和密鑰對應該是: 在此處輸入圖像描述

而上述python程式碼的輸出是:

Address: 1K6WQtD7bLQ5nQ14GyBV33mBWSbkiRKhQs
Public Key: 62Yi9HBYYagf8CY1Ve2fquHKjBqAA7GFjGUUtkUHbkP5PHzv3W
Private Key: EGHMsAp7nY7Jo9F589zCU227KBLTDhiwRq5vYVvRVZxJNPJn4

所以地址匹配,但不匹配密鑰對。

請嘗試以下展示,結果與<https://iancoleman.io/bip39/>相同。

$ python3.6 test.py
{'addr': '1A9vZ4oPLb29szfRWVFe1VoEe7a2qEMjvJ',
'coin': 'BTC',
'mnemonic_words': 'aware report movie exile buyer drum poverty supreme gym oppose float elegant',
'privatekey': 'L3g3hhYabnBFbGqd7qReebwCrRkGhAzaX4cBpYSv5S667sWJAn5A',
'publickey': '029dc2912196f2ad7a830747c2490287e4ff3ea52c417598681a955dcdf473b6c0'}

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import pprint
import binascii
import mnemonic
import bip32utils

def bip39(mnemonic_words):
   mobj = mnemonic.Mnemonic("english")
   seed = mobj.to_seed(mnemonic_words)

   bip32_root_key_obj = bip32utils.BIP32Key.fromEntropy(seed)
   bip32_child_key_obj = bip32_root_key_obj.ChildKey(
       44 + bip32utils.BIP32_HARDEN
   ).ChildKey(
       0 + bip32utils.BIP32_HARDEN
   ).ChildKey(
       0 + bip32utils.BIP32_HARDEN
   ).ChildKey(0).ChildKey(0)

   # return {
   #     'mnemonic_words': mnemonic_words,
   #     'bip32_root_key': bip32_root_key_obj.ExtendedKey(),
   #     'bip32_extended_private_key': bip32_child_key_obj.ExtendedKey(),
   #     'bip32_derivation_path': "m/44'/0'/0'/0",
   #     'bip32_derivation_addr': bip32_child_key_obj.Address(),
   #     'coin': 'BTC'
   # }

   return {
       'mnemonic_words': mnemonic_words,
       # 'bip32_root_key': bip32_root_key_obj.ExtendedKey(),
       # 'bip32_extended_private_key': bip32_child_key_obj.ExtendedKey(),
       # 'path': "m/44'/0'/0'/0",
       'addr': bip32_child_key_obj.Address(),
       'publickey': binascii.hexlify(bip32_child_key_obj.PublicKey()).decode(),
       'privatekey': bip32_child_key_obj.WalletImportFormat(),
       'coin': 'BTC'
   }


if __name__ == '__main__':
   mnemonic_words = "aware report movie exile buyer drum poverty supreme gym oppose float elegant"
   pprint.pprint(bip39(mnemonic_words))

我發現了我認為的問題。

你不應該做 Base58.check_encode

要列印 PublicKey,請使用 .hex() 方法。

此外,https: //iancoleman.io/bip39/#english 在 WIF 表單中列印私鑰,因此如果您想要與 iancoleman.io 具有相同的輸出,您應該使用 .WalletImportFormat() 而不是 .PrivateKey() 。這一次,不需要使用 .hex() (再次不需要在 base58 中編碼)

引用自:https://bitcoin.stackexchange.com/questions/76655