Marlowe/Blockly: Algorithms for SmartContracts

Hello,
I am trying to train myself in the design of SMARTCONTRACTS. I tested example # 1 (Escrow contract) which is offered in the Playground. It seems to me that I detected an anomaly. Regarding the intervention of the arbiter (Dismiss claim), we can only answer with 0 (impossible to enter 1: “choice must be between 0 and 0”) at the time of the simulation. As a result, the arbiter never accepts the buyer’s claim and the seller is invariably paid!
I propose this modification of the source code under Blockly with the following meaning:
0 → The arbiter does not recognize the merits of the protest. The seller is paid normally.
1 → The arbiter recognizes this well founded. The buyer is reimbursed.
Escrow contrat modified - Dissmiss claim

1 Like

To go further with the example of Escrow smartcontract and to help beginners, I propose a new version of this contract below:
Preliminary observations
This smartcontract is a simple mail order sale contract for any item between two parties who do not know each other and therefore do not trust each other. The fact that the transaction takes place in a decentralized environment (blockchain), without recourse in the event of a possible conflict, makes the security of the contract very uncertain. At the slightest disagreement, delay or incident, the transaction risks failing: a party, or even both, could be irreversibly harmed by the script of the contract.
Aware of the problem, the drafters of the contract below have therefore provided for two provisions:

  1. An escrow (prior monetary deposit), corresponding to the fixed price, made by the buyer. This deposit marks the buyer’s legal commitment to the transaction. Unfortunately, it does not ensure the proper performance of the contract: shipping, delivery, conformity of the item with the description provided by the seller to the buyer, possible return of the item, reimbursement of the buyer, etc.
  2. Any arbitration in the event of a conflict, entrusted to a trusted third party. Note that this arbitrator should normally be chosen by mutual agreement of the parties. This assumes that each party has the same list of arbitrators at the time of conclusion. The modalities of this choice are not provided here, for the sake of simplification.
    Flowchart
    Algo_escrow
    Blockly code
    image
1 Like

That’s a great suggestion. We’ve discussed that before, but very good to hear it coming from someone outside the team.

1 Like

Thanks for your answer. I was thinking about the second proposed contract: Escrow with collateral. Here is my analysis:

The main idea of ​​this sales contract is to dissuade the parties from engaging in a conflict. As in the previous contract, the buyer recorded the fixed price. But each party (the seller and the buyer) has also consigned a certain amount of money (collateral) of the same amount (eg 50 adas).
1) If the buyer is satisfied with the delivery, the contract is executed normally: the seller is paid and the collateral is returned
2) In the event that the buyer raises a problem and the seller recognizes the merits of this claim, the contract provides for the reimbursement of the buyer and the restitution of collateral.
3) If the seller rejects the buyer’s claim then:
a) The price is returned to the buyer
b) But the collateral is not returned to the parties. They are paid into escrow accounts provided for by the smartcontract. It is therefore a kind of penalty imposed on the parties in disagreement.
Thus, the contract is put on stand-by for a solution. The execution of the contract is suspended from the resolution of the conflict. This resolution is not provided for by the contract itself. The solution will come from outside within a timeframe that no one knows. The contract is therefore found in a random state. Note that the solution may never intervene and therefore never allow the contract to be closed. Which is contrary to the blockchain protocol.
In addition, the retention of collateral may appear unfair to the party suffering the damage. Suppose a seller is dishonest and in bad faith: the buyer suffers a kind of “double penalty”. He is certainly reimbursed for the price paid, but his collateral is retained in the escrow account … If his good faith is subsequently recognized, the sum will be returned to him, but in the meantime, he may consider himself unfairly treated.
The presented solution adopted by this second contract seems less efficient than that of resorting to arbitration, even if the deposit of collateral is easier to implement than arbitration. Indeed, the constitution of a collateral is internal to the smartcontract, whereas an arbitration procedure necessarily external.

In my conclusion, if this type of sales contract is to be developed on the Cardano blockchain, it would seem necessary to provide an arbitration service, in order to avoid delays and recurring uncertainties in their progress.

