# Bitcoin HD Wallets with hardened derivation and watch-only addresses

I'm learning about the details of how HD wallets work. After reading the BIP32 and BIP44 documents thoroughly and supplementing it with Mastering Bitcoin there's still on aspect that I can't figure out.

Say I derive an extended private key with the BIP44 first account, first address path path: `m/44'/0'/0'/0/0` and then I convert the extended private key into an extended public key.

Based on what I've read so far proper way would be to take the extended public key and work with an entirely non-hardened path like: `M/0/1` , `M/0/2` ?

Is this the correct way to do it ? My problem is that a public key of `M/44'/0'/0'/0/1` will not be the same as `M/0/1`.

I'm just trying to make sure I'm using the derivation paths correctly. Thanks a lot!

• "Based on what I've read so far" -> where did you read this? Could be that the m in `m/0/1` refers to the key derived from `m/44'/0'/0'/0/0` and not the master key. Jan 21, 2019 at 17:02
• @JBaczuk , `m/0/1` refers exactly to the path it pertains to. `m/44'/0'/0'/0/0` is a bip44 path. Not sure which wallet uses `m/0/1`, if any. In any case, publicly deriving straight from the master key is a huge footgun. Jan 21, 2019 at 18:12
• @arubi A wallet is not a good example for this because the wallet will have access to the private keys - hence it will allow for a lot more flexibility when deriving different paths. The constraint here is generating a chain of addresses just from a public key (say on a server) and reconciling them on the machine that holds the master keys (say an air-gapped computer). Jan 21, 2019 at 21:03
• What I'm saying is, whatever you're doing, deriving non hardened paths straight from the extended private key seems like a footgun to me. You can easily derive non hardened keys from some standard path like bip44, or you could replace the hardened `44'` with some other non-standard number to achieve the same result. `m/0/1` is not the way to go, imo. Jan 21, 2019 at 21:45
• @arubi sorry I misunderstood what you meant. I completely agree, I would derive the BIP44 path to get the extended private + chain code, then convert that to an extended public + chain code, and I'd use that instead to generate the M/0/1 and so on. Jan 21, 2019 at 21:57

Use the master key (call it m) to derive m/44'/0'/0'. This will give you a pair of public/private keys, let's call them xpub-a and xprv-a.

Now you can take xpub-a onto your online machine, and use xpub-a to derive receive addresses (xpub-a/0/0, xpub-a/0/1, etc) and change addresses (xpub-a/1/0, xpub-a/1/1, etc).

In this way, you've used hardened derivation concatenated with non-hardened derivation for your change and receive addresses. Your final addresses from the path of your master key (m), will then be:

m/44'/0'/0'/0/0

m/44'/0'/0'/0/1 ... etc.

m/44'/0'/0'/1/0

m/44'/0'/0'/1/1 ...etc...

Example using bip32:

let master = bip32.fromBase58('xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi')

let final = master.derivePath("m/44'/0'/0'/0/0")

let middle = master.derivePath("m/44'/0'/0'").neutered() // "neutered" removes the private key

let final2 = middle.derivePath("0/0");

// observe that final.neutered().toBase58() === final2.toBase58()

• Can someone confirm that this would be the case ? I haven't seen it when trying to derive addresses m/44'/0'/0'/0/0 (xpub-a) is not equal to M/0/0 (with xpub-a and xpub-a chaincode as input) Jan 21, 2019 at 21:05
• made some edits that hopefully help explain Jan 22, 2019 at 2:41
• that's right! I verified this and it's correct. The problem was deriving the initial extended public key with M/44'/0'/0'/0/0 instead of m/44'/0'/0' Jan 22, 2019 at 16:40

Is this the correct way to do it ? My problem is that a public key of M/44'/0'/0'/0/1 will not be the same as M/0/1.

`M/44'/0'/0'/0/1` and `M/0/1` represent different derivation paths, so naturally they will result in different extended public keys. Identical keys have identical derivation paths.

`M/44'/0'/0'/0/n` is derived from the corresponding extended private key `m/44'/0'/0'/0/n`, or from the "last" hardened extended public key along the derivation path, `M/44'/0'/0'`.

To generate wallet receiving private keys, use the following paths:

• `m/44'/0'/0'/0/0`
• `m/44'/0'/0'/0/1`
• `m/44'/0'/0'/0/2`
• ...

and for wallet change private keys...

• `m/44'/0'/0'/1/0`
• `m/44'/0'/0'/1/1`
• `m/44'/0'/0'/1/2`
• ...
• That won't work, as you can't do hardened derivation from an xpub. Jan 22, 2019 at 8:03
• Answer has been edited accordingly. Jan 22, 2019 at 8:10