Utiliser Marlowe depuis la ligne de commande ghci

Ce tutoriel vous montre comment utiliser Marlowe à partir de Haskell, et en particulier comment exercer un contrat en utilisant la sémantique donnée antérieurement.

 

Marlowe en Haskell

Ce tutoriel fonctionne avec la version 3.0 de Marlowe qui se trouve dans la branche master du dépôt:

 

Traverser les contrats

Comme nous l'avons vu précédemment, la sémantique d'une transaction unique est définie par la fonction

où les types sont définis comme ça :

et States sont définis comme suit, avec une fonction d'aide pour définir un état initialement vide:

Nous pouvons utiliser les services de ghci pour parcourir un contrat une transaction à la fois, et, ici, nous le ferons avec le contrat d'entiercement intégré contenu dans `EscrowSimmpleV2.hs <https://github.com/input-output-hk/marlowe/blob/master/semantics-3.0/src/Language/Marlowe/Examples/EscrowSimpleV2.hs>`_.

Pour aller à un seul pas a la fois, vous pouvez travailler dans ghci comme ceci, en utilisant la possibilité de faire des liens locaux:

Prelude> :set -XOverloadedStrings

Prelude> :l Language/Marlowe/Examples/EscrowSimpleV2.hs

 ...

*Lang...V2> let (TransactionOutput txWarn1 txPay1 state1 con1) = computeTransaction (TransactionInput (0, 0) [IDeposit "alice" "alice" ada 450]) (emptyState 0) contract

En faisant cela, nous avons mis en correspondance la sortie d'une application de computeTransaction, qui prend trois entrées : la deuxième est un état initial (au slot numéro 0) et la troisième est le contrat d'entiercement initial. La première est un TransactionInput qui contient un SlotInterval – ici SlotInterval 0 0 – et un dépôt de 450 Lovelace de "alice" sur son compte "alice" , plus précisément IDeposit "alice" "alice" ada 450.

 

Note

Si vous voulez essayer ceci par vous-même dans ghci, vous pouvez copier et coller les exemples de code dans le document original (voir le lien en bas de page) : ils sont dans des fenêtres à défilement horizontal.

 

La sortie est appariée avec TransactionOutput txWarn1 txPay1 state1 con1 afin que nous puissions examiner les différents composants séparément:

*Lang...V2> txWarn1

[]

*Lang...V2> txPay1

[]

*Lang...V2> state1

State {accounts = fromList [("alice", ada), 450)], choices = fromList [], boundValues = fromList [], minSlot = 0}

*Lang...V2> con1

When [Case (Choice (ChoiceId "choice" "alice") [Bound 0 1])

 ...

Cela montre que la transaction ne génère aucun avertissement ou paiement, mais met à jour l'état pour montrer le solde du compte "alice", et met à jour le contrat, prêt à recevoir un choix d'Alice ou de Bob.

Dans l'état suivant, le contrat est en attente d'entrée, et si Alice et Bob sont d'accord pour effectuer un paiement à Bob en choisissant 0, alors un paiement à Bob est généré. Ceci est vérifié par cette interaction dans GHCI:

*Lang...V2> let (TransactionOutput txWarn2 txPay2 state2 con2) = computeTransaction (TransactionInput (SlotInterval 0 0) [IChoice (ChoiceId "choice" "alice") 0, IChoice (ChoiceId "choice" "bob") 0]) state1 con1

*Lang...V2> txPay2

[Payment "bob" ada 450]

*Lang...V2> con2

Close

*Lang...V2> state2

State {accounts = fromList [], choices = fromList [(ChoiceId "choice" "alice",0),(ChoiceId "choice" "bob",0)], boundValues = fromList [], minSlot = 0}

Une autre façon de procéder est d'ajouter ces définitions à un fichier de travail, par ex. Build.hs, où ces définitions seront conservées. En effet, il serait très judicieux d'inclure certaines des définitions utilisées ci-dessus dans un tel fichier.

 

Routes alternatives à travers le contrat

Les liaisons locales sont perdues chaque fois qu'une commande :load ou :l  est exécutée, ce qui nous permet de réutiliser certaines commandes antérieures. Une exécution alternative du contrat est donnée par

  • Première étape : Alice dépose de l'argent comme dans l'exemple précédent.
  • Deuxième étape : Alice et Bob choisissent des options différentes. Cela peut être fait comme suit:

*Lang...V2> let (TransactionOutput txWarn2 txPay2 state2 con2) = computeTransaction (TransactionInput (SlotInterval 0 0) [IChoice (ChoiceId "choice" "alice") 0, IChoice (ChoiceId "choice" "bob") 1]) state1 con1

*Lang...V2> con2

When [Case (Choice (ChoiceId "choice" "carol") [Bound 1 1]) Close, Case (Choice (ChoiceId "choice" "carol") [Bound 0 0]) (Pay "alice" (Party "bob") ada (Constant 450) Close)] 100 Close

*Lang...V2> state2

State {accounts = fromList [("alice", ada), 450)], choices = fromList [(ChoiceId "choice" "alice",0),(ChoiceId "choice" "bob",1)], boundValues = fromList [] , minSlot = 0}

Cela montre que nous sommes maintenant dans un contrat où le choix appartient à Carol, et qu'il y a toujours les 450 Lovelace dans le compte "alice" .

  • Troisième étape : Carole fait un choix. Si elle choisit 0, le paiement à Bob est effectué. Si elle choisit 1, Alice est remboursée. Faisons cela maintenant:

*Lang...V2> let (TransactionOutput txWarn3 txPay3 state3 con3) = computeTransaction  (TransactionInput (SlotInterval 0 0) [IChoice (ChoiceId "choice" "carol") 1]) state2 con2

*Lang...V2> txPay3

[Payment "alice" ada 450]

*Lang...V2> con3

Close

*Lang...V2> state3

State {accounts = fromList [], choices = fromList [(ChoiceId "choice" "alice",0), (ChoiceId "choice" "bob",1),(ChoiceId "choice" "carol",1)], boundValues = fromList [], minSlot = 0}

Donc maintenant le contrat est prêt à Close, et donc de rembourser l'argent restant, mais il est clair, d'après state3 qu'il n'y a pas de comptes contenant des soldes non nuls, donc le contrat est terminé.

Pourquoi le pas à pas est-il utile ? C'est l'équivalent du débogage, et nous sommes en mesure de voir l'état interne du contrat à chaque étape, la suite du contrat, c'est-à-dire ce qui reste à exécuter, et les actions produites à chaque étape.

 

Exercice

Explorez d'autres façons d'aborder le contrat - Que se passe-t-il si Bob et Alice choisissent de rembourser l'argent à Alice ? - Que se passe-t-il si Bob et Alice sont en désaccord, mais que Carol se range du côté de Bob ?

© Copyright 2020, IOHK Revision 1b7b1fc1.

 

Vous trouverez une copie officielle de ce document ici :

https://alpha.marlowe.iohkdev.io/doc/marlowe/tutorials/using-marlowe.html

https://docs.cardano.org/projects/plutus/en/latest/marlowe/tutorials/using-marlowe.html

 

Plus de traductions de Cardano à: Cardano For The World