.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/privacy/analysis/plot_02_fistful_of_bitcoins_clustering.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_privacy_analysis_plot_02_fistful_of_bitcoins_clustering.py: A Fistful of Bitcoins: clustering addresses by owner (2013) =========================================================== Meiklejohn, Pomarole, Jordan, Levchenko, McCoy, Voelker and Savage showed that fresh addresses hide much less than they seem. Two heuristics group addresses that one user controls: - the inputs of one transaction share an owner, who signed them all; - a transaction's *change* goes to a fresh address: if exactly one output address has never been seen before, it is the sender's. Each heuristic adds edges to a graph of addresses, and the clusters are its connected components (found with union-find). Buying a few things from a service then names its whole cluster. .. GENERATED FROM PYTHON SOURCE LINES 19-24 .. code-block:: Python import matplotlib.pyplot as plt import blockchainkit as bk from blockchainkit.privacy.visualizers import plot_cluster_sizes .. GENERATED FROM PYTHON SOURCE LINES 25-28 A toy economy with known owners ------------------------------- Payees reuse a receiving address 90% of the time, as shops do. .. GENERATED FROM PYTHON SOURCE LINES 28-41 .. code-block:: Python history = bk.privacy.simulate_payments(150, 1_500, reuse=0.9, seed=13) print(f"{len(history.transactions)} transactions, {len(history.owners)} addresses, 150 users") inputs_only = bk.privacy.cluster_addresses(history.transactions) with_change = bk.privacy.cluster_addresses(history.transactions, change=True) for name, clusters in (("inputs only", inputs_only), ("with change", with_change)): score = bk.privacy.score_clusters(clusters, history.owners) print( f"{name:12}: {score.clusters} clusters, {score.identified} users identified, " f"{score.false_merges} false merges" ) assert len(with_change) < len(inputs_only) .. rst-class:: sphx-glr-script-out .. code-block:: none 1648 transactions, 1871 addresses, 150 users inputs only : 1322 clusters, 0 users identified, 0 false merges with change : 316 clusters, 49 users identified, 0 false merges .. GENERATED FROM PYTHON SOURCE LINES 42-45 When payees never reuse addresses --------------------------------- Two fresh outputs make the change ambiguous, and the heuristic abstains. .. GENERATED FROM PYTHON SOURCE LINES 45-58 .. code-block:: Python careful = bk.privacy.simulate_payments(150, 1_500, reuse=0.0, seed=13) careful_clusters = bk.privacy.cluster_addresses(careful.transactions, change=True) print("no reuse:", bk.privacy.score_clusters(careful_clusters, careful.owners)) fig, ax = plt.subplots(figsize=(6, 4)) plot_cluster_sizes(inputs_only, ax=ax, label="inputs only") plot_cluster_sizes(with_change, ax=ax, label="inputs and change") ax.set_title("Change outputs merge clusters into users") fig.tight_layout() plt.show() .. image-sg:: /api/gallery/privacy/analysis/images/sphx_glr_plot_02_fistful_of_bitcoins_clustering_001.png :alt: Change outputs merge clusters into users :srcset: /api/gallery/privacy/analysis/images/sphx_glr_plot_02_fistful_of_bitcoins_clustering_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none no reuse: ClusterScore(addresses=3239, users=150, clusters=2614, false_merges=0, identified=0, largest=6) .. GENERATED FROM PYTHON SOURCE LINES 59-64 Exercise -------- A user always spends exactly one coin per payment. Which heuristic still links that user's addresses, and when does it abstain? A worked solution is in :doc:`/exercises/privacy`. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.135 seconds) .. _sphx_glr_download_api_gallery_privacy_analysis_plot_02_fistful_of_bitcoins_clustering.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/privacy/analysis/plot_02_fistful_of_bitcoins_clustering.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_02_fistful_of_bitcoins_clustering.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_02_fistful_of_bitcoins_clustering.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_02_fistful_of_bitcoins_clustering.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_