{ "cells": [ { "cell_type": "markdown", "id": "4f3e8ba1-d2d2-4393-8c9e-8d324d444230", "metadata": {}, "source": [ "# Preliminaries for Using the Marlowe Starter Kit\n", "\n", "***Before running this notebook, you might want to use Jupyter's \"clear output\" function to erase the results of the previous execution of this notebook. That will make more apparent what has been executed in the current session.***\n", "\n", "The [demeter.run](https://demeter.run/) web3 development platform provides an extension *Cardano Marlowe Runtime* that has Marlowe tools installed and makes available the Marlowe Runtime backend services and a Cardano node. If you are not using [demeter.run](https://demeter.run/), then see [the docker page](docker.md) for instructions on deploying Marlowe Runtime using docker.\n", "\n", "This notebook provides instructions on setting up signing keys and addresses for this starter kit. It covers the following information:\n", "\n", "- Marlowe tools\n", "- Creating addresses and signing keys\n", " - The faucet\n", " - The lender\n", " - The borrower\n", "- Obtaining test ada\n", "- Fund the addresses of the parties\n", " - Using Daedalus or a web-browser wallet\n", " - Using a local faucet at the command line\n", " \n", "[A video works through this Jupyter notebook.](https://youtu.be/hGBmj9ZrYHs)\n", "\n", "You can ask questions about Marlowe in [the #ask-marlowe channel on the IOG Discord](https://discord.com/channels/826816523368005654/936295815926927390) or post problems with this lesson to [the issues list for the Marlowe Starter Kit github repository](https://github.com/input-output-hk/marlowe-starter-kit/issues)." ] }, { "cell_type": "markdown", "id": "4a2ec343-a4e7-4ad6-ae82-0b3ce6c1d2f9", "metadata": {}, "source": [ "## Marlowe Tools\n", "\n", "Three alternative workflows are available for running Marlowe contracts:\n", "1. Marlowe CLI (`marlowe-cli`) for lightweight experiments with Marlowe transactions.\n", "2. Marlowe Runtime CLI (`marlowe-runtime-cli`) for non-web applications that use the Marlowe Runtime backend services.\n", "3. Marlowe Runtime Web (`marlowe-web-server`) for web applications that use Marlowe Runtime backend services.\n", "\n", "Marlowe Runtime provides a variety of transaction-building, UTxO management, querying, and submission services for using Marlowe contracts: this makes it easy to run Marlowe contracts without attending to the details of the Cardano ledger and Plutus smart contracts. On the contrary, Marlowe CLI does not support querying and UTxO management, so it is best suited for experienced Cardano developers.\n", "\n", "" ] }, { "cell_type": "markdown", "id": "1d04e564-9695-43f2-b465-74fab8f21f5b", "metadata": {}, "source": [ "### Access to Cardano node and Marlowe Runtime\n", "\n", "If we're using [demeter.run](https://demeter.run/)'s Cardano Marlowe Runtime extension, then we already have access to Cardano Node and Marlowe Runtime. The followind commands will set the required environment variables to use a local docker deployment on the default ports. It will also set some supplementary environment variables." ] }, { "cell_type": "code", "execution_count": 1, "id": "37eac541-8c51-47ba-b50e-10d70ad321e0", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CARDANO_NODE_SOCKET_PATH = ~/.local/share/containers/storage/volumes/marlowe-starter-kit_shared/_data/node.socket\n", "CARDANO_TESTNET_MAGIC = 1\n" ] } ], "source": [ "if [[ -z \"$MARLOWE_RT_PORT\" ]]\n", "then\n", "\n", " # Only required for `marlowe-cli` and `cardano-cli`.\n", " export CARDANO_NODE_SOCKET_PATH=\"$(docker volume inspect marlowe-starter-kit_shared | jq -r '.[0].Mountpoint')/node.socket\"\n", " export CARDANO_TESTNET_MAGIC=1 # Note that preprod=1 and preview=2. Do not set this variable if using mainnet.\n", "\n", "fi\n", "\n", "# FIXME: This should have been inherited from the parent environment.\n", "if [[ -z \"$CARDANO_NODE_SOCKET_PATH\" ]]\n", "then\n", " export CARDANO_NODE_SOCKET_PATH=/ipc/node.socket\n", "fi\n", "\n", "# FIXME: This should have been set in the parent environment.\n", "if [[ -z \"$CARDANO_TESTNET_MAGIC\" ]]\n", "then\n", " export CARDANO_TESTNET_MAGIC=$CARDANO_NODE_MAGIC\n", "fi\n", "\n", "echo \"CARDANO_NODE_SOCKET_PATH = $CARDANO_NODE_SOCKET_PATH\"\n", "echo \"CARDANO_TESTNET_MAGIC = $CARDANO_TESTNET_MAGIC\"" ] }, { "cell_type": "markdown", "id": "49fff9dc-b2cf-4a63-b1fc-ea5eb0b478e7", "metadata": { "tags": [] }, "source": [ "Note the test network magic number:\n", "- `preprod` = 1\n", "- `preview` = 2" ] }, { "cell_type": "markdown", "id": "979706db-b6a7-4a50-827a-368835374bb8", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "source": [ "## Creating Addresses and Signing Keys\n", "\n", "The [Cardano Developers Portal](https://developers.cardano.org/docs/stake-pool-course/handbook/keys-addresses/) contains instructions for creating addresses and signing keys.\n", "\n", "This starter kit uses the following addresses:\n", "- An ***optional*** local *Faucet* used to fund parties to Marlowe contracts.\n", "- The *Lender* party for the examples in this starter kit.\n", "- The *Borrower* party for the examples in this starter kit.\n", "- The *Mediator* party for some examples in this starter kit.\n", "\n", "The instructions below detail how to create signing keys and addresses for these parties. It is assumed that one has the signing key and address for the faucet and that the faucet is already funded with test ada.\n", "\n", "***IMPORTANT:*** The [keys/](keys/) folder holds the signing keys that will be created for interacting with the Marlowe contract. If you delete or lose these files, then you also forever lose the test ada stored at those addresses. Either backup these files or, after running the tutorials, send the remaining test ada back to a more permanent wallet or return it to the faucet." ] }, { "cell_type": "markdown", "id": "f81c063e-5f03-4dcf-a9b8-297fa2504076", "metadata": {}, "source": [ "### The Faucet\n", "\n", "***This step is optional if one is using a wallet already funded with test ada.***\n", "\n", "Set the file names for this party's signing key and verification key." ] }, { "cell_type": "code", "execution_count": 2, "id": "8bb867d3-f099-4ce9-8411-af904024e729", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [], "source": [ "FAUCET_SKEY=keys/faucet.skey\n", "FAUCET_VKEY=keys/faucet.vkey" ] }, { "cell_type": "markdown", "id": "4aba92c6-85d1-4960-916f-1b9384cd2c06", "metadata": {}, "source": [ "Generate the keys if they haven't already been generated." ] }, { "cell_type": "code", "execution_count": 3, "id": "d3b8e993-a6c8-4307-a8f7-772b15d37731", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [], "source": [ "if [[ ! -e \"$FAUCET_SKEY\" ]]\n", "then\n", " cardano-cli address key-gen \\\n", " --signing-key-file \"$FAUCET_SKEY\" \\\n", " --verification-key-file \"$FAUCET_VKEY\"\n", "fi" ] }, { "cell_type": "markdown", "id": "7f6a11b1-8508-48f7-a876-fa36deeca8cb", "metadata": {}, "source": [ "Compute the faucet's address on the testnet." ] }, { "cell_type": "code", "execution_count": 4, "id": "1f8ede90-4c8d-4c97-a449-36e7a37aca42", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "FAUCET_ADDR = addr_test1vq9prvx8ufwutkwxx9cmmuuajaqmjqwujqlp9d8pvg6gupczgtm9j\n" ] } ], "source": [ "FAUCET_ADDR=$(cardano-cli address build --testnet-magic \"$CARDANO_TESTNET_MAGIC\" --payment-verification-key-file \"$FAUCET_VKEY\" )\n", "echo \"$FAUCET_ADDR\" > keys/faucet.address\n", "echo \"FAUCET_ADDR = $FAUCET_ADDR\"" ] }, { "cell_type": "markdown", "id": "709cad6d-8355-4959-a0a6-db0cac4824ae", "metadata": {}, "source": [ "### The Lender\n", "\n", "Set the file names for this party's signing key and verification key." ] }, { "cell_type": "code", "execution_count": 5, "id": "c66c378f-34f8-484f-acc7-200a40fb2468", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [], "source": [ "LENDER_SKEY=keys/lender.skey\n", "LENDER_VKEY=keys/lender.vkey" ] }, { "cell_type": "markdown", "id": "da7e0e93-aed7-41bb-ade3-5c5f818578f8", "metadata": {}, "source": [ "Generate the keys if they haven't already been generated." ] }, { "cell_type": "code", "execution_count": 6, "id": "e0be461f-2399-4b28-a0c6-21966383bafd", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [], "source": [ "if [[ ! -e \"$LENDER_SKEY\" ]]\n", "then\n", " cardano-cli address key-gen \\\n", " --signing-key-file \"$LENDER_SKEY\" \\\n", " --verification-key-file \"$LENDER_VKEY\"\n", "fi" ] }, { "cell_type": "markdown", "id": "a2aa5789-4857-4a28-ac2c-780444adfbff", "metadata": {}, "source": [ "Compute the party's address on the testnet." ] }, { "cell_type": "code", "execution_count": 7, "id": "67e73e10-0d09-4c8f-b4d0-07ccc34f11cb", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "LENDER_ADDR = addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck\n" ] } ], "source": [ "LENDER_ADDR=$(cardano-cli address build --testnet-magic \"$CARDANO_TESTNET_MAGIC\" --payment-verification-key-file \"$LENDER_VKEY\" )\n", "echo \"$LENDER_ADDR\" > keys/lender.address\n", "echo \"LENDER_ADDR = $LENDER_ADDR\"" ] }, { "cell_type": "markdown", "id": "82c69f5c-c6fe-4aa6-bef2-6daab94adba4", "metadata": {}, "source": [ "### The Borrower\n", "\n", "Set the file names for this party's signing key and verification key." ] }, { "cell_type": "code", "execution_count": 8, "id": "7a4cfdc0-0150-428d-b242-b463dea5a0c7", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [], "source": [ "BORROWER_SKEY=keys/borrower.skey\n", "BORROWER_VKEY=keys/borrower.vkey" ] }, { "cell_type": "markdown", "id": "0a735a03-abfa-443c-9d68-f4b6bdb28386", "metadata": {}, "source": [ "Generate the keys if they haven't already been generated." ] }, { "cell_type": "code", "execution_count": 9, "id": "540e6045-d92c-49da-af39-cd339a5963b0", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [], "source": [ "if [[ ! -e \"$BORROWER_SKEY\" ]]\n", "then\n", " cardano-cli address key-gen \\\n", " --signing-key-file \"$BORROWER_SKEY\" \\\n", " --verification-key-file \"$BORROWER_VKEY\"\n", "fi" ] }, { "cell_type": "markdown", "id": "3c5c365e-ebfe-41ee-9070-78f31710df48", "metadata": {}, "source": [ "Compute the party's address on the testnet." ] }, { "cell_type": "code", "execution_count": 10, "id": "6ed6137d-b9fe-4a87-b0a4-f2b802fa96e4", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "BORROWER_ADDR = addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d\n" ] } ], "source": [ "BORROWER_ADDR=$(cardano-cli address build --testnet-magic \"$CARDANO_TESTNET_MAGIC\" --payment-verification-key-file \"$BORROWER_VKEY\" )\n", "echo \"$BORROWER_ADDR\" > keys/borrower.address\n", "echo \"BORROWER_ADDR = $BORROWER_ADDR\"" ] }, { "cell_type": "markdown", "id": "a888e3e6-bdab-4763-8f7f-5c72c990ea90", "metadata": {}, "source": [ "### The Mediator\n", "\n", "Set the file names for this party's signing key and verification key." ] }, { "cell_type": "code", "execution_count": 11, "id": "89967b6a-01a0-42a6-ba70-258f67a2ddba", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [], "source": [ "MEDIATOR_SKEY=keys/mediator.skey\n", "MEDIATOR_VKEY=keys/mediator.vkey" ] }, { "cell_type": "markdown", "id": "40dd9cf7-5931-47a4-a6c3-6bfcc7031963", "metadata": {}, "source": [ "Generate the keys if they haven't already been generated." ] }, { "cell_type": "code", "execution_count": 12, "id": "81238600-8ae9-43fd-881f-5bb1ab85688d", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [], "source": [ "if [[ ! -e \"$MEDIATOR_SKEY\" ]]\n", "then\n", " cardano-cli address key-gen \\\n", " --signing-key-file \"$MEDIATOR_SKEY\" \\\n", " --verification-key-file \"$MEDIATOR_VKEY\"\n", "fi" ] }, { "cell_type": "markdown", "id": "8ddf1475-a5a1-4d63-a83d-311cb7391500", "metadata": {}, "source": [ "Compute the party's address on the testnet." ] }, { "cell_type": "code", "execution_count": 13, "id": "16cd8dd9-153c-4abc-903e-a91e742044ca", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "MEDIATOR_ADDR = addr_test1vr6tytqs3x8qgewhw89m3xrz58t3tqu2hfsecw0u06lf3hg052wsv\n" ] } ], "source": [ "MEDIATOR_ADDR=$(cardano-cli address build --testnet-magic \"$CARDANO_TESTNET_MAGIC\" --payment-verification-key-file \"$MEDIATOR_VKEY\" )\n", "echo \"$MEDIATOR_ADDR\" > keys/mediator.address\n", "echo \"MEDIATOR_ADDR = $MEDIATOR_ADDR\"" ] }, { "cell_type": "markdown", "id": "74ea3de1-6c14-4ef6-a5ab-e8784cc879cc", "metadata": {}, "source": [ "## Obtaining Test Ada\n", "\n", "In order to execute transactions on a Cardano network, one needs the native currency ada to pay fees and use as funds. There are the faucets for the public testnets at https://docs.cardano.org/cardano-testnet/tools/faucet where one can obtain test ada daily.\n", "\n", "Optionally, it can be convenient to centrally manage funds with the [Daedalus wallet](https://docs.cardano.org/cardano-testnet/daedalus-testnet) or one of the [web-browser wallets](https://builtoncardano.com/ecosystem/wallets): be sure to select the correct public testnet if using one of these wallets.\n", "\n", "If you will be using a local faucet, then send test ada to the faucet address created in the previous section. Otherwise, send the test ada to the Daedalus or web-browser wallet." ] }, { "cell_type": "code", "execution_count": 14, "id": "73e739b1-9d2f-4f36-b1ce-24e9e6c88f4b", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "FAUCET_ADDR = addr_test1vq9prvx8ufwutkwxx9cmmuuajaqmjqwujqlp9d8pvg6gupczgtm9j\n" ] } ], "source": [ "echo \"FAUCET_ADDR = $FAUCET_ADDR\"" ] }, { "cell_type": "markdown", "id": "415587c0-2559-4ecc-b4cc-737fd3d955d9", "metadata": {}, "source": [ "## Fund the Addresses of the Parties\n", "\n", "We'll fund each address with 1000 test ada." ] }, { "cell_type": "code", "execution_count": 15, "id": "7c2069be-6817-4193-90bf-fd2a5fb26de7", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "LENDER_ADDR = addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck\n", "BORROWER_ADDR = addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d\n", "MEDIATOR_ADDR = addr_test1vr6tytqs3x8qgewhw89m3xrz58t3tqu2hfsecw0u06lf3hg052wsv\n" ] } ], "source": [ "echo \"LENDER_ADDR = $LENDER_ADDR\"\n", "echo \"BORROWER_ADDR = $BORROWER_ADDR\"\n", "echo \"MEDIATOR_ADDR = $MEDIATOR_ADDR\"" ] }, { "cell_type": "markdown", "id": "3829569e-7f4a-4d2f-983a-b23d81c5b190", "metadata": {}, "source": [ "### Using Daedalus or a Web-Browser Wallet\n", "\n", "If you already have a wallet wallet that contains test ada, then you can just send the funds to the addresses of the keys that we created in the previous section. The screenshot below shows using Daedalus to fund the lender address.\n", "\n", "" ] }, { "cell_type": "markdown", "id": "2c14be5d-b4ae-4c62-9cc4-271fe79dcaea", "metadata": {}, "source": [ "### Using a Local Faucet at the Command Line\n", "\n", "One can use `cardano-cli` or `marlowe-cli` send funds to an address. Here we use `marlowe-cli`.\n", "\n", "***If you have just funded `FAUCET_ADDR` with ada, you may have to wait a couple of minutes before that transaction is confirmed. If the command below fails, then retry it until it succeeds.***" ] }, { "cell_type": "code", "execution_count": 16, "id": "5bcf4056-963b-41e1-b963-6af2c09498b5", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "TxId \"8461a35e612b38d4cb592e4ba1b7f13c2ff2825942d66e7200acc575cd4c8f1c\"\n" ] } ], "source": [ "# Note that `FAUCET_ADDR` must have already been funded with test ada.\n", "\n", "# 1 ada = 1,000,000 lovelace\n", "ADA=1000000\n", "\n", "# Send 1000 ada\n", "AMOUNT=$((1000 * ADA))\n", "\n", "# Execute the transaction.\n", "marlowe-cli util fund-address \\\n", " --lovelace \"$AMOUNT\" \\\n", " --out-file /dev/null \\\n", " --source-wallet-credentials \"$FAUCET_ADDR\":\"$FAUCET_SKEY\" \\\n", " --submit 600 \\\n", " \"$LENDER_ADDR\" \"$BORROWER_ADDR\" \"$MEDIATOR_ADDR\"" ] }, { "cell_type": "markdown", "id": "a9096d7c-9b21-48a6-b747-c14560486d17", "metadata": {}, "source": [ "See that the addresses have indeed been funded:" ] }, { "cell_type": "code", "execution_count": 17, "id": "d4f822da-45bf-4222-95fa-5ce6a912869b", "metadata": { "tags": [], "vscode": { "languageId": "shellscript" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Lender @ addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck\n", " TxHash TxIx Amount\n", "--------------------------------------------------------------------------------------\n", "8461a35e612b38d4cb592e4ba1b7f13c2ff2825942d66e7200acc575cd4c8f1c 1 1000000000 lovelace + TxOutDatumNone\n", "\n", "\n", "Borrower @ addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d\n", " TxHash TxIx Amount\n", "--------------------------------------------------------------------------------------\n", "8461a35e612b38d4cb592e4ba1b7f13c2ff2825942d66e7200acc575cd4c8f1c 2 1000000000 lovelace + TxOutDatumNone\n", "\n", "\n", "Mediator @ addr_test1vr6tytqs3x8qgewhw89m3xrz58t3tqu2hfsecw0u06lf3hg052wsv\n", " TxHash TxIx Amount\n", "--------------------------------------------------------------------------------------\n", "8461a35e612b38d4cb592e4ba1b7f13c2ff2825942d66e7200acc575cd4c8f1c 3 1000000000 lovelace + TxOutDatumNone\n", "\n" ] } ], "source": [ "echo\n", "echo \"Lender @ $LENDER_ADDR\"\n", "cardano-cli query utxo --testnet-magic \"$CARDANO_TESTNET_MAGIC\" --address \"$LENDER_ADDR\"\n", "echo\n", "\n", "echo\n", "echo \"Borrower @ $BORROWER_ADDR\"\n", "cardano-cli query utxo --testnet-magic \"$CARDANO_TESTNET_MAGIC\" --address \"$BORROWER_ADDR\"\n", "echo\n", "\n", "echo\n", "echo \"Mediator @ $MEDIATOR_ADDR\"\n", "cardano-cli query utxo --testnet-magic \"$CARDANO_TESTNET_MAGIC\" --address \"$MEDIATOR_ADDR\"\n", "echo" ] } ], "metadata": { "kernelspec": { "display_name": "Bash with Marlowe Tools", "language": "bash", "name": "bash-minimal" }, "language_info": { "codemirror_mode": "shell", "file_extension": ".sh", "mimetype": "text/x-sh", "name": "bash" } }, "nbformat": 4, "nbformat_minor": 5 }