PyTeal: escritura de contratos Algorand Smart en Python

PyTeal es un enlace de lenguaje python para Algorand Smart Contracts (ASC) que abstrae las complejidades de escribir contratos inteligentes. PyTeal se proporciona como una herramienta de código abierto para la comunidad de Algorand. Lo invitamos a probar, usar y contribuir con PyTeal si está interesado en desarrollar e implementar ASC en Python.

En la versión 2.0, agregamos ASC como la primitiva de contrato inteligente de capa 1 de alto rendimiento para Algorand.

Los ASC están escritos en un lenguaje de pila basado en código de byte llamado Lenguaje de aprobación de ejecución de transacciones (TEAL). TEAL puede analizar y aprobar transacciones, pero no puede crear o cambiar transacciones, y como resultado solo devuelve verdadero o falso.

TEAL fue diseñado para ser significativamente limitado en relación con lo que la mayoría del mundo piensa cuando se usa el término "contacto inteligente". El lenguaje es un lenguaje no "completo", que no admite bucles pero admite ramificaciones directas, consta de 30 instrucciones básicas, se ejecuta como un programa de línea recta únicamente utilizando operaciones TEAL y cada ASC es como máximo 1KB- largo.

Sin embargo, hay una sobrecarga significativa en la escritura de lógica usando un lenguaje de pila. También existe la sobrecarga adicional de necesitar aprender otro idioma de blockchain.

PyTeal permite a los desarrolladores de Algorand expresar su lógica de contrato inteligente en Python. La biblioteca PyTeal luego compila la lógica del contrato inteligente para el código fuente TEAL para los desarrolladores. En pocas palabras, PyTeal extrae mucho trabajo pesado que se requiere al escribir TEAL.

Echemos un vistazo a un programa PyTeal de pago periódico.

El núcleo de este ejemplo se encuentra entre las líneas 14 y 30 (en las líneas 6-12, simplemente estamos definiendo constantes).

Echemos un vistazo a periodic_pay_core:

Lo primero que hace este programa es verificar el tipo de transacción. En este caso, está comprobando una transacción de pago.

Txn.type_enum () == Int (1)

A continuación se muestra la lista de TypeEnums:

https://developer.algorand.org/docs/reference/teal/opcodes/

Lo siguiente que hace el programa es verificar la tarifa para asegurarse de que sea inferior a una cantidad razonable. Esto siempre debe hacerse como un control de seguridad y cordura porque, de lo contrario, alguien podría enviar una transacción que el contrato podría aprobar donde todo el dinero del contrato se desperdicia en la tarifa de transacción.

Txn.fee () <= tmpl_fee,

Entonces esto dice, asegúrese de que la tarifa de transacción sea menor o igual a 1000.

Del mismo modo, periodic_pay_transfer verifica que la transacción establezca CloseRemainderTo en la dirección global cero (lo que significa que la transacción no cerrará el saldo de la dirección), establezca el receptor de la transacción en el receptor previsto y establezca el monto de la transacción en cantidad prevista

Además, permite que la transferencia suceda cada tmpl_period rondas para tmpl_dur rondas al verificar que Txn.first_valid () es divisible por ttmpl_period y Txn.first_valid () y Txn.last_valid () están alejados.

Por último, verificamos que el contrato de arrendamiento esté configurado para limitar la tasa de reproducción. Lo que significa que solo una de estas transacciones puede mantener este contrato de arrendamiento entre la primera y la última ronda válida. Este parámetro es una cadena de 32 bytes y, combinado con el campo del remitente, hace que la transacción sea única. Si alguien reenvía la transacción con el mismo parámetro de arrendamiento y el remitente, dentro de la misma ventana de la primera y última ronda válida, la transacción será rechazada.

La sección principal final del código PyTeal especifica ese caso cerrado. Cuando el tiempo del pago periódico (Txn.first_valid ()> tmpl_timeout), todo el saldo restante se cierra a tmpl_rcv.

Ahora que se declaran todas las condiciones, podemos juntar todas las condiciones (periodic_pay_core, periodic_pay_transfer y periodic_pay_close) en periodic_pay_escrow:

periodic_pay_escrow = Y (periodic_pay_core,
O (periodic_pay_transfer,
periódico_pago_close))

En total, periódico_pago_escrow está diciendo, aquí están las condiciones para el núcleo de esta transacción de pago:

periódico_pago_core:

debe ser una transacción de pago y debe ser menor o igual que tmpl_fee

Y uno de los siguientes:

periodic_pay_transfer:

asegúrese de que CloseRemainderTo esté establecido en 0, de modo que no haya una salida accidental para los fondos que están en la cuenta, verifique el receptor, verifique el monto, verifique que esta transacción ocurra cada tmpl_periodrounds para tmpl_dur rondas, verifique ese arrendamiento está configurado correctamente

