Guía del lenguaje Marlowe

Marlowe está diseñado para crear los componentes básicos de los contratos financieros: pagos a los participantes y depósitos de éstos, elecciones de los participantes e información del mundo real.

Marlowe es un lenguaje pequeño, con un puñado de construcciones diferentes que, para cada contrato, describen un comportamiento que implica un conjunto fijo y finito de roles. Cuando se ejecuta un contrato, los roles que implica son cumplidos por los participantes, que son identidades en la blockchain. Cada rol está representado por un token en la cadena y los roles pueden ser transferidos durante la ejecución del contrato, lo que significa que esencialmente pueden ser intercambiados.

Los contratos pueden construirse juntando un pequeño número de estas construcciones que, en combinación, pueden utilizarse para describir y modelar muchos tipos diferentes de contratos financieros. Algunos ejemplos incluyen un contrato que en ejecución puede hacer un pago a un rol o a una clave pública, un contrato que puede esperar una acción de uno de los roles, como un depósito de moneda, o una elección de un conjunto de opciones. Consulte el ejemplo de Contrato de Custodia que aparece a continuación.

Fundamentalmente, un contrato no puede esperar indefinidamente una acción: si no se ha iniciado ninguna acción en un tiempo determinado (el tiempo de espera), entonces el contrato continuará con un comportamiento alternativo, por ejemplo, tomar una acción correctiva como el reembolso de los fondos del contrato.

Los contratos de Marlowe pueden bifurcarse en función de las alternativas y tienen una duración limitada, al final de la cual se devuelve el dinero restante a los participantes. Esta característica significa que el dinero no puede quedar bloqueado para siempre en un contrato. Dependiendo del estado actual de un contrato, éste puede elegir entre dos alternativas de acción futura, que son a su vez contratos. Cuando ya no se requieran más acciones, el contrato se cerrará, y se devolverá el dinero restante en el contrato.

Uso de los Types de Haskell

Los Types de Haskell se utilizan para representar los distintos componentes del contrato, incluyendo cuentas, valores, observaciones y acciones. Estos elementos de Marlowe se utilizan para suministrar información externa y entradas a un contrato en ejecución para controlar su evolución.

En el modelado de las partes básicas de Marlowe se utiliza una combinación de Haskell data types son utilizados, que definen nuevos types, y type sinónimos que dan un nuevo nombre a un type existente.

Además de escribir contratos en la versión textual de Marlowe, también puedes utilizar uno de los siguientes medios de programación visual:

  1. Usando Blockly
  2. Usando JavaScript
  3. Usando Haskell

 

¿Cómo es un contrato Marlowe?

Un contrato se construye en Marlowe combinando un pequeño número de bloques de construcción para describir muchos tipos diferentes de contratos financieros, como realizar un pago, hacer una observación, esperar hasta que se cumpla una determinada condición, etc. A continuación, el contrato se ejecuta en una blockchain, como Cardano, e interactúa con el mundo exterior.

El propio Marlowe está integrado en Haskell y se modela como una colección de types de datos algebraicos en Haskell, con contratos definidos por el type Contract:

data Contract = Close

              | Pay Party Payee Token Value Contract

              | If Observation Contract Contract

              | When [Case] Timeout Contract

              | Let ValueId Value Contract

              | Assert Observation Contract

Marlowe dispone de seis métodos de construcción de contratos. Cinco de estos métodos – PayLetIfWhen, y Assert – construyen un contrato complejo a partir de contratos más simples, y el quinto método, Close, es un contrato simple. En cada paso de la ejecución, además de devolver un nuevo estado y un contrato de continuación, es posible que también se generen efectos -pagos- y avisos.

Pay

Un contrato de pago Pay a p t v cont hará un pago de valor v de token t desde la cuenta a al beneficiario p, que será uno de los participantes del contrato u otra cuenta del mismo. Se generarán avisos si el valor v no es positivo, o si no hay suficiente en la cuenta para realizar el pago en su totalidad (aunque haya saldos positivos de otros tokens en la cuenta). En este último caso, se realiza un pago parcial (de todo el dinero disponible). El contrato de continuación es el que se da en el contrato: cont.

Close

El contrato Close proporciona el cierre (o la rescisión) del contrato. La única acción que realiza es proporcionar reembolsos a los propietarios de las cuentas que contienen un saldo positivo. Esto se realiza una cuenta por paso, pero todas las cuentas serán reembolsadas en una sola transacción.

Antes de pasar a otras formas de contrato, es necesario describir los valuesobservations, y actions:

  • Values - incluyen cantidades que cambian con el tiempo, como "el intervalo actual de slots", "el saldo actual de alguna ficha en una cuenta", y cualquier elección que ya se haya realizado (valores volátiles). Los valores también pueden combinarse utilizando la suma, la resta y la negación, y pueden ser condicionales a una observación.
  • Observations - son valores booleanos derivados de la comparación de valores, y pueden combinarse utilizando los operadores booleanos estándar. También es posible observar si se ha realizado alguna elección (para una determinada elección identificada). Las observaciones tendrán un valor en cada paso de la ejecución.
  • Actions - ocurren en determinados momentos de la ejecución, por ejemplo:
    • depositar dinero
    • elegir entre varias alternativas, incluyendo un valor oracular
    • notificar al contrato que una observación se ha hecho realidad
  • Oracles - se están desarrollando para Cardano blockchain, y estarán disponibles para su uso dentro de Marlowe en Cardano. Hasta entonces hemos introducido un prototipo de oráculo, que se implementa en el Marlowe Playground. Modelamos los oráculos como elecciones que son realizadas por un participante con un rol específico de Oráculo, "kraken".

