.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/channels/interoperability/plot_01_atomic_swaps.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_channels_interoperability_plot_01_atomic_swaps.py: Tier Nolan's atomic cross-chain swaps (2013) ============================================ Alice has coins on chain A, Bob on chain B, and neither will pay first. Tier Nolan's protocol ties both payments to one secret. Alice locks her coins to Bob behind the hash of a secret, refundable to her at :math:`T_A`; Bob locks his to Alice behind the same hash, refundable at :math:`T_B`. Alice claims on B by revealing the secret, and Bob reads it there and claims on A. The swap is atomic if .. math:: T_A > T_B + \text{Bob's reaction time}, because Alice must reveal before :math:`T_B` to be paid, and Bob then has until :math:`T_A` to use the secret. .. GENERATED FROM PYTHON SOURCE LINES 21-26 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np import blockchainkit as bk .. GENERATED FROM PYTHON SOURCE LINES 27-29 Honest parties, and Alice walking away -------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 29-47 .. code-block:: Python def new_swap(timeout_a, timeout_b): swap = bk.channels.AtomicSwap( 7, 5, b"swap secret", amount_a=10, amount_b=3, timeout_a=timeout_a, timeout_b=timeout_b ) swap.lock_bob() return swap honest = new_swap(48, 24) assert honest.claim_b(height=10) and honest.claim_a(height=11) print("honest:", honest.outcome()) walked = new_swap(48, 24) # Alice never claims; both refund. assert walked.refund_b(height=24) and walked.refund_a(height=48) assert walked.outcome().refunded .. rst-class:: sphx-glr-script-out .. code-block:: none honest: SwapOutcome(alice=(0, 3), bob=(10, 0), secret_revealed=True) .. GENERATED FROM PYTHON SOURCE LINES 48-53 Alice's best strategy against each pair of timeouts --------------------------------------------------- Alice reveals the secret on B at some height before Bob's refund at T_B = 24, and also takes her refund on A the moment T_A arrives. Bob claims on A one block after the secret appears. .. GENERATED FROM PYTHON SOURCE LINES 53-81 .. code-block:: Python margins = range(-12, 13, 3) # T_A - T_B. claims = range(4, 24, 3) # The height at which Alice reveals. grid = np.zeros((len(claims), len(margins))) for j, margin in enumerate(margins): timeout_b = 24 for i, reveal in enumerate(claims): swap = new_swap(timeout_b + margin, timeout_b) events = sorted([(reveal, "claim"), (timeout_b + margin, "refund")]) for height, action in events: if action == "claim" and swap.claim_b(height=height): swap.claim_a(height=height + 1) elif action == "refund": swap.refund_a(height=height) grid[i, j] = swap.outcome().atomic print("atomic for every reveal height when T_A - T_B >= 3:", grid[:, margins.index(3)].all()) assert grid[:, margins.index(3) :].all() and not grid[:, : margins.index(0)].all() fig, ax = plt.subplots(figsize=(8, 4)) ax.imshow(grid, origin="lower", cmap="RdYlGn", aspect="auto", vmin=0, vmax=1) ax.set_xticks(range(len(margins)), labels=list(margins)) ax.set_yticks(range(len(claims)), labels=list(claims)) ax.set(xlabel="T_A - T_B (blocks)", ylabel="height at which Alice reveals") ax.set_title("Green: nobody loses. Red: Alice keeps both coins") fig.tight_layout() plt.show() .. image-sg:: /api/gallery/channels/interoperability/images/sphx_glr_plot_01_atomic_swaps_001.png :alt: Green: nobody loses. Red: Alice keeps both coins :srcset: /api/gallery/channels/interoperability/images/sphx_glr_plot_01_atomic_swaps_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none atomic for every reveal height when T_A - T_B >= 3: True .. GENERATED FROM PYTHON SOURCE LINES 82-88 Exercise -------- Even with safe timeouts, Alice holds a free option: after Bob locks, she can wait until just before ``T_B`` and complete the swap only if the exchange rate has moved in her favour. How long does the option last, and what could Bob charge for it? .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.810 seconds) .. _sphx_glr_download_api_gallery_channels_interoperability_plot_01_atomic_swaps.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/channels/interoperability/plot_01_atomic_swaps.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_01_atomic_swaps.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_01_atomic_swaps.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_01_atomic_swaps.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_