我正在尝试根据BIP0039从助记符创建一组公用/专用密钥。我正在使用Python。
这是我到目前为止的代码:
from mnemonic import Mnemonic
mnemon = Mnemonic('english')
words = mnemon.generate(256)
mnemon.check(words)
seed = mnemon.to_seed(words)
在BIP0039中,声明您应该能够获得带有种子的Key,但是我无法使用bip32utils在Python中弄清楚它。有没有人举过一个例子,说明如何使用bip32utils将种子转换成私钥/公钥及其各自的地址?
答案 0 :(得分: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/bips,xprv...
。如果这对您来说已经足够了,那么您就不需要 bip32utils。
但是,据我所知,mnemonic 不支持从中派生私钥、链码、公钥或扩展公钥。这只是在 bip32utils 类中实现的。
我不清楚哪些库可以使用,哪些不可以。您可能需要自己实现缺少的功能(付出相应的努力):
链码和私钥可以从扩展私钥中确定。为此,您只需要了解格式(参见例如 bitcon/bips)。如果曲线已知(比特币为 secp256k1)(为此需要 ec 算法或 ec 库),则公钥可以从私钥导出,因此是扩展公钥。 bip32utils 可以作为这方面的蓝图。