.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/consensus/pos/plot_03_sortition.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_consensus_pos_plot_03_sortition.py: Cryptographic sortition: a secret, stake-weighted committee (Algorand 2017) =========================================================================== Algorand chooses a small committee each round by lottery: every unit of stake is a ticket, and each user privately evaluates a verifiable random function on the round seed to learn how many of their tickets won. Nobody can target the committee in advance, because members reveal themselves only when they vote. What to look for ---------------- Seats are proportional to stake, and splitting stake into many accounts earns the same expected seats: there is no Sybil advantage. Committee size varies from round to round around its expected value. The history behind this experiment: :doc:`/history/consensus_breakthroughs`. .. GENERATED FROM PYTHON SOURCE LINES 22-24 Run 300 rounds -------------- .. GENERATED FROM PYTHON SOURCE LINES 24-43 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np import blockchainkit as bk stakes = {"alice": 4000, "bob": 3000, "carol": 2000, "dave": 1000} total, expected = sum(stakes.values()), 30 seats = {name: [] for name in stakes} for r in range(300): seed = r.to_bytes(4, "big") for name, stake in stakes.items(): seats[name].append( bk.consensus.sortition(name.encode(), stake, total, expected, round_seed=seed) ) means = {name: np.mean(v) for name, v in seats.items()} for name, stake in stakes.items(): assert abs(means[name] - expected * stake / total) < 1.5 committee = np.sum([seats[name] for name in stakes], axis=0) .. GENERATED FROM PYTHON SOURCE LINES 44-46 Splitting stake gains nothing ----------------------------- .. GENERATED FROM PYTHON SOURCE LINES 46-73 .. code-block:: Python split = [ sum( bk.consensus.sortition( f"dave-{i}".encode(), 100, total, expected, round_seed=r.to_bytes(4, "big") ) for i in range(10) ) for r in range(300) ] assert abs(np.mean(split) - means["dave"]) < 1.0 fig, (left, right) = plt.subplots(1, 2, figsize=(10, 3.8)) left.bar(stakes.keys(), [means[n] for n in stakes], color="#2563eb", label="mean seats") left.plot( list(stakes), [expected * s / total for s in stakes.values()], "o", color="black", label="expected", ) left.set(ylabel="seats per round", title="Seats follow stake") left.legend() right.hist(committee, bins=20, color="#16a34a", edgecolor="white") right.axvline(expected, color="black", linestyle="--") right.set(xlabel="committee size", title=f"Committee size around {expected}") fig.tight_layout() .. image-sg:: /api/gallery/consensus/pos/images/sphx_glr_plot_03_sortition_001.png :alt: Seats follow stake, Committee size around 30 :srcset: /api/gallery/consensus/pos/images/sphx_glr_plot_03_sortition_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 74-79 Exercise -------- The hash here is computed from a private secret, so others cannot check a user's claimed seats. What does a verifiable random function add, and why must the round seed itself be unpredictable? .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.281 seconds) .. _sphx_glr_download_api_gallery_consensus_pos_plot_03_sortition.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/consensus/pos/plot_03_sortition.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_03_sortition.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_03_sortition.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_03_sortition.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_