Implementa un contrato programable

Universal Ledger admite contratos programables que se pueden implementar en una red para automatizar y aplicar acuerdos entre los participantes interesados.

En este instructivo, se muestran los pasos necesarios para que los desarrolladores desarrollen, implementen y interactúen con un contrato programable en una red de Universal Ledger.

Antes de comenzar

Para completar este instructivo, necesitarás lo siguiente:

  • En la consola de Google Cloud , activa Cloud Shell.

    Activa Cloud Shell

  • Una cuenta de usuario de Universal Ledger con el rol ROLE_CONTRACT_CREATOR. Esta cuenta se convertirá en el propietario del contrato.

  • Una o más cuentas de usuario de Universal Ledger con el rol ROLE_CONTRACT_PARTICIPANT. Puede ser la misma cuenta que la del propietario del contrato.

  • De manera opcional, configura la CLI de Universal Ledger para poder firmar y enviar transacciones en nombre de estas cuentas de usuario.

Los roles de Universal Ledger se pueden asignar a una cuenta de usuario cuando su administrador de cuentas la crea, en el momento en que se envía su transacción CreateAccount, o se pueden modificar más adelante a través de una transacción AddRoles si la cuenta ya existe. Para experimentar, también puedes usar la CLI de Universal Ledger para administrar cuentas.

Configura tu entorno

Para simplificar la configuración, este instructivo se escribió para el entorno predeterminado que se proporciona en una sesión de Cloud Shell. Es posible que debas modificar estos comandos si usas un entorno diferente.

El compilador gculpyc toma el código fuente escrito en el lenguaje GCULpy y produce código de bytes para Universal Ledger.

Ejecuta cada uno de los siguientes comandos para extraer la imagen de Docker de gculpyc, definir un alias para ejecutar el objeto binario y confirmar que este funcione.

docker pull us-docker.pkg.dev/gcul-artifacts/images/client/gculpyc:stable
alias gculpyc="docker run --rm -i --user $(id -u):$(id -g) \
    --volume .:/workspace --workdir /workspace \
    us-docker.pkg.dev/gcul-artifacts/images/client/gculpyc:stable"
gculpyc --help

Escribe tu contrato

GCULpy es el lenguaje que se usa para escribir contratos para el Universal Ledger. Es un subconjunto de Python con tipado estático, optimizado para una lógica de contrato clara, auditable y comprensible. Este diseño prioriza la escritura de código seguro y restringe los comportamientos inesperados o no seguros. Para obtener más detalles, consulta la referencia de El lenguaje GCULpy.

Debido a que GCULpy es un subconjunto estricto de Python, puedes seguir usando tus entornos de desarrollo integrados (IDE) preferidos junto con tus flujos de trabajo y prácticas de desarrollo existentes.

Por ejemplo, tu código podría verse de la siguiente manera:

import gcul

class Counter(gcul.Contract):
    """Example contract implementing a counter."""

    value: int

    def increment(self) -> None:
        """Increments the counter value by 1."""
        self.value += 1

Copia este código de muestra y guárdalo en un archivo llamado counter.py.

Realiza pruebas locales

En un futuro cercano, los desarrolladores tendrán acceso a un entorno de simulación local. Se proporciona como parte del módulo de Python gcul y está diseñado para proporcionar las funcionalidades necesarias para simular de forma nativa una red de Universal Ledger dentro de un entorno de Python. Por lo tanto, podrás ejecutar contratos de forma local y escribir pruebas de unidades con tus frameworks de pruebas preferidos, lo que garantizará la confiabilidad y la exactitud de tus contratos antes de la implementación.

Compila el contrato

Compila el código fuente del contrato anterior en código de bytes con el siguiente comando de gculpyc:

gculpyc --source_file counter.py --output_file counter.bin

Implementa el contrato

Implementa el contrato en una red de Universal Ledger enviando una transacción CreateContract firmada por una cuenta de usuario que tenga el ROLE_CONTRACT_CREATOR.

Si usas la CLI de Universal Ledger, puedes hacerlo ejecutando el siguiente comando:

ul-cli contracts create \
    --alias counter-contract \
    --sender OWNER_ALIAS \
    counter.bin

Reemplaza lo siguiente:

  • OWNER_ALIAS: Es el alias de una cuenta de usuario con el rol ROLE_CONTRACT_CREATOR.

Cuando se finalice la transacción, el resultado de este comando incluirá el ID del contrato recién implementado. Por ejemplo:

Contract created: 1:CTR:005XvYfiSm3913Jwv4y8HVQucStJ2Ev15Sar6A1kNNX10

Invoca un método de contrato

Una vez que se implementa un contrato, cualquier cuenta de usuario con el rol ROLE_CONTRACT_PARTICIPANT puede enviar una transacción InvokeContractMethod para invocar cualquiera de los métodos públicos del contrato.

Si usas la CLI de Universal Ledger, puedes hacerlo ejecutando el siguiente comando:

ul-cli contracts invoke \
    --alias counter-contract \
    --method-name increment \
    --sender PARTICIPANT_ALIAS

Reemplaza lo siguiente:

  • PARTICIPANT_ALIAS: Es el alias de una cuenta de usuario con el rol ROLE_CONTRACT_PARTICIPANT.

Lee el estado del contrato

Para concluir este instructivo, puedes enviar una solicitud QueryAccount para leer y verificar el estado del contrato almacenado en el libro mayor. Este es el mismo método de la API que se usa para consultar y recuperar los detalles de cualquier cuenta de Universal Ledger.

Con la CLI de Universal Ledger, puedes ejecutar lo siguiente:

ul-cli accounts describe --alias counter-contract

Esto debería confirmar que el valor del contador ahora está establecido en 1, lo que produce un resultado como el siguiente:

Account: 1:CTR:005XvYfiSm3913Jwv4y8HVQucStJ2Ev15Sar6A1kNNX10
Contract account details:
  Owner: 1:USR:XCL:022uF6cVkTJBaa6pViqTuYqP4455jnRbRc4bWannZGg0b
  Contract fields:
    value: int64_value:1

  Balances:
    None

¿Qué sigue?