Marlowe resources and tools (playground, tutorials, documentation)

Also steps like the one given below, when we say transfer money from Lender to Lender what it means?
Does it means transferring money from lender wallet to contract to some intermediate Lender account?

Can’t we just say that Lender transfers money to contract wallet once and all subsequent transactions are happening from contract wallet. With this no need for having Lender or Borrower key in the contract.

marlowe-runtime-cli deposit
–contract “$CONTRACT_ID”
–from-party “$LENDER_ADDR”
–to-party “$LENDER_ADDR”
–lovelace “$PRINCIPAL”
–change-address “$LENDER_ADDR”
–manual-sign tx-2.unsigned
| jq -r ‘fromjson | .txId’
)

Could you please explain, I am little lost here or missing something fundamental. Basically, I want to avoid saving any wallet private key.

from lender wallet to contract to some intermediate Lender account

Exactly. Marlowe uses an account model within the contract. You can think of Marlowe as having internal accounts for the participants in the contract, in order to keep track of who owns which funds.

  • This is important because if a contract closes (via the Close block in Blockly) with funds left in the internal accounts, then the contract will pay each account holder their funds. (This means that it is impossible to write a Marlowe contract that loses funds forever because it forgets to pay them.) You can experiment with this in Playground by depositing to an account, but not explicitly paying out of that account; when Close is executed, the payment is made for that account even though there wasn’t a Pay block.
  • --from-party indicates that the funds are coming from the external wallet with $LENDER_ADDR. For security, the Marlowe deposit must be signed by the key for $LENDER_ADDR. (If role tokens were used, then the deposit would have to be authorized by the holder of the role token for this party.)
  • --to-party indicates that those funds are being stored in the internal account for $LENDER_ADDR within the Marlowe contract.

You can see how the internal accounts change in Marlowe Playground by clicking on the Current State tab when you simulate:

You can also use https://marlowescan.com/ to view the state in each Marlowe transaction that has occurred on any of the public Cardano networks:

Can’t we just say that Lender transfers money to contract wallet once and all subsequent transactions are happening from contract wallet.

Although on the blockchain the contract’s UTxO holds the funds, for the aforementioned security reasons Marlowe requires that they be tagged a belonging to one or more internal accounts.

With this no need for having Lender or Borrower key in the contract.

You certainly could design a contract that doesn’t hold funds in an account for the Lender or Borrower key. For example, the Escrow contract could deposit funds in an internal account called “Contract” (or “Funds” or whatever). The initial deposit would be --to-party Contract, and payments could be made from the “Contract” role. However, you might find that changing the Escrow contract in this way is a little tricky because you need to make sure that the logic is correct for either the Seller to be paid or the Buyer to be refunded (depending on scenario), regardless of situations where one of the parties fails to act (which causes a timeout).

Could you please explain, I am little lost here or missing something fundamental.

If you use roles in the contract (which means that role tokens are used for the authorizations instead of keys for addresses), then the contract never needs to refer to any addresses.

Basically, I want to avoid saving any wallet private key.

In the end, every transaction must be signed by some private key. The way to avoid ever storing or handling those signing keys yourself is to connect your contract to a CIP-30 wallet (typically a web browser extension). Then the wallet securely manages the user’s signing keys.

We don’t want user to provide the signing key for authorizing the transactions

Correct, most Dapps wouldn’t want to ever touch or possess a user’s signing keys. Instead the Dapp would connect to the user’s Cardano wallet, which then securely manages the key, prompts the user to sign transactions, etc.

once we add an address in contract he receives some notification for depositing the money.

This video about Marlowe Run gives a sense of the workflow, where different users each have their own browser that alerts them when it is time for them to act on a Marlowe contract and asks them to sign the transaction. Note that Marlowe Run has been retired, but the newer Marlowe Runtime supports web-based applications. Nevertheless, the hardest part of building a Cardano web application often is integrating it with one of the CIP-30 wallets because that involves setting up communication between your application (typically a tab in a web browser) and the third-party wallet (typically an extension in a web browser). Keep an eye out for new announcements of examples where Marlowe as part of a Dapp that has CIP-30 wallet integration.

Hello @bwbush ,

Thanks for all your support so far. I am making good progress but currently stuck as one strange problem.
I have created below contract (preprod network) with party called ContractW (as you suggested in above post for internal transaction). Contract is created and as first step it is expecting Role ContractW to deposit 1000 ADA to ContractW account. Already validated this in marlowe play ground.

Contract ID: fa7264876ba2c5873934dc2028edde9746fa7f7fb6ccffb85a2ba27807307038#1

But when I am trying to make deposit from ContractW to ContractW account using below command I am getting (ApplyInputsConstraintsBuildupFailed (MarloweComputeTransactionFailed “TEApplyNoMatchError”)) error.

I know you explained about it in your example that this will happen if there is mismatch with the contract expectation, But in this case everything seems fine.