O

periódico_pago_close:

compruebe que el campo CloseRemainderTo esté establecido en el receptor, asegúrese de que el campo del receptor sea ahora 0, el FirstValid de la transacción haya pasado la ronda de tiempo de espera (tmpl_timeout) y que el importe también sea 0.

La ejecución de este código de Python producirá la siguiente fuente de TEAL:

Ahora que hemos visto PyTeal y entendemos cómo se compila en la fuente TEAL, veamos el ejemplo.

Usaremos el objetivo para compilar TEAL y Algorand Python SDK para construir y enviar la transacción.

Antes de ejecutar este código PyTeal, asegúrese de generar una cadena arbitraria de 32 bytes para el parámetro de arrendamiento y pasar esa misma cadena al código Python SDK que está utilizando para firmar y enviar la lógica. Puede usar el que está en el código PyTeal anterior si solo está haciendo una ejecución práctica de este código.

Continúe e importe el código PyTeal de la esencia en la parte superior de la publicación en su editor de elección.pip3 instale pytealpython3 periodic_payment.py

Ahora, suponga que ha instalado Algorand Python SDK y el objetivo de la herramienta de línea de comando Algorand. Podemos ejecutar el siguiente código de Python (suponiendo que el código de PyTeal esté en periodic_payment.py en la misma carpeta):

El código genera resultados como:

Woohoo! ¡Desplegó un contrato inteligente de pago periódico!

A continuación, mostramos algunas características más interesantes proporcionadas por PyTeal:

Sobrecarga de operadores de Python

PyTeal sobrecarga los operadores aritméticos y de comparación de Python (+, -, *, /,>, =,> =, ==) para que los usuarios de PyTeal puedan expresar la lógica de contrato inteligente en Python de forma más natural. Por ejemplo:

Txn.fee () <Int (4000)

comprueba que la tarifa de transacción de la transacción actual sea inferior a 4000 microAlgos.

Gtxn.amount (0) == Gtxn.amount (1) * Int (2)

comprueba que la cantidad de Algos transferidos en la primera transacción en la transferencia grupal es el doble de los algos transferidos en la segunda transacción.

Comprobación de tipo

En TEAL, hay dos tipos de datos: uint64, un tipo entero de 64 bits sin signo, y bytes, un tipo de bytes sin procesar. La entrada de cada operador de TEAL debe escribirse correctamente. De lo contrario, habrá un error de tiempo de ejecución si se ejecuta esa parte del código TEAL. En PyTeal, implementamos un subsistema de verificación de tipos que rechazará los programas PyTeal mal escritos al momento de construir el programa PyTeal. Por ejemplo,

Error de tipo “” ”“ ”” cond = Txn.fee () <Txn.receiver ()

Ejecutar este programa PyTeal en Python produce un mensaje de error:

TealTypeError: Error de tipo: TealType.bytes mientras se esperaba TealType.uint64

Esto se debe a que Txn.receiver () se escribe bytes mientras que los operandos tipados sobrecargados <expect uint64 en ambos lados.

Abstracciones de alto nivel

PyTeal también proporciona abstracciones de nivel superior "azucaradas" que capturan patrones de uso para hacer que el desarrollo en PyTeal sea aún más "dulce". Por ejemplo, observamos que un patrón de uso común de TEAL es activar diferentes casos cuando la transacción debe ser aprobada (como el caso de recepción y el caso de escape en el contrato de hash bloqueado). Creamos un operador Cond en PyTeal para facilitar la expresión de este tipo de condiciones. Por ejemplo:

holandés = Cond ((Global.group_size () == Int (5), bid),
(Global.group_size () == Int (4), canjear),
(Global.group_size () == Int (1), resumen))

Cond toma una secuencia de pares (condición, acción) y evalúa la primera acción cuya condición asociada se evalúa como verdadera. En el ejemplo anterior, si el tamaño del grupo de la transferencia atómica actual de Algorand es 5, se evalúa la oferta; si el tamaño del grupo es 4, se evalúa el canje; si el tamaño del grupo es 1, se evaluará la recapitulación. Si el tamaño del grupo no es ninguno de los anteriores, el código TEAL generado devolverá un error.

¡Gracias por leer esto! Considere usar y contribuir a PyTeal si está interesado en desarrollar e implementar contratos inteligentes de Algorand en Python.

PyTeal GitHub:

Documento de PyTeal:

Foro de usuarios de Algorand:

Victor Luchangco, Sam Abbassi, Jason Weathersby y Derek Leung también contribuyeron a este artículo. El contrato de pago periódico es del contrato de pago periódico TEAL original de Derek Leung y Max Justicz.