Hello Alain,

I think the solution you propose for the simple “Escrow” contract is equivalent to the one in the examples of the Marlowe Playground. The idea with the example in the Marlowe Playground is that if the Arbiter agrees with the Buyer then Arbiter would use the choice “Confirm problem” instead:
screenshot

The advantage of the approach in the examples of the Marlowe Playground is that the name of the choice gives the user a hint of what the option means without having to look at the contract.

Am I missing anything?

Hello Pablo,
You are right. I’m confused. The ESCROW example is indeed error free.
What misled me is the use of the CHOICE block with only one option (bounds 1 to 1), inusual for me. But this writing is more economical and I will adopt it.
Sorry again …

Escrow with collateral and arbitration
The main idea of ​​this sales contract is, in case of difficulty, to encourage the parties to seek an agreement before entering into a conflict. As in the previous contract (simple Escrow), the buyer has deposited the fixed price. The seller and the buyer have also deposited a certain sum of money (collateral). In the following example, the collateral amounts to 10% of the fixed price.
As the constitution of collateral represents an additional cost for the parties, it would be wise to present this expense as an assurance of the successful completion of the contract (performance bond), consisting of possible recourse to arbitration in the event of difficulty. This expense should, in my opinion, be optional and advisable when the monetary stake is important. Rather, this option would be left to the buyer’s initiative.

Issue

  • If the buyer is satisfied with the delivery of the product or service, the contract is executed normally: the seller is paid and the collateral is returned to the seller and the buyer respectively. The contract is closed.
  • In the event that the buyer raises a problem, he formulates a claim with the seller.
    • If the seller recognizes the merits of this claim, the contract provides for the refund of the buyer and the restitution of collateral. The item is returned to the seller. The transaction fails and the contract is closed.
    • If the seller rejects the buyer’s claim, the dispute is submitted to an arbiter who was chosen by mutual agreement at the time of the conclusion of the contract.
    • If the arbiter recognizes the merits of the buyer’s claim, the deposited price and the collateral are returned to the buyer. The transaction fails. Responsibility for the problem lies with the seller. Also, the latter’s collateral remains consigned in the blockchain and is not returned to him. The contract is closed.
    • If the arbiter rejects the buyer’s claim, the transaction fails too. The buyer’s responsibility is engaged. The price deposited is returned to him. On the other hand, his collateral remains consigned in the blockchain and is not returned to him. The seller’s collateral is returned and the contract is closed.
    2 notes:
  • It could be envisaged that the collateral not returned is attributed to the non-at-fault party as compensation. This possibility is not shown in the example below.
  • When the buyer is at fault, it would have been legally possible to force him to accept the transaction and to enforce the contract, since having chosen the arbiter, he is subject to his decision. This is not the solution that has been adopted here.

Algo

