Implementa un contrato programable

El libro de contabilidad universal admite contratos programables que se pueden implementar en una red para automatizar y aplicar acuerdos entre los participantes interesados.

En este instructivo, se muestran a los desarrolladores los pasos necesarios para desarrollar, implementar e interactuar 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 del libro mayor universal con el ROLE_CONTRACT_CREATOR Esta cuenta se convertirá en la propietaria del contrato.

  • Una o más cuentas de usuario del registro universal con el objeto 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 la crea su administrador de cuentas, en el momento en que se envía su transacción CreateAccount o se modifica más adelante a través de una transacción AddRoles si la cuenta ya existe. Para fines experimentales, 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 bytecode para el registro universal.

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 el objeto binario funciona.

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

Escribe tu contrato

GCULpy es el lenguaje que se usa para escribir contratos para el registro contable universal. Es un subconjunto de Python con escritura estática, 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 inseguros. Para obtener más detalles, consulta la referencia de el lenguaje GCULpy.

Dado 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 el 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 brindar 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 prueba preferidos, lo que garantizará la confiabilidad y la precisión de tus contratos antes de la implementación.

Compila el contrato

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

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

Implementa el contrato

Para implementar el contrato en una red de Universal Ledger, envía una transacción CreateContract firmada por una cuenta de usuario que tenga el ROLE_CONTRACT_CREATOR.

Si usas la CLI de Universal Ledger, puedes ejecutar 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 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 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 ejecutar 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 ROLE_CONTRACT_PARTICIPANT.

Leer el estado del contrato

Para concluir este instructivo, puedes enviar una solicitud de QueryAccount para leer y verificar el estado del contrato almacenado en el libro de contabilidad. Este es el mismo método de 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?