.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/contracts/foundations/plot_02_capabilities.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_contracts_foundations_plot_02_capabilities.py: Miller's capabilities: purses, and the tx.origin confused deputy (1997-2006) ============================================================================ In an object-capability system, the only way to act on something is to hold a reference to it. Mark Miller's E language built distributed money on this rule: to pay, hand over a purse holding exactly the payment; the recipient can take that and nothing else. There is no ambient authority, no global "who is calling" to consult. Ambient authority causes the *confused deputy* (Hardy, 1988): a program holding authority for one party is tricked into using it for another. Ethereum's ``tx.origin``, the account that signed the transaction, is ambient: a wallet that checks it pays out whenever its owner's transaction passes through, even when the owner was lured into calling an attacker's contract. Checking ``msg.sender``, the immediate caller, closes the hole. .. GENERATED FROM PYTHON SOURCE LINES 20-25 .. code-block:: Python import matplotlib.pyplot as plt import blockchainkit as bk from blockchainkit.contracts.visualizers import plot_call_tree .. GENERATED FROM PYTHON SOURCE LINES 26-28 Paying with a purse ------------------- .. GENERATED FROM PYTHON SOURCE LINES 28-40 .. code-block:: Python mint = bk.contracts.Mint("carol-bucks") alice, bob = mint.make_purse(100), mint.make_purse(0) payment = alice.sprout() payment.deposit(25, alice) # Alice moves 25 into a purse she will hand over. bob.deposit(25, payment) # Bob holds only the payment purse... try: bob.deposit(1, payment) except ValueError as error: print("Bob cannot take more:", error) # ...so he cannot reach Alice's 75. assert (alice.balance, bob.balance) == (75, 25) .. rst-class:: sphx-glr-script-out .. code-block:: none Bob cannot take more: insufficient funds in the source purse .. GENERATED FROM PYTHON SOURCE LINES 41-43 The confused deputy ------------------- .. GENERATED FROM PYTHON SOURCE LINES 43-65 .. code-block:: Python theft = {} for wallet_code in (bk.contracts.OriginWallet, bk.contracts.SenderWallet): world = bk.contracts.World() world.fund("alice", 100) wallet = world.deploy("alice", wallet_code, name="alice's wallet") world.transact("alice", wallet, value=100) phisher = world.deploy("mallory", bk.contracts.AirdropPhisher, name="airdrop") receipt = world.transact("alice", phisher, "claim_airdrop", wallet) theft[wallet_code.__name__] = (world, receipt, world.balance("mallory")) print(f"{wallet_code.__name__}: Mallory gets {world.balance('mallory')}") assert theft["OriginWallet"][2] == 100 and theft["SenderWallet"][2] == 0 fig, (top, bottom) = plt.subplots(2, 1, figsize=(9, 4.5)) for ax, name in ((top, "OriginWallet"), (bottom, "SenderWallet")): world, receipt, _ = theft[name] plot_call_tree(receipt, names=world.name, ax=ax) ax.set_title(f"{name}: {ax.get_title()}") fig.tight_layout() plt.show() .. image-sg:: /api/gallery/contracts/foundations/images/sphx_glr_plot_02_capabilities_001.png :alt: OriginWallet: Call tree: 3 calls, 24,800 gas, succeeded, SenderWallet: Call tree: 2 calls, 24,100 gas, reverted (not the owner) :srcset: /api/gallery/contracts/foundations/images/sphx_glr_plot_02_capabilities_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none OriginWallet: Mallory gets 100 SenderWallet: Mallory gets 0 .. GENERATED FROM PYTHON SOURCE LINES 66-71 Exercise -------- ``SenderWallet`` still authorizes by identity. Write a wallet contract that instead pays whoever presents a secret it was given at deployment. Which of the two designs is closer to a capability, and what new risk does it bring? .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.055 seconds) .. _sphx_glr_download_api_gallery_contracts_foundations_plot_02_capabilities.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/contracts/foundations/plot_02_capabilities.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_02_capabilities.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_02_capabilities.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_02_capabilities.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_