If

El condicional If obs cont1 cont2 continuará como cont1 or cont2, en función del valor booleano de la observación obs cuando se ejecuta esta construcción.

When

Este es el constructor más complejo para los contratos, con la forma When cases timeout cont. Se trata de un contrato que se activa en función de las acciones, que pueden o no ocurrir en un slot determinado: lo que ocurre cuando se producen varias acciones se describe en los casos del contrato.

En el contrato When cases timeout cont, la lista cases contiene una colección de casos. Cada caso tiene la forma Case ac co donde ac es una acción y co una continuación (otro contrato). Cuando una acción particular, por ejemplo, ac, ocurre, el estado se actualiza en consecuencia y el contrato continuará como la continuación correspondiente co.

Para asegurarse de que el contrato progresa eventualmente, el contrato When cases timeout cont continuará como cont una vez que el timeout, un número de slot, se ha alcanzado.

Let

Un contrato let Let id val cont permite registrar un valor, en un momento determinado, y darle un nombre mediante un identificador. En este caso, la expresión val es evaluada y almacenada con el nombre id. El contrato continúa entonces como cont.

Además de permitirnos utilizar abreviaturas, este mecanismo también nos permite capturar y guardar valores volátiles que puedan estar cambiando con el tiempo, por ejemplo, el precio actual del petróleo, o el número de slot actual, en un momento determinado de la ejecución del contrato, para utilizarlo posteriormente en la ejecución del mismo.

Assert

El contrato assert Assert obs cont no tiene ningún efecto sobre el estado del contrato, continúa inmediatamente como cont, pero emite un aviso cuando la Observación obs es falsa. Se puede utilizar para asegurar que una propiedad se mantiene en cualquier punto del contrato, ya que el análisis estático fallará si alguna ejecución hace que un assert sea falso.

Ejemplo de Contrato de Fideicomiso

Supongamos que alice quiere comprar un gato de bob, pero ninguno de ellos confía en el otro. Afortunadamente, tienen una amiga común carol en quien ambos confían para que sea neutral (pero no lo suficiente como para darle el dinero y actuar como intermediaria). Por lo tanto, acuerdan el siguiente contrato, escrito con un sencillo pseudocódigo funcional. Este tipo de contrato es un ejemplo sencillo de fideicomiso (escrow):

 When aliceChoice

      (When bobChoice

            (If (aliceChosen 'ValueEQ' bobChosen)

                agreement

                arbitrate))

El contrato se describe utilizando los constructores de un tipo de datos Haskell. El constructor When más externo tiene dos argumentos: el primero es una observación y el segundo es otro contrato. El significado que se pretende dar a esto es que cuando la acción ocurre, el segundo contrato se activa.

El segundo contrato es a su vez otro When – pidiendo una decisión de bob - pero dentro de eso, hay una opción: Si alice y bob se ponen de acuerdo sobre lo que hay que hacer, se hace; si no, se le pide a carol que arbitre y tome una decisión.

En general, When ofrece una lista de casos, cada uno con una acción y un contrato correspondiente que se desencadena cuando esa acción ocurre. De este modo, podemos permitir la opción de que Bob haga la primera elección, en lugar de alice, así:

 When [ Case aliceChoice

              (When [ Case bobChoice

                          (If (aliceChosen 'ValueEQ' bobChosen)

                             agreement

                             arbitrate) ],

               

        Case bobChoice

              (When [ Case aliceChoice

                           (If (aliceChosen 'ValueEQ' bobChosen)

                              agreement

                              arbitrate) ],

       ]

En este contrato, tanto Alice como Bob pueden hacer la primera elección; entonces el otro hace una elección. Si están de acuerdo, se hace; si no, Carol arbitra.

Fideicomiso en Marlowe

Los contratos de Marlowe incorporan construcciones adicionales para asegurar que progresan correctamente. Cada vez que vemos un  When, tenemos que proporcionar dos cosas adicionales: 

  • un timeout después del cual el contrato avanzará, y
  • el contrato continuation con el que progresa

 

Utilizando Timeouts

Timeouts se utilizan cuando la condición del When nunca se hace realidad. Así que los valores de tiempo de espera y de continuación se añaden a cada When que occurre en el contrato:

 When [ Case aliceChoice

              (When [ Case bobChoice

                          (If (aliceChosen 'ValueEQ' bobChosen)

                             agreement

                             arbitrate) ],

                    60              -- ADDED

                    arbitrate       -- ADDED

        ]

        40          -- ADDED

        Close       -- ADDED

El  When  más externo pide que Alice haga la primera elección: si Alice no ha hecho una elección antes del slot 40, el contrato se cierra y se devuelven todos los fondos del contrato.

Cuentas de Marlowe y uso de Tokens

Una Cuenta Marlowe contiene importes de múltiples monedas y/o tokens fungibles y no fungibles. Una cantidad concreta está indexada por un Token, que es un par de CurrencySymbol y TokenName. Puedes pensar en un Account como un Map Token Integer, donde: data Token = Token CurrencySymbol TokenName

El token ada de Cardano se representa como Token adaSymbol adaToken, sin embargo, puedes crear tus propias monedas y tokens.

 

Encuentra una copia oficial de este documento aquí:

https://docs.cardano.org/en/latest/marlowe/marlowe-lang-guide.html

 

© Copyright 2020, IOHK Revision d7c21086.

 

Más traducciones de Cardano en: http://CardanoForTheWorld.com