{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Marlowe Lang\n", "\n", "\n", "Some basic usage-example for marlowe_lang.\n", "There is also an interactive example published at [runkit.com](https://runkit.com/olofblomqvist/marlowe-dsl-example)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "marlowe_lang utils initialized.\n" ] } ], "source": [ "// depending on your env, you might want to use import * as m from 'marlowe_lang' (optionally using web/nodejs tags)\n", "let m = require('marlowe_lang')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Working with JSON" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\n", " \"when\": [],\n", " \"timeout_continuation\": \"close\",\n", " \"timeout\": 123\n", "}\n" ] } ], "source": [ "// Converting Marlowe DSL to JSON\n", "let json_encoded_contract = m.marlowe_to_json_with_variables('When [] (TimeParam \"var1\") Close',\"var1=123\") // or just marlowe_to_json if you dont need variables\n", "json_encoded_contract\n", "// if you just want to populate variables without converting to json, you can do:\n", "// m.parse_marlowe_with_variables(contract,\"Price=1\")" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "When [ ] 123 Close\n" ] } ], "source": [ "m.decode_marlowe_dsl_from_json(json_encoded_contract)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using the state machine" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Viewing current contract state\n", "**ie. next acceptable input actions**" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\n", " \"WaitingForInput\": {\n", " \"expected\": [\n", " {\n", " \"Deposit\": {\n", " \"who_is_expected_to_pay\": {\n", " \"role_token\": \"Buyer\"\n", " },\n", " \"expected_asset_type\": {\n", " \"token_name\": \"\",\n", " \"currency_symbol\": \"\"\n", " },\n", " \"expected_amount\": 1000000,\n", " \"expected_target_account\": {\n", " \"role_token\": \"Seller\"\n", " },\n", " \"continuation\": \"close\"\n", " }\n", " }\n", " ],\n", " \"timeout\": 3487663680000\n", " }\n", "}\n" ] } ], "source": [ "let m = require('marlowe_lang')\n", "\n", "// Examine some contract state\n", "let contract = `When\n", " [Case\n", " (Deposit\n", " (Role \"Seller\")\n", " (Role \"Buyer\")\n", " (Token \"\" \"\")\n", " (ConstantParam \"Price\")\n", " )\n", " Close ]\n", " 3487663680000 Close \n", "`\n", "// Populate the variables\n", "let core_dsl = m.parse_marlowe_with_variables(contract,'Price=1000000');\n", "\n", "// Create state machine and process until it closes or requires input\n", "let machine = new m.WASMMarloweStateMachine(core_dsl,\"\");\n", "machine.process();\n", "\n", "// Read current state and print to console\n", "let current_state = machine.machine_state_json();\n", "current_state" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Parameters\n", "\n", "Marlowe has support for using variables, but those need to be set prior to initializing a contract so that it can run.\n", "You can inspect the parameters for a contract using \"get_input_params_for_contract\", and set them using \"parse_marlowe_with_variables\"" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The contract has the following variables [ 'CONST_PARAM:Price' ]\n", "After populating the 'Price' variable, the contract looks like this (marlowe core dsl) When [ (Case (Deposit (Role \"Seller\") (Role \"Buyer\") (Token \"\" \"\") (Constant 666)) Close) ] 3487663680000 Close\n" ] } ], "source": [ "let param_list = m.get_input_params_for_contract(contract)\n", "let marlowe_core_dsl = m.parse_marlowe_with_variables(contract,\"Price=666\")\n", "\n", "console.log(\"The contract has the following variables\",param_list)\n", "console.log(\"After populating the 'Price' variable, the contract looks like this (marlowe core dsl)\",marlowe_core_dsl)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Working with CBORHEX" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "// Some example datum from here: https://preprod.cexplorer.io/tx/0b4fbb9e3ab2ada2249ab3b8b8f7520a833c224c19420f1fecef22601f9d6218\n", "let example_datum_cbor_hex = \"d8799fd8799f40ffd8799fa1d8799fd8799fd87980d8799fd8799f581c8b4e5029a73fd4155dfdcb5013e28db2fafb3e1ab487275f4aa50903ffd8799fd8799fd8799f581ccce6bfa02342d29adce20d09d3824463bfb59b0753d7d1d8514b376cffffffffffd8799f4040ffff1a001e8480a0a000ffd87c9f9fd8799fd8799fd8799fd87980d8799fd8799f581c8b4e5029a73fd4155dfdcb5013e28db2fafb3e1ab487275f4aa50903ffd8799fd8799fd8799f581ccce6bfa02342d29adce20d09d3824463bfb59b0753d7d1d8514b376cffffffffffd8799fd87980d8799fd8799f581c8b4e5029a73fd4155dfdcb5013e28db2fafb3e1ab487275f4aa50903ffd8799fd8799fd8799f581ccce6bfa02342d29adce20d09d3824463bfb59b0753d7d1d8514b376cffffffffffd8799f581c9772ff715b691c0444f333ba1db93b055c0864bec48fff92d1f2a7fe51446a65645f746573744d6963726f555344ffd87a9f1a3b9aca00ffffd87a9fd8799fd87980d8799fd8799f581c8b4e5029a73fd4155dfdcb5013e28db2fafb3e1ab487275f4aa50903ffd8799fd8799fd8799f581ccce6bfa02342d29adce20d09d3824463bfb59b0753d7d1d8514b376cffffffffffd87a9fd8799fd87980d8799fd8799f581c8b4e5029a73fd4155dfdcb5013e28db2fafb3e1ab487275f4aa50903ffd8799fd8799fd8799f581ccce6bfa02342d29adce20d09d3824463bfb59b0753d7d1d8514b376cffffffffffffd8799f581c9772ff715b691c0444f333ba1db93b055c0864bec48fff92d1f2a7fe51446a65645f746573744d6963726f555344ffd87a9f1a3b9aca00ffd87c9f9fd8799fd8799fd8799fd87980d8799fd8799f581c8b4e5029a73fd4155dfdcb5013e28db2fafb3e1ab487275f4aa50903ffd8799fd8799fd8799f581ccce6bfa02342d29adce20d09d3824463bfb59b0753d7d1d8514b376cffffffffffd8799fd87980d8799fd8799f581c8b4e5029a73fd4155dfdcb5013e28db2fafb3e1ab487275f4aa50903ffd8799fd8799fd8799f581ccce6bfa02342d29adce20d09d3824463bfb59b0753d7d1d8514b376cffffffffffd8799f581c9772ff715b691c0444f333ba1db93b055c0864bec48fff92d1f2a7fe51446a65645f746573744d6963726f555344ffd87f9fd87e9fd87a9f1a000186a0ffd87a9f1a3b9aca00ffffd87a9f1a000f4240ffffffd87a9fd8799fd87980d8799fd8799f581c8b4e5029a73fd4155dfdcb5013e28db2fafb3e1ab487275f4aa50903ffd8799fd8799fd8799f581ccce6bfa02342d29adce20d09d3824463bfb59b0753d7d1d8514b376cffffffffffd87a9fd8799fd87980d8799fd8799f581c8b4e5029a73fd4155dfdcb5013e28db2fafb3e1ab487275f4aa50903ffd8799fd8799fd8799f581ccce6bfa02342d29adce20d09d3824463bfb59b0753d7d1d8514b376cffffffffffffd8799f581c9772ff715b691c0444f333ba1db93b055c0864bec48fff92d1f2a7fe51446a65645f746573744d6963726f555344ffd87f9fd87e9fd87a9f1a000186a0ffd87a9f1a3b9aca00ffffd87a9f1a000f4240ffffd87c9f9fd8799fd8799fd8799fd87980d8799fd8799f581c8b4e5029a73fd4155dfdcb5013e28db2fafb3e1ab487275f4aa50903ffd8799fd8799fd8799f581ccce6bfa02342d29adce20d09d3824463bfb59b0753d7d1d8514b376cffffffffffd8799fd87980d8799fd8799f581c8b4e5029a73fd4155dfdcb5013e28db2fafb3e1ab487275f4aa50903ffd8799fd8799fd8799f581ccce6bfa02342d29adce20d09d3824463bfb59b0753d7d1d8514b376cffffffffffd8799f581c9772ff715b691c0444f333ba1db93b055c0864bec48fff92d1f2a7fe51446a65645f746573744d6963726f555344ffd87a9f1a3b9aca00ffffd87a9fd8799fd87980d8799fd8799f581c8b4e5029a73fd4155dfdcb5013e28db2fafb3e1ab487275f4aa50903ffd8799fd8799fd8799f581ccce6bfa02342d29adce20d09d3824463bfb59b0753d7d1d8514b376cffffffffffd87a9fd8799fd87980d8799fd8799f581c8b4e5029a73fd4155dfdcb5013e28db2fafb3e1ab487275f4aa50903ffd8799fd8799fd8799f581ccce6bfa02342d29adce20d09d3824463bfb59b0753d7d1d8514b376cffffffffffffd8799f581c9772ff715b691c0444f333ba1db93b055c0864bec48fff92d1f2a7fe51446a65645f746573744d6963726f555344ffd87a9f1a3b9aca00ffd87980ffffff1b000001941f297c00d87980ffffffff1b000001941f297c00d87980ffffffff1b0000018cc251f400d87980ffff\"\n", "\n", "// example from here: https://cardanoscan.io/transaction/f3a397d2f58f2c30a8034235659c5688b0c5d308581dbd7ce4470049b4aebd66?tab=contracts\n", "let example_redeemer_cbor_hex = \"9fd8799fd8799fd8799fd87a80d8799fd8799f581c1fdc22c9b2339e644d229335129b35e65161839660636675b29aa5a8ffd8799fd8799fd8799f581c43b85595ee70ca74e98583872933bec6c67a99982ca2f25547a89b4dffffffffffd8799fd87a80d8799fd8799f581c1fdc22c9b2339e644d229335129b35e65161839660636675b29aa5a8ffd8799fd8799fd8799f581c43b85595ee70ca74e98583872933bec6c67a99982ca2f25547a89b4dffffffffffd8799f581c85556ab05acc925edff2af02ef819a8b4903bfb5d5e100a7c95ab9084d4d61726c6f77654c6973626f6eff01ffffff\"\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Decoding datums" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\n", " \"marlowe_params\": \"\",\n", " \"state\": {\n", " \"accounts\": [\n", " [\n", " [\n", " {\n", " \"address\": \"addr_test1qz95u5pf5ulag92alh94qylz3ke047e7r26gwf6lf2jsjq7vu6l6qg6z62ddecsdp8fcy3rrh76ekp6n6lgas52txakq3eft7r\"\n", " },\n", " {\n", " \"token_name\": \"\",\n", " \"currency_symbol\": \"\"\n", " }\n", " ],\n", " 2000000\n", " ]\n", " ],\n", " \"choices\": [],\n", " \"boundValues\": [],\n", " \"minTime\": 0\n", " },\n", " \"contract\": {\n", " \"when\": [\n", " {\n", " \"then\": {\n", " \"token\": {\n", " \"token_name\": \"Djed_testMicroUSD\",\n", " \"currency_symbol\": \"9772ff715b691c0444f333ba1db93b055c0864bec48fff92d1f2a7fe\"\n", " },\n", " \"to\": {\n", " \"party\": {\n", " \"address\": \"addr_test1qz95u5pf5ulag92alh94qylz3ke047e7r26gwf6lf2jsjq7vu6l6qg6z62ddecsdp8fcy3rrh76ekp6n6lgas52txakq3eft7r\"\n", " }\n", " },\n", " \"then\": {\n", " \"when\": [\n", " {\n", " \"then\": {\n", " \"token\": {\n", " \"token_name\": \"Djed_testMicroUSD\",\n", " \"currency_symbol\": \"9772ff715b691c0444f333ba1db93b055c0864bec48fff92d1f2a7fe\"\n", " },\n", " \"to\": {\n", " \"party\": {\n", " \"address\": \"addr_test1qz95u5pf5ulag92alh94qylz3ke047e7r26gwf6lf2jsjq7vu6l6qg6z62ddecsdp8fcy3rrh76ekp6n6lgas52txakq3eft7r\"\n", " }\n", " },\n", " \"then\": {\n", " \"when\": [\n", " {\n", " \"then\": {\n", " \"token\": {\n", " \"token_name\": \"Djed_testMicroUSD\",\n", " \"currency_symbol\": \"9772ff715b691c0444f333ba1db93b055c0864bec48fff92d1f2a7fe\"\n", " },\n", " \"to\": {\n", " \"party\": {\n", " \"address\": \"addr_test1qz95u5pf5ulag92alh94qylz3ke047e7r26gwf6lf2jsjq7vu6l6qg6z62ddecsdp8fcy3rrh76ekp6n6lgas52txakq3eft7r\"\n", " }\n", " },\n", " \"then\": \"close\",\n", " \"pay\": 1000000000,\n", " \"from_account\": {\n", " \"address\": \"addr_test1qz95u5pf5ulag92alh94qylz3ke047e7r26gwf6lf2jsjq7vu6l6qg6z62ddecsdp8fcy3rrh76ekp6n6lgas52txakq3eft7r\"\n", " }\n", " },\n", " \"case\": {\n", " \"party\": {\n", " \"address\": \"addr_test1qz95u5pf5ulag92alh94qylz3ke047e7r26gwf6lf2jsjq7vu6l6qg6z62ddecsdp8fcy3rrh76ekp6n6lgas52txakq3eft7r\"\n", " },\n", " \"of_token\": {\n", " \"token_name\": \"Djed_testMicroUSD\",\n", " \"currency_symbol\": \"9772ff715b691c0444f333ba1db93b055c0864bec48fff92d1f2a7fe\"\n", " },\n", " \"into_account\": {\n", " \"address\": \"addr_test1qz95u5pf5ulag92alh94qylz3ke047e7r26gwf6lf2jsjq7vu6l6qg6z62ddecsdp8fcy3rrh76ekp6n6lgas52txakq3eft7r\"\n", " },\n", " \"deposits\": 1000000000\n", " }\n", " }\n", " ],\n", " \"timeout_continuation\": \"close\",\n", " \"timeout\": 1735689600000\n", " },\n", " \"pay\": {\n", " \"divide\": {\n", " \"times\": 1000000000,\n", " \"multiply\": 100000\n", " },\n", " \"by\": 1000000\n", " },\n", " \"from_account\": {\n", " \"address\": \"addr_test1qz95u5pf5ulag92alh94qylz3ke047e7r26gwf6lf2jsjq7vu6l6qg6z62ddecsdp8fcy3rrh76ekp6n6lgas52txakq3eft7r\"\n", " }\n", " },\n", " \"case\": {\n", " \"party\": {\n", " \"address\": \"addr_test1qz95u5pf5ulag92alh94qylz3ke047e7r26gwf6lf2jsjq7vu6l6qg6z62ddecsdp8fcy3rrh76ekp6n6lgas52txakq3eft7r\"\n", " },\n", " \"of_token\": {\n", " \"token_name\": \"Djed_testMicroUSD\",\n", " \"currency_symbol\": \"9772ff715b691c0444f333ba1db93b055c0864bec48fff92d1f2a7fe\"\n", " },\n", " \"into_account\": {\n", " \"address\": \"addr_test1qz95u5pf5ulag92alh94qylz3ke047e7r26gwf6lf2jsjq7vu6l6qg6z62ddecsdp8fcy3rrh76ekp6n6lgas52txakq3eft7r\"\n", " },\n", " \"deposits\": {\n", " \"divide\": {\n", " \"times\": 1000000000,\n", " \"multiply\": 100000\n", " },\n", " \"by\": 1000000\n", " }\n", " }\n", " }\n", " ],\n", " \"timeout_continuation\": \"close\",\n", " \"timeout\": 1735689600000\n", " },\n", " \"pay\": 1000000000,\n", " \"from_account\": {\n", " \"address\": \"addr_test1qz95u5pf5ulag92alh94qylz3ke047e7r26gwf6lf2jsjq7vu6l6qg6z62ddecsdp8fcy3rrh76ekp6n6lgas52txakq3eft7r\"\n", " }\n", " },\n", " \"case\": {\n", " \"party\": {\n", " \"address\": \"addr_test1qz95u5pf5ulag92alh94qylz3ke047e7r26gwf6lf2jsjq7vu6l6qg6z62ddecsdp8fcy3rrh76ekp6n6lgas52txakq3eft7r\"\n", " },\n", " \"of_token\": {\n", " \"token_name\": \"Djed_testMicroUSD\",\n", " \"currency_symbol\": \"9772ff715b691c0444f333ba1db93b055c0864bec48fff92d1f2a7fe\"\n", " },\n", " \"into_account\": {\n", " \"address\": \"addr_test1qz95u5pf5ulag92alh94qylz3ke047e7r26gwf6lf2jsjq7vu6l6qg6z62ddecsdp8fcy3rrh76ekp6n6lgas52txakq3eft7r\"\n", " },\n", " \"deposits\": 1000000000\n", " }\n", " }\n", " ],\n", " \"timeout_continuation\": \"close\",\n", " \"timeout\": 1704067200000\n", " }\n", "}\n" ] } ], "source": [ "m.decode_cborhex_marlowe_plutus_datum(example_datum_cbor_hex)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Decoding redeemer/inputs" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\n", " \"Ok\": [\n", " {\n", " \"input_from_party\": {\n", " \"address\": \"addr1qy0acgkfkgeeuezdy2fn2y5mxhn9zcvrjesxxen4k2d2t2zrhp2etmnsef6wnpvrsu5n80kxceafnxpv5te923agndxshwgt4u\"\n", " },\n", " \"of_tokens\": {\n", " \"token_name\": \"MarloweLisbon\",\n", " \"currency_symbol\": \"85556ab05acc925edff2af02ef819a8b4903bfb5d5e100a7c95ab908\"\n", " },\n", " \"into_account\": {\n", " \"address\": \"addr1qy0acgkfkgeeuezdy2fn2y5mxhn9zcvrjesxxen4k2d2t2zrhp2etmnsef6wnpvrsu5n80kxceafnxpv5te923agndxshwgt4u\"\n", " },\n", " \"that_deposits\": 1\n", " }\n", " ]\n", "}\n" ] } ], "source": [ "\n", "m.decode_marlowe_input_cbor_hex(example_redeemer_cbor_hex)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Try-decode\n", "\n", "If you don't know if the cbor-hex is a valid redeemer or datum, you can use the \"decode_marlowe_data_or_redeemer\" method\n", "which will attempt to figure out the correct way to decode it" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Decoded redeemer from cbor hex:\n", "\n", " (Deposit (Address \"addr1qy0acgkfkgeeuezdy2fn2y5mxhn9zcvrjesxxen4k2d2t2zrhp2etmnsef6wnpvrsu5n80kxceafnxpv5te923agndxshwgt4u\") (Address \"addr1qy0acgkfkgeeuezdy2fn2y5mxhn9zcvrjesxxen4k2d2t2zrhp2etmnsef6wnpvrsu5n80kxceafnxpv5te923agndxshwgt4u\") (Token \"85556ab05acc925edff2af02ef819a8b4903bfb5d5e100a7c95ab908\" \"MarloweLisbon\") 1)\n" ] } ], "source": [ "\n", "m.decode_marlowe_data_or_redeemer(example_redeemer_cbor_hex)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Encoding contracts to cbor-hex\n", "\n", "Todo: This is currently not exposed in the WASM builds but only using the Rust crate.\n" ] } ], "metadata": { "kernelspec": { "display_name": "TypeScript", "language": "typescript", "name": "tslab" }, "language_info": { "codemirror_mode": { "mode": "typescript", "name": "javascript", "typescript": true }, "file_extension": ".ts", "mimetype": "text/typescript", "name": "typescript", "version": "3.7.2" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }