<p>Mycelium HD is <a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki" rel="noreferrer">BIP 44</a> compliant. As specified by BIP 44, the address gap limit is 20. This means that after 20 indexes of unused addresses, the wallet expects that no more addresses are used beyond that point. Therefore if you send funds to an address with a gap of more than 20 indexes between the last used address, the wallet software will not check if that address has received any funds. </p>

CC BY-SA 4.0
2018-07-09T17:38:49.627Z
oh so they did get the money. It just won't show up until they use 223 other addresses first, in this case! Kinda wild. This is actually good news. I was afraid there was a limit on `i`.
toddmo
CC BY-SA 4.0
2018-07-08T23:30:18.607Z
2018-07-08T23:30:18.607Z
user44404
<p>Here's my code to get a child public key from a parent HD key. I adapted it from <a href="https://freedomnode.com/blog/58/generate-bitcoin-wallet-addresses-from-extended-public-key-with-php" rel="nofollow noreferrer">freedomnode</a>:</p>

<pre><code>  public function address_from_master_pub($path = '0/0') {
    if ($this-&gt;xpub === NULL &amp;&amp; $this-&gt;ypub === NULL &amp;&amp; $this-&gt;zpub === NULL) {
      throw new Exception("XPUB, YPUB or ZPUB key is not present!");
    }

    $adapter = Bitcoin::getEcAdapter();
    $slip132 = new Slip132(new KeyToScriptHelper($adapter));
    $registry_classname = 'BitWasp\\Bitcoin\\Network\\Slip132\\'.$this-&gt;network_name.'Registry';
    $bitcoin_prefixes = new $registry_classname();

    if ($this-&gt;xpub !== NULL) {
      $pubPrefix = $slip132-&gt;p2pkh($bitcoin_prefixes);
      $pub = $this-&gt;xpub;
    } else if ($this-&gt;ypub !== NULL) {
      $pubPrefix = $slip132-&gt;p2shP2wpkh($bitcoin_prefixes);
      $pub = $this-&gt;ypub;
    } else if ($this-&gt;zpub !== NULL) {
      $pubPrefix = $slip132-&gt;p2wpkh($bitcoin_prefixes);
      $pub = $this-&gt;zpub;
    }

    $config = new GlobalPrefixConfig([
      new NetworkConfig($this-&gt;network, [
        $pubPrefix,
      ])
    ]);

    $serializer = new Base58ExtendedKeySerializer(
      new ExtendedKeySerializer($adapter, $config)
    );

    $key = $serializer-&gt;parse($this-&gt;network, $pub);
    $child_key = $key-&gt;derivePath($path);

    return $child_key-&gt;getAddress(new AddressCreator())-&gt;getAddress();
  }
</code></pre>

<p>If I use it for index 0 or 1 or 2 (paths <code>0/0</code>, <code>0/1</code>, <code>0/2</code>), it works fine in the sense that if I send bitcoin to that address, I can see the transaction on the public blockchain under the parent <code>xpub</code> on blockchain.com and it shows the funds. Plus, the child addresses which I generate match what shows up in Mycelium HD account receiving address.</p>

<p>But when I used index 243 (thus creating a path of <code>0/243</code> it didn't show up on the receiving end (under that <code>xpub</code>) even though it showed up on my sending end as a confirmed transaction. That path <code>0/243</code> generated a valid bitcoin address, but it didn't show up under that <code>xpub</code> on blockchain.com even after it was confirmed.</p>

<p>What's the rule involved? If <code>i</code> > some limit it no longer works? Or if I use an index "out of order" it doesn't work? Or something else, like Mycelium stopping recognizing child addresses past a certain index (<code>i</code>) and really the fundsa safa just under a higher level new HD xpub? I used the same code to generate all the child addresses for <code>i</code> = 0, 1, 2, and 243.</p>

<address-generation><bip32-hd-wallets><bip44>
BIP 32 child key derivation "stops working" after a certain index (i)
toddmo
# BIP 32 child key derivation "stops working" after a certain index (i)

(Asked by: username_0 on 2018-07-08)

Here's my code to get a child public key from a parent HD key. I adapted it from freedomnode:
  public function address_from_master_pub($path = '0/0') {
    if ($this->xpub === NULL && $this->ypub === NULL && $this->zpub === NULL) {
      throw new Exception("XPUB, YPUB or ZPUB key is not present!");
    }

    $adapter = Bitcoin::getEcAdapter();
    $slip132 = new Slip132(new KeyToScriptHelper($adapter));
    $registry_classname = 'BitWasp\\Bitcoin\\Network\\Slip132\\'.$this->network_name.'Registry';
    $bitcoin_prefixes = new $registry_classname();

    if ($this->xpub !== NULL) {
      $pubPrefix = $slip132->p2pkh($bitcoin_prefixes);
      $pub = $this->xpub;
    } else if ($this->ypub !== NULL) {
      $pubPrefix = $slip132->p2shP2wpkh($bitcoin_prefixes);
      $pub = $this->ypub;
    } else if ($this->zpub !== NULL) {
      $pubPrefix = $slip132->p2wpkh($bitcoin_prefixes);
      $pub = $this->zpub;
    }

    $config = new GlobalPrefixConfig([
      new NetworkConfig($this->network, [
        $pubPrefix,
      ])
    ]);

    $serializer = new Base58ExtendedKeySerializer(
      new ExtendedKeySerializer($adapter, $config)
    );

    $key = $serializer->parse($this->network, $pub);
    $child_key = $key->derivePath($path);

    return $child_key->getAddress(new AddressCreator())->getAddress();
  }

If I use it for index 0 or 1 or 2 (paths 0/0, 0/1, 0/2), it works fine in the sense that if I send bitcoin to that address, I can see the transaction on the public blockchain under the parent xpub on blockchain.com and it shows the funds. Plus, the child addresses which I generate match what shows up in Mycelium HD account receiving address.
But when I used index 243 (thus creating a path of 0/243 it didn't show up on the receiving end (under that xpub) even though it showed up on my sending end as a confirmed transaction. That path 0/243 generated a valid bitcoin address, but it didn't show up under that xpub on blockchain.com even after it was confirmed.
What's the rule involved? If i > some limit it no longer works? Or if I use an index "out of order" it doesn't work? Or something else, like Mycelium stopping recognizing child addresses past a certain index (i) and really the fundsa safa just under a higher level new HD xpub? I used the same code to generate all the child addresses for i = 0, 1, 2, and 243.

**Tags:** address-generation, bip32-hd-wallets, bip44


---

## 1 answers

### Answer by username_1 on 2018-07-08. Score: 5 | Accepted answer

Mycelium HD is [BIP 44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) compliant. As specified by BIP 44, the address gap limit is 20. This means that after 20 indexes of unused addresses, the wallet expects that no more addresses are used beyond that point. Therefore if you send funds to an address with a gap of more than 20 indexes between the last used address, the wallet software will not check if that address has received any funds.

> **Comments:**
> **username_0**: oh so they did get the money. It just won't show up until they use 223 other addresses first, in this case! Kinda wild. This is actually good news. I was afraid there was a limit on `i`.  

---