**Marlowe Code**
When
    [Case
        (Deposit
            (Role "Seller")
            (Role "Buyer")
            (Token "" "")
            (ConstantParam "Price")
        )
        (When
            [Case
                (Deposit
                    (PK "000000000000000000000000000000000000000000000000000000000000000000000…")
                    (Role "Buyer")
                    (Token "" "")
                    (Scale
                        (1%10)
                        (ConstantParam "Price")
                    )
                )
                (When
                    [Case
                        (Deposit
                          (PK “000000000000000000000000000000000000000000000000000000000000000000000…”) 
                            (Role "Seller")
                            (Token "" "")
                            (Scale
                                (1%10)
                                (ConstantParam "Price")
                            )
                        )
                        (When
                            [Case
                                (Choice
                                    (ChoiceId
                                        "Everything is alright"
                                        (Role "Buyer")
                                    )
                                    [Bound 0 0]
                                )
                                (Pay
                                    (PK “000000000000000000000000000000000000000000000000000000000000000000000…”)
                                    (Account (Role "Seller"))
                                    (Token "" "")
                                    (Scale
                                        (1%10)
                                        (ConstantParam "Price")
                                    )
                                    (Pay
                                        (PK “000000000000000000000000000000000000000000000000000000000000000000000…”)
                                        (Account (Role "Buyer"))
                                        (Token "" "")
                                        (Scale
                                            (1%10)
                                            (ConstantParam "Price")
                                        )
                                        Close 
                                    )
                                ), Case
                                (Choice
                                    (ChoiceId
                                        "Report problem"
                                        (Role "Buyer")
                                    )
                                    [Bound 0 0]
                                )
                                (When
                                    [Case
                                        (Choice
                                            (ChoiceId
                                                "Confirm problem"
                                                (Role "Seller")
                                            )
                                            [Bound 0 0]
                                        )
                                        (Pay
                                            (Role "Seller")
                                            (Account (Role "Buyer"))
                                            (Token "" "")
                                            (ConstantParam "Price")
                                            (Pay
                                                (PK “000000000000000000000000000000000000000000000000000000000000000000000…”)
                                                (Account (Role "Buyer"))
                                                (Token "" "")
                                                (Scale
                                                    (1%10)
                                                    (ConstantParam "Price")
                                                )
                                                (Pay
                                                    (PK “000000000000000000000000000000000000000000000000000000000000000000000…”)
                                                    (Account (Role "Seller"))
                                                    (Token "" "")
                                                    (Scale
                                                        (1%10)
                                                        (ConstantParam "Price")
                                                    )
                                                    Close 
                                                )
                                            )
                                        ), Case
                                        (Choice
                                            (ChoiceId
                                                "Dispute problem"
                                                (Role "Seller")
                                            )
                                            [Bound 0 0]
                                        )
                                        (When
                                            [Case
                                                (Choice
                                                    (ChoiceId
                                                        "Dismiss claim"
                                                        (Role "Arbiter")
                                                    )
                                                    [Bound 0 0]
                                                )
                                                (Pay
                                                    (PK “000000000000000000000000000000000000000000000000000000000000000000000…”)
                                                    (Account (Role "Seller"))
                                                    (Token "" "")
                                                    (Scale
                                                        (1%10)
                                                        (ConstantParam "Price")
                                                    )
                                                    (Pay
                                                        (Role "Seller")
                                                        (Account (Role "Buyer"))
                                                        (Token "" "")
                                                        (ConstantParam "Price")
                                                        Close 
                                                    )
                                                ), Case
                                                (Choice
                                                    (ChoiceId
                                                        "Confirm problem"
                                                        (Role "Arbiter")
                                                    )
                                                    [Bound 0 0]
                                                )
                                                (Pay
                                                    (PK “000000000000000000000000000000000000000000000000000000000000000000000…”)
                                                    (Account (Role "Buyer"))
                                                    (Token "" "")
                                                    (Scale
                                                        (1%10)
                                                        (ConstantParam "Price")
                                                    )
                                                    (Pay
                                                        (Role "Seller")
                                                        (Account (Role "Buyer"))
                                                        (Token "" "")
                                                        (ConstantParam "Price")
                                                        Close 
                                                    )
                                                )]
                                            (SlotParam "Arbiter's response timeout")
                                            Close 
                                        )]
                                    (SlotParam "Seller's response timeout")
                                    Close 
                                )]
                            (SlotParam "Dispute by buyer timeout")
                            Close 
                        )]
                    (SlotParam "Collateral deposit by seller timeout")
                    Close 
                )]
            (SlotParam "Collateral deposit by buyer timeout")
            Close 
        )]
    (SlotParam "Deposit of price by buyer timeout")
    Close

Hello,
I would like to modify the example given of the “zero coupon bond” contract. I would like the contract to be able to calculate the “discounted price” (actual value) from the following 3 parameters: notional price (future value), rate of return, time to maturity (in years).
I started modifying the contract this way:
ZCB2

The formula to apply is normally:
ZBC3
I can’t do it. Can anyone help me? Thank you in advance…

Hi Alain.

You can do this by authoring the contract in Haskell or JavaScript: you can do the calculations in the programming language and generate (“compile”) the final contract from this.

One proviso: you can do this so long as the calculations are static, and can be done in advance of the contract running.

Hope this helps,

Simon