.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/wallets/derivation/plot_03_bip44_derivation_paths.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_wallets_derivation_plot_03_bip44_derivation_paths.py: Multi-account derivation paths (BIP44, 2014) ============================================ BIP32 allows any tree of keys, so one wallet program could not restore another's from the same seed. Marek Palatinus and Pavol Rusnak fixed five levels, .. math:: m / 44' / \text{coin}' / \text{account}' / \text{change} / \text{index}, and a rule for finding used keys: scan each account's receiving chain until 20 addresses in a row are unused (the gap limit), and stop at the first account with none. A wallet that hands out more than 20 unpaid addresses in a row hides later payments from any other wallet restoring the seed. Here a seed is restored with several gap limits. .. GENERATED FROM PYTHON SOURCE LINES 21-25 .. code-block:: Python import matplotlib.pyplot as plt import blockchainkit as bk .. GENERATED FROM PYTHON SOURCE LINES 26-28 The paths of a wallet --------------------- .. GENERATED FROM PYTHON SOURCE LINES 28-43 .. code-block:: Python master = bk.wallets.master_key(bytes(range(16))) print(bk.wallets.bip44_path(0, 0, 0, 0), "first Bitcoin receiving address") print(bk.wallets.bip44_path(60, 0, 0, 0), "first Ether address") print(bk.wallets.parse_path("m/44'/0'/0'/0/5")) def address(account, index): path = bk.wallets.bip44_path(0, account, 0, index) return bk.wallets.p2pkh_address(bk.wallets.derive_path(master, path).public) # A user paid to addresses 0-3 and 9 of account 0, and to address 0 of account 1. used = {address(0, i) for i in (0, 1, 2, 3, 9)} | {address(1, 0)} .. rst-class:: sphx-glr-script-out .. code-block:: none m/44'/0'/0'/0/0 first Bitcoin receiving address m/44'/60'/0'/0/0 first Ether address (2147483692, 2147483648, 2147483648, 0, 5) .. GENERATED FROM PYTHON SOURCE LINES 44-46 Restoring with different gap limits ----------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 46-68 .. code-block:: Python limits = [2, 4, 5, 6, 8] found = [] for gap in limits: scan = bk.wallets.discover_accounts(master, used, gap_limit=gap) found.append(len(scan.found)) print( f"gap limit {gap}: {scan.accounts} accounts, {len(scan.found)} of 6 addresses," f" {scan.derived} derived" ) assert found[0] < 6 and found[-1] == 6 fig, ax = plt.subplots(figsize=(6, 4)) ax.step(limits, found, where="post", color="#2563eb") ax.plot(limits, found, "o", color="#2563eb") ax.axhline(6, color="#64748b", linestyle="--", label="addresses used") ax.set(xlabel="gap limit", ylabel="used addresses found", ylim=(0, 6.5)) ax.set_title("A gap longer than the limit hides the coins") ax.legend(loc="lower right") fig.tight_layout() plt.show() .. image-sg:: /api/gallery/wallets/derivation/images/sphx_glr_plot_03_bip44_derivation_paths_001.png :alt: A gap longer than the limit hides the coins :srcset: /api/gallery/wallets/derivation/images/sphx_glr_plot_03_bip44_derivation_paths_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none gap limit 2: 2 accounts, 5 of 6 addresses, 11 derived gap limit 4: 2 accounts, 5 of 6 addresses, 17 derived gap limit 5: 2 accounts, 5 of 6 addresses, 20 derived gap limit 6: 2 accounts, 6 of 6 addresses, 29 derived gap limit 8: 2 accounts, 6 of 6 addresses, 35 derived .. GENERATED FROM PYTHON SOURCE LINES 69-74 Exercise -------- The user also pays to address 30 of account 0. What is the smallest gap limit that finds it? A worked solution is in :doc:`/exercises/wallets`. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.291 seconds) .. _sphx_glr_download_api_gallery_wallets_derivation_plot_03_bip44_derivation_paths.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../../../lite/lab/index.html?path=api/gallery/wallets/derivation/plot_03_bip44_derivation_paths.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_03_bip44_derivation_paths.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_03_bip44_derivation_paths.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_03_bip44_derivation_paths.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_