.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/wallets/addresses/plot_01_base58check_addresses.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_addresses_plot_01_base58check_addresses.py: Base58Check addresses (2009) ============================ Bitcoin's first release wrote an address as a version byte, the 20-byte ``HASH160`` of a public key and a 4-byte checksum, in base 58: the digits and letters without 0, O, I and l, which are easily confused. A wallet refuses to pay an address whose checksum fails, so a typo is caught unless it happens to match the checksum, with probability .. math:: 2^{-32} \approx 2.3 \times 10^{-10}. The account names of :mod:`blockchainkit.structures` are bare SHA-256 digests, where every typo is just another valid account. Here every single-character typo of an address is tried. .. 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 address of a key -------------------- .. GENERATED FROM PYTHON SOURCE LINES 28-37 .. code-block:: Python key = bk.crypto.public_key(1) address = bk.wallets.p2pkh_address(key) print("private key 1 ->", address) print("uncompressed ->", bk.wallets.p2pkh_address(key, compressed=False)) version, payload = bk.wallets.base58check_decode(address) print("version", version, "HASH160", payload.hex()) assert address == "1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH" .. rst-class:: sphx-glr-script-out .. code-block:: none private key 1 -> 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH uncompressed -> 1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm version 0 HASH160 751e76e8199196d454941c45d1b3a323f1433bd6 .. GENERATED FROM PYTHON SOURCE LINES 38-40 Every single-character typo --------------------------- .. GENERATED FROM PYTHON SOURCE LINES 40-63 .. code-block:: Python alphabet = bk.wallets.ALPHABET typos = [ address[:i] + c + address[i + 1 :] for i in range(len(address)) for c in alphabet if c != address[i] ] accepted = [t for t in typos if bk.wallets.is_valid_address(t)] print(f"{len(typos):,} typos, {len(accepted)} accepted") assert not accepted # An unchecked hex name accepts every typo: each is some other account. plain = bk.crypto.sha256(bk.crypto.encode_point(key)).hex() plain_typos = len(plain) * 15 fig, ax = plt.subplots(figsize=(6, 4)) ax.bar(["hex digest", "Base58Check"], [plain_typos, len(accepted)], color=["#dc2626", "#2563eb"]) ax.set(ylabel="single-character typos accepted") ax.set_title(f"Of {len(typos):,} typos, the checksum refuses all") fig.tight_layout() plt.show() .. image-sg:: /api/gallery/wallets/addresses/images/sphx_glr_plot_01_base58check_addresses_001.png :alt: Of 1,938 typos, the checksum refuses all :srcset: /api/gallery/wallets/addresses/images/sphx_glr_plot_01_base58check_addresses_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none 1,938 typos, 0 accepted .. GENERATED FROM PYTHON SOURCE LINES 64-69 Exercise -------- How many of the typos that swap two neighbouring characters does the checksum accept? A worked solution is in :doc:`/exercises/wallets`. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.054 seconds) .. _sphx_glr_download_api_gallery_wallets_addresses_plot_01_base58check_addresses.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/addresses/plot_01_base58check_addresses.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_01_base58check_addresses.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_01_base58check_addresses.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_01_base58check_addresses.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_