Introducción al desarrollo con TEAL en Algorand

TEAL, que es un acrónimo de Transaction Execution y Approval Language, es el lenguaje de contrato inteligente principal adoptado por la cadena de bloques Algorand.

Versiones de TEAL

Los cambios en PyTeal, que es una biblioteca de Python que se compila en TEAL, están en marcha y deberían estar disponibles pronto. El marco para desarrolladores de Reach ahora es totalmente compatible con la versión 3 de TEAL, lo que permite a los desarrolladores centrarse en la lógica empresarial de una aplicación. A continuación, el marco genera automáticamente contratos TEAL verificados formalmente.

Este artículo explica los cambios que trae TEAL 3 a la comunidad de programadores.

Para obtener más información sobre TEAL, consulte la documentación para desarrolladores.

Al igual que con la versión 2 de TEAL, en la tercera, los creadores de contenido deben especificar a qué versión de éste se adhieren sus contratos actuales. Esto se hace en la primera línea de código en un programa TEAL. Por ejemplo:

// Teal Version 2
#pragma Version 2

// Teal Version 3
#pragma Version 3

Si se omite esta línea, la cadena de bloques de Algorand asumirá que el contrato utiliza la versión 1 de TEAL.

Adición de transacciones y propiedades globales

Las siguientes secciones analizan las nuevas propiedades de transacción y una nueva variable global disponible en la versión 3 de TEAL.

Interactuar con aplicaciones adicionales

Algo y los contratos inteligentes con estado se denominan Aplicaciones. Cuando se implementan, se hace referencia a ellos mediante un ID de aplicación. Estos contratos se comunican mediante transacciones de aplicaciones. La transacción de la aplicación principal proporciona información adicional que se puede pasar y procesar mediante el código TEAL del contrato inteligente con estado.

Figura 1 – Arquitectura de llamada de transacción de contrato inteligente con estado.

Cualquier aplicación puede examinar el estado global de hasta dos contratos inteligentes adicionales por llamada de transacción. El proceso para hacer esto se describió en un artículo anterior.

Esto se logra pasando las ID de aplicación del contrato inteligente con estado adicional con la llamada de transacción al contrato inteligente con estado. En TEAL, esto se conoce como Application Array o Foreign Apps Array. Actualmente dentro de éste, el desarrollador debe saber antes de escribir el código de contrato inteligente cuántas aplicaciones adicionales se espera que pasen a la convocatoria del contrato.

La versión 3 de TEAL ahora proporciona dos propiedades de transacción adicionales que están disponibles para determinar el número de ID de aplicaciones pasadas y también proporcionan una propiedad conveniente para acceder a cualquier ID de aplicación pasada. Estas propiedades NumApplications y Applications están disponibles para su uso con una sola transacción usando txn en el código de operación o para transacciones agrupadas usando gtxn.

// Verify current transaction has two Applications 
// passed with the transaction
txn NumApplications
int 2
==

// Check the second transaction in a group to verify 
// it has only one application in its application array
gtxn 1 NumApplications
int 1
==

// Check that the first foreign Application 
// passed in has an Application ID equal to 123456
txn Applications 1
int 123456

Para obtener más información sobre cómo leer el estado global de otras aplicaciones, consulte la documentación para desarrolladores.

Interactuar con activos

De manera similar a la interacción con aplicaciones adicionales, los contratos inteligentes con estado también pueden interactuar con hasta dos activos por llamada de transacción. Estos ID de activos se pasan en la matriz de activos y con la versión 3 de TEAL, los desarrolladores pueden hacer referencia al número de activos pasados ​​utilizando la propiedad Num Assets de transacción y recuperar el AssetID utilizando la Assets.

// Verify current transaction has two Assets 
// passed with the transaction
txn NumAssets
int 2
==

// Check the second transaction in a group to verify 
// it is passed the Asset ID 123456 as the first asset
// in the assets array
gtxn 1 Assets 0
int 123456
==

Para obtener más información sobre cómo interrogar activos en contratos inteligentes con estado, consulte la documentación del desarrollador.

Variable global adicional

En versiones anteriores de TEAL, si un desarrollador solo quería permitir que el creador del contrato hiciera algo como posiblemente eliminarlo o actualizarlo, tendría que almacenar la dirección del programador en el estado global. Éste es limitado y esto también requiere un código adicional para almacenar y recuperar este estado para poder utilizarlo. La versión 3 de TEAL ahora proporciona una variable global adicional disponible dentro de un contrato inteligente con estado que registra la dirección del creador. El siguiente TEAL se puede utilizar para comprobar que el remitente de una transacción es el creador del contrato.

txn Sender
global CreatorAddress
==

Comprobaciones de uso del estado global y local