marlowe-runtime-cli deposit --contract “fa7264876ba2c5873934dc2028edde9746fa7f7fb6ccffb85a2ba27807307038#1” --from-party “addr_test1vpkemtrztcll44n9nphdp5upg9wj2zf4edd9emer3st7lpcz9ru4d” --to-party “addr_test1vpkemtrztcll44n9nphdp5upg9wj2zf4edd9emer3st7lpcz9ru4d” --lovelace 1000000000 --change-address “addr_test1vpkemtrztcll44n9nphdp5upg9wj2zf4edd9emer3st7lpcz9ru4d” --manual-sign tx-2.unsigned

Note: I have provided all the actual addresses for you to check.

I already tried many things and seems to stuck here from 1 day, could you please help. Eagerly waiting for your response.

Thanks,
AS

For a contract that uses roles instead of addresses, like the one you created, you need to identify the party by the role name (not by the address where the role token happens to reside). Try the following:

marlowe-runtime-cli deposit \
  --contract "fa7264876ba2c5873934dc2028edde9746fa7f7fb6ccffb85a2ba27807307038#1" \
  --from-party ContractW \
  --to-party ContractW \
  --lovelace 1000000000 \
  --change-address "addr_test1vpkemtrztcll44n9nphdp5upg9wj2zf4edd9emer3st7lpcz9ru4d" \
  --manual-sign tx-2.unsigned

If the contract contains an Address block then you’ll need to use Cardano address in commands like marlowe-runtime-cli deposit, but if it contains a Role block then you’ll only need to use the name of the role.

BTW, roles give Marlowe contracts some extra flexibility compared to addresses because you can transfer the role tokens to another address or wallet, in which case that address/wallet becomes the participant in the contract. One can even sell role tokens (i.e., sell participation in the contract) or have one Marlowe (or Plutus) contract hold the role tokens for another Marlowe contract. On mainnet, one can even use Ada Handles as role tokens. There are a lot of interesting possibilities.

1 Like

Thanks @bwbush for clarifying this, it make sense.
But now I am getting this error:

ApplyFailed (ApplyInputsConstraintError (BalancingError “TxBodyScriptExecutionError [(ScriptWitnessIndexTxIn 1,ScriptErrorEvaluationFailed (CekError An error has occurred: User error:\nThe machine terminated part way through evaluation due to overspending the budget.\nThe budget when the machine terminated was:\n({ cpu: 5727517221\n| mem: -1600\n})\nNegative numbers indicate the overspent budget; note that this only indicatessthe budget that was needed for the next step, not to run the program to completion.) ["Data decoded successfully","Redeemer decoded successfully","Script context decoded successfully"])]”))

The machine terminated part way through evaluation due to overspending the budget.

This means that your contract is so large that it exceeds the blockchain’s protocol limit on Plutus execution costs. The protocol limit exists to protect the blockchain, so that the block-producing Cardano nodes have time to run all of the Plutus scripts (like Marlowe) for a block in a fraction of a second, leaving enough time for the blocks to propagate globally among all of the blockchain’s nodes before the next block is produced.

The design of Marlowe’s on-chain implementation contains a capability called “merkleization” for dealing with this limit. Merkleization lets one break up a contract into small pieces. (I’ve run contracts with a million Case statements, for instance, even though the contract is too large to fit in a single transaction.) The marlowe-runtime-cli tool will very soon support merkleizing contracts. I apologize that this capability isn’t available already in Marlowe Runtime, and will let you know when that capability is released. Thanks for your patience.

Meanwhile, it is possible to use the lower-level marlowe-cli tool to run large contracts like this. Take a look at cell In [20] of this contract for a raffle among 125 participants. In brief, one just adds the --merkleize flag to marlowe-cli run initialize when setting up the contract.

1 Like

P.S. Here are instructions on how to avoid protocol limits for Marlowe contracts.

P.S. Here is an example of a web application that uses Marlowe Runtime with a CIP-30 wallet and a video of the same.

@bwbush :Thanks for your quick reply however for now we decided to make smaller contract and create more later if needed.

Need your help again, post your help deposit is successful but now when I try to make a choice as shown below, again I get weird error.

Command: ~/build/marlowe-runtime-cli/bin/marlowe-runtime-cli choose --choice PNL --value 30 --contract “36dc1e2b3f9277398eaf5ee32a98c5e4ee8ad545d6e696e4745817aadee7180f#1” --party Oracle --change-address addr_test1vp0spz37rn7nxf3gvu3zy4ejmwmvq3jpea2v5k3j2n4zfwg8kyt39 --manual-sign pnl.json

