Máquina Virtual TON
La Máquina Virtual de The Open Network (TVM o TON VM) es una máquina virtual diseñada para ejecutar contratos inteligentes en la blockchain de TON. Es la base para el procesamiento de transacciones y la gestión del estado de la red. Los desarrolladores utilizan las herramientas de TVM para crear aplicaciones descentralizadas.
TVM procesa mensajes entrantes y datos persistentes, genera nuevos mensajes y modifica datos. Los requisitos de TVM incluyen soporte para futuras extensiones manteniendo la compatibilidad retroactiva, alta densidad de código para ahorrar espacio en la blockchain y un determinismo completo (cada ejecución de código debe producir el mismo resultado).
Historia y evolución de TVM
La Máquina Virtual de TON (TVM) fue desarrollada por el equipo de Telegram en 2018. Desde su desarrollo inicial, ha continuado evolucionando a través de varios hitos clave:
- Primera versión de TVM (2018): Fue presentada junto con el lanzamiento de la red de prueba de TON. Esta versión se centró en la funcionalidad de los contratos inteligentes y su integración en la blockchain de TON.
- Marzo de 2020: Se publicó una documentación técnica detallada sobre TVM, que describía aspectos de la máquina virtual, incluido el soporte para diferentes tipos de datos y la optimización de operaciones.
- Lanzamiento de la red principal: Tras pruebas y ajustes, la red principal de TON se lanzó en 2020. En este punto, TVM ya soportaba operaciones más complejas y proporcionaba una ejecución de código completamente determinista.
Conceptos básicos de TVM
TVM utiliza notaciones (una forma de representar datos) para cadenas de bits, las cuales se representan en dos formatos:
- Notación hexadecimal: Las cadenas de bits cuya longitud es divisible por múltiplos de cuatro se dividen en grupos de cuatro bits, cada uno representado por un dígito hexadecimal de 0 a F. Si la longitud no es un múltiplo de cuatro, la cadena se completa con un tag especial de finalización para indicar la modificación.
- Serialización a una secuencia de octetos: En este caso, para la representación en bytes, la cadena se divide en grupos de 8 bits. Si es necesario, la cadena se expande para que su longitud sea divisible por ocho.
TVM como una Stack máquina
TVM funciona como una Stack máquina. Una Stack máquina es un modelo de computación en el cual los datos se almacenan en una estructura de tipo pila (último en entrar, primero en salir) en lugar de variables o registros. Las operaciones básicas, incluidas las operaciones aritméticas, obtienen argumentos de la pila y devuelven el resultado en ella.
Tipos de valores en TVM
TVM opera con tipos de valores predefinidos:
- Integer: Enteros con signo de 257 bits.
- Cell: Objetos que contienen datos de hasta 1023 bits y hasta 4 referencias.
- Tuple: Colecciones ordenadas de valores de diferentes tipos.
- Slice: Subceldas que contienen parte de los datos y referencias a la celda original.
- Builder: Herramientas para serializar datos en nuevas celdas.
- Continuation: Objetos que representan puntos de continuación de una ejecución.
- Null: Un tipo que representa la ausencia de un valor, utilizado para indicar valores vacíos o no inicializados.
Instrucciones de TVM
Las instrucciones de TVM se categorizan según el tipo de operaciones:
- Primitivas de Stack y tuplas: Reordenamiento de la pila y manipulación de tuplas.
- Primitivas constantes: Inserción de valores predefinidos en la pila.
- Primitivas aritméticas: Realización de operaciones aritméticas estándar.
- Primitivas de celdas: Creación de nuevas celdas y acceso a los datos en celdas existentes.
- Primitivas de control de flujo y continuaciones: Control del flujo de ejecución del programa.
- Primitivas personalizadas: Operaciones específicas requeridas para aplicaciones en TON.
Celdas de TVM
Las celdas de TVM son los elementos básicos de la memoria y el almacenamiento persistente. Cada celda puede contener hasta 1023 bits de datos y hasta 4 referencias, formando un grafo acíclico dirigido (DAG). Todos los datos de la blockchain se representan como colecciones de celdas, lo que simplifica el almacenamiento y el procesamiento.
Tipos de celdas
- Celdas normales (tipo-1): Celdas estándar que contienen datos y referencias.
- Celdas exóticas: Tienen tipos únicos (1-255) y particularidades en la deserialización y el hashing. Entre estas se incluyen ramas truncadas, celdas de referencia de biblioteca y celdas Merkle.
Control de flujo, continuaciones y excepciones en TVM
Las continuaciones en TVM son elementos centrales para controlar el flujo de ejecución de los programas. Se utilizan para llamadas a subrutinas, operaciones condicionales e iterativas, así como para el manejo de excepciones.
Una continuación es un marcador de ejecución que puede activarse posteriormente, permitiendo que la ejecución del programa continúe desde un estado guardado.
Tipos de continuaciones
- Continuaciones normales: Incluyen código ejecutable, pila, una lista de valores almacenados en registros de control y una página de código para interpretar las instrucciones.
- Continuaciones simples: Se caracterizan únicamente por el código y la página de código, sin datos adicionales de la pila.
- Continuaciones actuales: Reflejan el código que se está ejecutando. Este es un componente clave del estado de TVM que define la operación actual.
Las continuaciones participan activamente en la decodificación y ejecución de operaciones. Pueden decodificar una instrucción, ejecutarla y actualizar el estado actual del programa hasta que se queden sin código o encuentren una instrucción de retorno.
Las continuaciones se controlan mediante las instrucciones JMP y RET, que permiten alternar entre continuaciones pasando el control y los datos necesarios.
Las excepciones en TVM se gestionan mediante continuaciones especiales que se activan cuando ocurren errores o ciertas condiciones específicas. Estas continuaciones manejan las excepciones proporcionando parámetros de error para realizar acciones adicionales. TVM incluye primitivas condicionales e iterativas, como IF, WHILE y REPEAT, que enriquecen el lenguaje con constructos para controlar la ejecución del código en respuesta a condiciones dinámicas. Las continuaciones también pueden usarse para simular estructuras orientadas a objetos, donde cada objeto está representado por una continuación y los métodos del objeto se activan a través de estas continuaciones.
Code Pages y Codificación de Instrucciones
Las páginas de código aseguran la ejecución transparente del código escrito para diferentes versiones de TVM y permiten la interacción entre instancias de código desarrolladas en distintos momentos.
En las continuaciones de cada continuación normal, las páginas de código incluyen un campo de 16 bits denominado página de código, que indica qué página se utilizará para ejecutar su código. Esto permite que cada continuación utilice diferentes versiones de codificaciones de instrucciones necesarias para su ejecución, lo cual es crucial para mantener la compatibilidad entre versiones de TVM.
Las instrucciones en TVM se codifican utilizando un código binario con prefijo, lo que garantiza la unicidad en la decodificación. Se genera una excepción de código de operación no válido si el prefijo del código actual de la continuación no coincide con una instrucción válida de la página de código actual.
Es posible realizar cambios automáticos entre páginas de código según la operación que se esté ejecutando, lo que permite optimizar la ejecución del código. Por ejemplo, se pueden utilizar páginas de código especializadas para ciertos tipos de operaciones, como manipulación de pilas o procesamiento de datos, donde las instrucciones de un tipo suelen seguirse unas a otras.
Comparación de TVM con Ethereum Virtual Machine (EVM)
La Máquina Virtual de TON y la Máquina Virtual de Ethereum son máquinas virtuales apilables para ejecutar contratos inteligentes, pero tienen diferencias.
TVM utiliza el modelo de «paquete de celdas», donde los datos se representan como celdas, cada una con hasta 128 bytes de datos y enlaces a otras celdas. Esto ayuda a manejar estructuras de datos complejas como árboles y grafos acíclicos dirigidos (directed acyclic graphs (DAGs). Por otro lado, EVM utiliza enteros de 256 bits y Merkle Patricia Trie (MPT) para almacenar el estado. Esta estructura de datos requiere más recursos porque los números de 256 bits y los MPT necesitan más memoria y potencia computacional.
TVM también tiene una verificación automática de desbordamiento para las operaciones aritméticas, lo que mejora la confiabilidad del código. En EVM, dicha verificación requiere una implementación manual, lo que complica el desarrollo.
Las características criptográficas de TVM incluyen soporte para Curve25519, emparejamientos de Weil para zk-SNARKs y sha256, mientras que EVM utiliza secp256k1 y keccak256. En otras palabras, TVM admite operaciones criptográficas más complejas.
El lenguaje de programación principal para TVM es FunC, que ofrece soporte para tipos estáticos y tipos de datos algebraicos, a diferencia de Solidity, el lenguaje de EVM.