Al crear un contrato inteligente con estado, la transacción de la aplicación debe especificar el número de segmentos de bytes globales y enteros que el contrato inteligente está reservando. Además, la transacción debe especificar la cantidad de segmentos de bytes locales y enteros que se reservarán para cualquier cuenta que opte por el contrato inteligente con estado. Actualmente, los desarrolladores de TEAL no tienen acceso a estos valores. Con la versión de TEAL 3 desarrolladores pueden examinar estos valores de creación con la adición de 4 propiedades de transacción GlobalNumUint, GlobalNumByteSlice, LocalNumUint, y LocalNumByteSlice.

//this contract is reserving 5 global unsigned integers
txn GlobalNumUint
int 5
==

Para obtener más información sobre la creación de contratos inteligentes con estado, consulte la documentación para desarrolladores.

Nuevos códigos de operación TEAL

La versión 3 de TEAL proporciona códigos de operación adicionales que ofrecen muchas comodidades nuevas para los desarrolladores. Estos cambios se detallan a continuación.

El código de operación de aserción

El código de operación de aserción se proporciona para permitir que una transacción falle inmediatamente si la parte superior de la pila no es un valor entero positivo. Esta llamada está disponible para contratos inteligentes con y sin estado. La aserción también saca este valor de la pila en el proceso.

// Assuming an integer argument is passed in, fail if
// stateful contract example
txna ApplicationArgs 0
btoi
assert

El código de operación de intercambio

El código de operación de intercambio permite cambiar los dos elementos superiores de la pila. Esto a menudo es necesario para configurar parámetros para códigos de operación adicionales.

// Teal Version 2 incrementing a global integer
byte "Total"
app_global_get
gtxn 1 Amount
+
store 1

byte "Total"
load 1
app_global_put

// Teal Version 3
byte "Total"
app_global_get
gtxn 1 Amount
+
byte "Total"
swap
app_global_put

El código de operación dig n

El código de operación dig n permite a los desarrolladores de TEAL hacer una copia de cualquier valor en la pila y moverlo a la parte superior de la pila. Por ejemplo, si hay un número entero de 5 ranuras hacia abajo en la pila, se puede usar el siguiente TEAL para hacer una copia y colocarlo en la parte superior de la pila. Tenga en cuenta que hace una copia de la ranura, dejando el valor original donde está también.

dig 4

Los códigos de operación de bits

La versión 3 de TEAL ahora ofrece soporte para obtener y configurar bits específicos. Este es un código de operación extremadamente importante para facilitar la mecánica de bits y para algunas operaciones matemáticas. Se suministran dos códigos de operación (getbit y setbit) para manejar la obtención de un bit específico o el establecimiento de un bit específico.

// check that the 6th bit is set in a unit64
int 235 // target
int 6 // bit to get
getbit
int 1
==

El código de operación setbit toma tres parámetros, el valor objetivo, el bit a establecer y el valor a establecer. Los valores válidos para el último parámetro son 0 o 1. Cualquier otro valor provocará una devolución fallida del contrato.

// global byte slices can store up to 64 bytes, set 
// the 400th bit to 1
// this will panic if there is no 400th bit
int 0
byte "myglobal64byteglobal"
app_global_get_ex
assert
int 400 // bit to  set
int  1 // value to set it to
setbit

// hex values supported
int 0x0000 // target
int 3 // bit to set
int 1 // value to set it to
setbit
int 0x0008
==

byte 0xfffff0
int 21 // target bit
int 1 // value to set it to
setbit
byte 0xfffff4
==

Los códigos de operación de bytes

Actualmente, TEAL admite segmentos de bytes que pueden tener hasta 64 bytes. Estos segmentos de bytes se pueden almacenar como valores de almacenamiento globales o locales y se pueden manipular en la pila. A menudo, los desarrolladores pueden querer acceder o modificar uno de estos bytes individualmente. La versión 3 de TEAL ahora admite los códigos de operación getbyte y setbyte. Estos códigos de operación solo funcionan con segmentos de bytes y no admiten uint64s.

El código de operación getbyte acepta dos argumentos, el segmento de bytes de destino y el byte a recuperar. Estos argumentos se extraen de la pila y el byte específico se coloca en la parte superior de la pila. Intentar recuperar un byte que no existe provocará pánico y una devolución fallida del contrato.

// Get the third byte in the following string
byte "Test the getbyte opcode" // target
int 3 // byte to retrieve
getbyte
int 116 // ASCII value for 't'
==

La llamada al código de operación setbyte toma tres argumentos, el segmento de bytes de destino, el byte para establecer y el valor para establecerlo. Estos se extraen de la pila y el nuevo segmento de bytes se coloca en la parte superior de la pila.

// Change the third byte in the following byte slice to ASCII 'i'
byte "john" // target
int 2 // byte to set
int 105 // value to set it to "i"
setbyte
byte "join"
==

El código de operación seleccionado