Error: ApplyFailed (ApplyInputsConstraintError (BalancingError “TxBodyErrorMinUTxONotMet (TxOutInAnyEra BabbageEra (TxOut (AddressInEra (ShelleyAddressInEra ShelleyBasedEraBabbage) (ShelleyAddress Testnet (KeyHashObj (KeyHash "5f008a3e1cfd3326286722225732dbb6c04641cf54ca5a3254ea24b9")) StakeRefNull)) (TxOutValue MultiAssetInBabbageEra (valueFromList [(AdaAssetId,849153)])) TxOutDatumNone ReferenceScriptNone)) (Lovelace 857690)”))

These errors are very difficult to understand. :frowning:

Could you please help again.

Thanks,
AS

I’m not 100% sure without investigating in detail, but BalancingError and the fact that the change address only contains about 4 ada suggests that you need more funds at the change address. You might try sending some more test ada there and then retrying the transaction.

I’ve relayed your comment about the cryptic error messages to the Marlowe team. Thanks.

1 Like

Hello @bwbush,

I was able to run 3 months contract end to end using role token, however I see lot of transaction happening in contract which I do not understand.
Hence I looked into your example (01-runtime-cli.ipynb ZCB) wherein you are using address instead of role (Address) and I found that transactions in the example contract are quite simple and easy to understand. I believe complexity in my contract could be due to role tokens getting issued etc.

So I though lets use the address directly as you did, but in marlowe designer I cant find any control for address. It just have something called PublicKey which has no option to parametrize it.

I am still fine to hard code the PublicKey for now, But what I should put there. I tried putting my wallet public address (addr_test1vp0spz37rn7nxf3gvu3zy4ejmwmvq3jpea2v5k3j2n4zfwg8kyt39), but it does not understand that.

Could you please help how can I specify public address or if public key is the only option how can I get the public key for wallet.

Thanks,
AS

Hello @bwbush,

I am figured out that PKey is considered as Public key for Cardano Wallet. I created the contract on Marlowe playground and it worked as expected.

But now when I try to create the contract using marlowe-runtime-cli I get below error:
ContractFileDecodingError (AesonException “Error in $: key "assert" not found”)

But I am still able to create roles-based contract using same command, but its failing with Public key (pk_hash) based contract and in both contract logic is same.

Could you please advise, I am completely stuck here.

Thanks,
AS

The “Public Key” block in the Marlowe language was replaced with an “Address” block last August. Use this version of Playground to include a Bech32 address, for example addr_test1vp28qhdavped0rwr24ww8fmstr727a5ln7vrshlvq7cl3zgn0uaxs, in your contract.

@abhisheksingh2912, this version of Playground now includes the Address block (instead of PubKey): https://play.marlowe.iohk.io/.

Hello @bwbush ,

Hope you doing good, with all your help we are able to create test contract end to end in cardano test net.

Now before going live with mainnet i have few questions, I assume switching to main-net is like just removing the --testnet-magic and replacing it with main-net and update some env variables.

Or anything else is needed…?

Another thing is, whenever I use below command to get wallet balance:
cardano-cli query utxo --testnet-magic 1 --address addr_test1vqr9ww2lv9prrztmrp9e8xphcpkduruxqlxmdw8v4shtvacn0vdcl

I get this error:
MuxError MuxBearerClosed “<socket: 11> closed when reading data, waiting on next header True”

cardano-cli: MuxBearerClosed “<socket: 11> closed when reading data, waiting on next header True”

Though other CLI commands are working fine.

Waiting for your response.

Thanks,
AS

Hello @bwbush ,

I need you help urgently, we moved on to main net and trying to create real contract with real ADA.
Contract creating contract is having 30 ADA, and I am creating a contract of value 15 ADA with min-utxo of 2 ADA (tried 3 and % as well) but I keep getting below error:

CreateFailed (CreateConstraintError (CoinSelectionFailed “Insufficient lovelace available for coin selection: valueFromList [(AdaAssetId,10525534)] required, but valueFromList available.”))

Could you please advise, this is a hard blocker for us to move forward.

Appreciate your help here.

Thanks,
AS

I assume switching to main-net is like just removing the --testnet-magic and replacing it with main-net and update some env variables.

In addition to replacing --testnet-magic 1 with --mainnet, you’ll also need to connect to a mainnet node instead of a testnet node.

It sounds like the wallet might not have sufficient ada for the transaction. Have you tried cardano-cli query utxo --address to see how much value resides there?

Thanks @bwbush for your reply, really appreciate your help.

What do you mean when you say “you’ll also need to connect to a mainnet node instead of a testnet node.”

How can I validate or do this.?

My main net wallet have 30 ADA i am sure, what I suspect this is still going to Testnet as you pointed out.

Also cardano-cli query utxo --address never works for me, I always get below error:

MuxError MuxBearerClosed “<socket: 11> closed when reading data, waiting on next header True”

cardano-cli: MuxBearerClosed “<socket: 11> closed when reading data, waiting on next header True”

Waiting for your reply.

Thanks,
AS