0

I am trying to derive addresses from a master public key (aka extended public key) in python. I don't fully understand the math behind the key derivation, but have been able to decode the master public key from base58 to bin and encode the bin to hex. This is now where I am stuck at, I have all the info from the hex including the chain code, but am not sure what to do with the chain code hex. I have tried many different versions of encoded/decoded master public keys and some of them generated addresses, but the addresses were not properly derived from the original master public key.

Master Public Key (base58): ypub6WpT17zUsUE5oPuekrZEHkzk4bF4j9S3CM8VMx3BpiQwxxWMS914zVWEyMRBAJHQiQZRbtX4VLDYo4Y8WQZXCgSkzwEAJ73ToepntwymZ8g

Master Public Key (hex): 049d7cb2032d8b913e8000000059ddf15a4f066a86e3f9035060be5d13fba7fc94ae6ad525b626cb53175deef602e555ecef37d396bf7d641f2d42feb015c90d3d8a690832dc6e118fedecb8789cf58fc09d

I have been using bitaps.com/bip32 to compare if I was ever able to successfully derive the first address in index 0 with BIP49 selected. All of the values on bitaps.com/bip32 correlates with characters in the master public key hex above.

This is the correct public key which is generated for the address in index 0: 02b1fb3ab28ba345fa21521dcf0c09e6f2e8edae0113d562da61ae6dadd6dc5187

How would I be able to use the chain code hex from the master public key hex to generate the public key above for the derivation path m/49'/0'/0'/0/0 and then use that public key to generate the corresponding address in python?

m1xolyd1an
  • 5,636
  • 2
  • 14
  • 30
amint
  • 1
  • 3
  • Check out https://github.com/mcdallas/cryptotools/blob/master/cryptotools/BTC/HD/bip32.py – Mike D Aug 14 '21 at 15:36
  • @MikeD That looks promising, but needs to be modified to work with BIP49. The script which is used in that code sample is P2PKH, I am trying to use P2WPKH-P2SH script. – amint Aug 14 '21 at 16:14
  • No modification is needed, I can reproduce the test vector from bip49 with this command (Xprv.from_mnemonic('abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about')/49./1./0./0/0).key.to_public().to_address('P2WPKH-P2SH') prints '2Mww8dCYPUpKHofjgcXcBCEGmniw9CoaiD2' – Mike D Aug 14 '21 at 17:02
  • @MikeD Is it possible to get from master public key instead of mnemonic? Using Electrum and want to derive the keys from the master public key in python. – amint Aug 14 '21 at 17:26
  • You can’t derive a hardened path from an extended public key so m/49’/0’/0’/0 is not possible – Mike D Aug 14 '21 at 17:38
  • @MikeD well apparently this website bitaps.com/bip32 is able to show all derived addresses and show the balances in those addresses just from the master public key... Also I meant to put this path m/49'/0'/0'/0/0 – amint Aug 14 '21 at 17:44
  • it doesn’t, it interprets your input as the m/49’/0’/0’ key not as the root key – Mike D Aug 14 '21 at 17:51
  • @MikeD how can I capture the same information that bitaps.com/bip32 produces when I input my master public key on their website. Or if it is not possible, then what is used to produce their info? – amint Aug 14 '21 at 17:55
  • for example (Xpub.decode('ypub6WpT17zUsUE5oPuekrZEHkzk4bF4j9S3CM8VMx3BpiQwxxWMS914zVWEyMRBAJHQiQZRbtX4VLDYo4Y8WQZXCgSkzwEAJ73ToepntwymZ8g')/0/0).key.to_address('P2WPKH-P2SH’) produces address ‘ 36eFXx5LfAR7urFC2VUnSTNCUb8z9k8x6a’ the first on the list in that site – Mike D Aug 14 '21 at 18:03
  • @MikeD that is what I was looking for, so technically you can generate an address from an index of 0 - 999999999 and all of those would be valid addresses. I am not sure if I was overcomplicating it, but appreciate the help. – amint Aug 14 '21 at 18:30
  • No Problem. The confusion was because you said that you have the Master public key (which would be m) and want to derive m/49’/0’/0’/0/0 which is not possible since you have to traverse hardened paths. Instead what you have is key m/49’/0’/0’ which you can use to derive m/49’/0’/0’/0/0 (no hardened path inbetween) – Mike D Aug 14 '21 at 18:43
  • @MikeD I just tried to send small transaction to one of the addresses generated, and nothing appeared in my electrum wallet. What is the highest index allowed when generating an address and for it to be valid? – amint Aug 14 '21 at 18:44
  • The funds probably went through but electrum only generates the first 20 addresses by default. Check out https://bitcoin.stackexchange.com/questions/22606/more-receive-addresses-with-electrum – Mike D Aug 14 '21 at 18:50
  • @MikeD The first address I generated straight from electrum and when I sent funds to that first address it instantly noticed it as unconfirmed on electrum. I tried the index 999999999 to see if the transaction would show up on the wallet, but nothing yet. I will try 99 next – amint Aug 14 '21 at 18:55
  • 99 won’t work neither, only up to 20 – Mike D Aug 14 '21 at 18:56
  • @MikeD or the the funds went through on the index 999999999, how do I access the funds from there in electrum? – amint Aug 14 '21 at 18:57
  • @MikeD I see, only up to 20 will work. Then how do you generate random addresses past 20? Is that possible, I have seen somewhere that you can use like for instance an id to randomize the address that is generated. I think its called child key derivation or something of that nature. – amint Aug 14 '21 at 19:02
  • @MikeD 1 last question, I understand the gap limit now. Lets say an address has 16 addresses already used, how would you automatically generate the next address in line without specifying the index? – amint Aug 14 '21 at 21:09

0 Answers0