La versión 3 de TEAL ahora también admite la selección condicional de resultados. Esto se puede hacer con el código de operación select. Este código de operación espera que se le pasen tres argumentos e inspecciona el último argumento, que estará en la parte superior de la pila. Si este valor no es igual a 0, el segundo argumento de la pila se coloca en la parte superior de la pila. Si el valor es 0, el tercer valor de la pila se coloca en la parte superior de la pila. Los tres argumentos iniciales se extraen de la pila y el resultado final es solo el valor de retorno seleccionado.

int 1 // 0 value selection
byte "this is a select test" // not equal to 0 selection
int 1 // condition to check
select // finishes with the byte string on the top of the stack

Mejora del rendimiento al cargar uint64 y segmentos de bytes

Teal Version 3 también proporciona códigos de operación optimizados para enviar uint64s y segmentos de bytes a la pila. Estos dos códigos de operación son pushint y pushbytes respectivamente.

// load int 5 onto the top of the stack
pushint 5
// load byte slice onto the top of the stack
pushbytes "this is a byte slice"

El código de operación min_balance

A menudo, las transacciones fallan porque el resultado de una transacción reduciría una cuenta por debajo del saldo mínimo requerido en la cadena de bloques de Algorand. Este saldo mínimo está determinado por la cantidad de activos y aplicaciones en los que la cuenta está actualmente habilitada, así como por un saldo de protocolo mínimo que aparecerá en el libro mayor. A menudo, cuando se trabaja con contratos inteligentes, es valioso tener este valor calculado disponible dentro de un contrato inteligente para manejar esta condición. La versión 3 de TEAL ahora tiene el código de operación min_balance disponible en contratos con estado que permite verificar el saldo mínimo de cualquier cuenta en la matriz de cuentas con llamada de aplicación. Este código de operación toma un parámetro que es el índice en la matriz de cuentas (int 0 es el remitente de la llamada de la aplicación). El código de operación saca este valor de la pila y coloca el saldo mínimo de esa cuenta en la parte superior de la pila. Este valor se especifica en microAlgos.

// load application call senders balance
int 0
balance
// load a spend transaction from the same sender
// and subtract
gtxn 1 Amount

// load second transaction fee and subtract
gtxn 1 Fee
-
// load first transaction free and subtract 
txn Fee
-
// get senders min balance 
int 0
min_balance
// verify result of subtractions is greater than or equal to min balance
>=

Los códigos de operación gtxns y gtxnsa

TEAL actualmente proporciona los códigos de operación gtxn y gtxna para acceder a varias propiedades de transacción dentro de un grupo de transacciones. La transacción específica se determina después del código de operación, por ejemplo, hace gtxn 1 Amount referencia a la propiedad de monto de la segunda transacción. El código de operación gtxna proporciona acceso a muchos de los parámetros que pueden ser matrices, como la matriz de argumentos de la aplicación para un contrato inteligente con estado. Por ejemplo gtxna 0 ApplicationArgs 0, empujará el primer argumento de la primera transacción a la parte superior de la pila.

TEAL ahora proporciona dos nuevos códigos de operación para hacer referencia a transacciones grupales usando la pila en lugar de especificarlas en el comando de código de operación. Estos códigos de operación gtxns y gtxnsa funcionan de manera muy similar a la llamada anterior, pero permiten un nivel de direccionamiento indirecto y hacen posible escribir LogicSigs que sean más componibles. Por ejemplo, con esta adición, LogicSig puede referirse a “la siguiente transacción en el grupo” en lugar de especificar la ranura exacta.

Los dos ejemplos anteriores se ilustran a continuación utilizando la versión 3 de TEAL. Finalmente, también se muestra cómo obtener la siguiente transacción en el monto de un grupo.

// get the amount of the second transaction
int 1
gtxns Amount

// get the first argument of the first transaction
// in a stateful smart contract
int 0
gtxnsa ApplicationArgs 0

// Assume current transaction depends on the transaction
// that is next in the group
// get current group index
// add one and then get that transaction amount
txn GroupIndex
int 1
+
gtxns Amount

Conclusión

Algorand actualiza y mejora continuamente el protocolo y nuestras herramientas para brindar un mejor soporte a los desarrolladores de blockchain. Esperamos que estos cambios le resulten útiles. ¡Actualmente estamos trabajando en funciones más interesantes que estarán disponibles muy pronto! Asegúrese de proporcionar sus comentarios a través de github y los numerosos canales sociales dedicados a nuestra comunidad de desarrolladores.


Este artículo ha sido escrito originalmente por Jason Weathersby  en «Artículos» del portal para desarrolladores de Algorand  y traducido por AlgoLatam.

Original Article: https://developer.algorand.org/articles/introducing-teal-version-3/

Deja una respuesta

Tu dirección de correo electrónico no será publicada.