<p>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.</p>
<p>Master Public Key (base58): <code>ypub6WpT17zUsUE5oPuekrZEHkzk4bF4j9S3CM8VMx3BpiQwxxWMS914zVWEyMRBAJHQiQZRbtX4VLDYo4Y8WQZXCgSkzwEAJ73ToepntwymZ8g</code></p>
<p>Master Public Key (hex):
<code>049d7cb2032d8b913e8000000059ddf15a4f066a86e3f9035060be5d13fba7fc94ae6ad525b626cb53175deef602e555ecef37d396bf7d641f2d42feb015c90d3d8a690832dc6e118fedecb8789cf58fc09d</code></p>
<p>I have been using <code>bitaps.com/bip32</code> to compare if I was ever able to successfully derive the first address in index 0 with BIP49 selected. All of the values on <code>bitaps.com/bip32</code> correlates with characters in the master public key hex above.</p>
<p>This is the correct public key which is generated for the address in index 0:
<code>02b1fb3ab28ba345fa21521dcf0c09e6f2e8edae0113d562da61ae6dadd6dc5187</code></p>
<p>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 <code>m/49'/0'/0'/0/0</code> and then use that public key to generate the corresponding address in python?</p>

CC BY-SA 4.0
2021-08-14T15:36:46.767Z
Check out https://github.com/mcdallas/cryptotools/blob/master/cryptotools/BTC/HD/bip32.py
Mike D
CC BY-SA 4.0
2021-08-14T16:14:51.030Z
@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
CC BY-SA 4.0
2021-08-14T17:02:36.287Z
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
CC BY-SA 4.0
2021-08-14T17:26:55.280Z
@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
CC BY-SA 4.0
2021-08-14T17:38:11.420Z
You can’t derive a hardened path from an extended public key so `m/49’/0’/0’/0` is not possible
Mike D
CC BY-SA 4.0
2021-08-14T17:44:56.057Z
@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
CC BY-SA 4.0
2021-08-14T17:51:42.943Z
it doesn’t, it interprets your input as the m/49’/0’/0’ key not as the root key
Mike D
CC BY-SA 4.0
2021-08-14T17:55:54.297Z
@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
CC BY-SA 4.0
2021-08-14T18:03:00.423Z
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
CC BY-SA 4.0
2021-08-14T18:30:09.650Z
@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
CC BY-SA 4.0
2021-08-14T18:43:18.930Z
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
CC BY-SA 4.0
2021-08-14T18:44:43.613Z
@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
CC BY-SA 4.0
2021-08-14T18:50:23.173Z
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
CC BY-SA 4.0
2021-08-14T18:55:30.073Z
@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
CC BY-SA 4.0
2021-08-14T18:56:50.193Z
99 won’t work neither, only up to 20
Mike D
CC BY-SA 4.0
2021-08-14T18:57:13.973Z
@MikeD or the the funds went through on the index 999999999, how do I access the funds from there in electrum?
amint
CC BY-SA 4.0
2021-08-14T19:02:55.880Z
@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
CC BY-SA 4.0
2021-08-14T21:09:55.577Z
@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
<bip32-hd-wallets><public-key><python><p2sh><base58>
How do you Derive Addresses from a BIP49 Master Public Key using P2WPKH-P2SH?
amint
# How do you Derive Addresses from a BIP49 Master Public Key using P2WPKH-P2SH?

(Asked by: username_0 on 2021-08-14)

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?

**Tags:** bip32-hd-wallets, public-key, python, p2sh, base58

> **Comments:**
> **username_1**: Check out https://github.com/mcdallas/cryptotools/blob/master/cryptotools/BTC/HD/bip32.py  
> **username_0**: @username_1 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.  
> **username_1**: 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'  
> **username_0**: @username_1 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.  
> **username_1**: You can’t derive a hardened path from an extended public key so `m/49’/0’/0’/0` is not possible  
> **username_0**: @username_1 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  
> **username_1**: it doesn’t, it interprets your input as the m/49’/0’/0’ key not as the root key  
> **username_0**: @username_1 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?  
> **username_1**: for example `(Xpub.decode('ypub6WpT17zUsUE5oPuekrZEHkzk4bF4j9S3CM8VMx3BpiQwxxWMS914zVWEyMRBAJHQiQZRbtX4VLDYo4Y8WQZXCgSkzwEAJ73ToepntwymZ8g')/0/0).key.to_address('P2WPKH-P2SH’)` produces address ‘ 36eFXx5LfAR7urFC2VUnSTNCUb8z9k8x6a’ the first on the list in that site  
> **username_0**: @username_1 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.  
> **username_1**: 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)  
> **username_0**: @username_1 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?  
> **username_1**: 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  
> **username_0**: @username_1 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  
> **username_1**: 99 won’t work neither, only up to 20  
> **username_0**: @username_1 or the the funds went through on the index 999999999, how do I access the funds from there in electrum?  
> **username_0**: @username_1 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.  
> **username_0**: @username_1 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?  

---

## 0 answers

