Back to Blog

Solana Simplificado 01: Domina los Conceptos Fundamentales de Solana en Una Sola Lectura

June 7, 2024
10 min read

Introducción

En 2024, Solana emergió de forma espectacular, con su Valor Total Bloqueado (TVL) disparándose de mil millones de USD a principios de año a casi cinco mil millones de USD, convirtiéndose en la cuarta blockchain pública más grande.

En comparación con Ethereum, Solana ofrece a los usuarios una experiencia superior con mayor velocidad y menores costos. El mecanismo de consenso basado en Prueba de Historia y el modelo de procesamiento asincrónico de transacciones ofrecen a los desarrolladores un alto rendimiento de transacciones y baja latencia, convirtiéndola en una plataforma favorita para todo tipo de aplicaciones descentralizadas.

BlockSec ha planificado especialmente la serie "Solana Simplificado", que cubre conceptos básicos de Solana, guías prácticas para analizar transacciones de Solana y tutoriales para escribir contratos inteligentes en Solana.

Como primer artículo de esta serie, este texto profundizará en los conceptos clave dentro de la red Solana, incluyendo sus mecanismos de operación, modelo de cuentas y transacciones, sentando las bases para escribir contratos inteligentes correctos y eficientes en Solana.

eBPF: La Piedra Angular de la Ejecución de Transacciones en Solana

Para escribir y ejecutar contratos inteligentes, las blockchains generalmente requieren un lenguaje de programación y un entorno computacional Turing-completo.

Los contratos inteligentes en Ethereum suelen escribirse en un lenguaje de alto nivel llamado Solidity. El compilador los traduce a bytecode, que luego se ejecuta en la Máquina Virtual de Ethereum (EVM). En lugar de desarrollar un entorno virtual y un lenguaje completamente nuevos, Solana ha optado por aprovechar al máximo las tecnologías avanzadas existentes. La máquina virtual eBPF (filtro de paquetes Berkeley extendido), diseñada inicialmente para ampliar las funcionalidades del kernel de Linux, ha sido seleccionada por Solana para servir como su entorno de ejecución subyacente.

Entonces, ¿qué ventajas ofrece eBPF sobre la EVM?

A diferencia de la EVM, que se limita a la ejecución interpretada, eBPF admite la compilación Just-In-Time (JIT), lo que le permite traducir el bytecode en instrucciones de máquina que el procesador puede ejecutar directamente. Esta capacidad aumenta significativamente la eficiencia del programa.

Además, eBPF cuenta con un conjunto de instrucciones eficiente y una infraestructura madura. Los desarrolladores pueden crear contratos inteligentes utilizando el lenguaje Rust. Aprovechando el backend eBPF del framework de compilador LLVM, los programas en Rust pueden compilarse directamente a bytecode eBPF.

El Modelo de Cuentas de Solana

Estructura de Cuentas de Solana

Los datos se almacenan en forma de cuentas en Solana. Como se ilustra a continuación, todos los datos dentro de Solana pueden conceptualizarse como una vasta base de datos clave-valor. Las claves en esta base de datos son las direcciones de las cuentas. Para las cuentas de "billetera" (es decir, cuentas controladas directamente por usuarios de Solana mediante pares de claves públicas-privadas), estas direcciones son claves públicas generadas utilizando el sistema de firma Ed25519. Los valores en la base de datos consisten en los detalles específicos de cada cuenta, incluyendo el saldo y otra información relevante.

Solana utiliza la siguiente estructura conocida como AccountInfo para describir una cuenta.

El AccountInfo de cada cuenta contiene cuatro campos. A continuación se explica cada uno:

  • Campo Data: Este campo almacena los datos relacionados con la cuenta. Si la cuenta es un programa (es decir, un contrato inteligente), almacena el bytecode eBPF. De lo contrario, el formato de los datos generalmente es definido por el creador de la cuenta.

  • Campo Executable: Este campo se utiliza para indicar si la cuenta es un programa. Es importante destacar que, a diferencia de Ethereum, los programas en Solana pueden actualizarse.

  • Campo Lamports: Este campo registra el saldo de tokens de Solana en la cuenta. Los Lamports son en realidad la unidad más pequeña del Token SOL (1 SOL = 1 mil millones de Lamports).

  • Campo Owner: Este campo indica el propietario de la cuenta. En Solana, cada cuenta tiene un "Propietario". Por ejemplo, el propietario de todas las cuentas de "billetera" es el Programa del Sistema, una cuenta especial en la red Solana responsable de funciones como la creación de cuentas. El propietario de la cuenta es el único que puede modificar los datos de la cuenta y deducir Lamports del saldo (sin embargo, cualquiera puede aumentar los Lamports transfiriendo fondos a la cuenta).

Cuentas Predefinidas de Solana

Solana cuenta con un conjunto de programas ejecutables predefinidos conocidos como Native Programs, que se despliegan en direcciones fijas. A medida que la red Solana se actualiza, estos programas predefinidos también pueden actualizarse. Sirven como APIs y funciones de biblioteca, ofreciendo funcionalidades específicas dentro de la red Solana.

Dentro de los Native Programs, uno con el que los desarrolladores interactúan frecuentemente es el System Program. El Programa del Sistema proporciona a los desarrolladores un conjunto de instrucciones, cada una de las cuales realiza una tarea independiente. Por ejemplo, los desarrolladores pueden usar la instrucción CreateAccount para crear nuevas cuentas, o la instrucción Transfer para transferir Lamports a otras cuentas.

Otro Native Program común es el programa BPF Loader. Es el propietario de todas las demás cuentas de programas y es responsable de desplegar, actualizar y ejecutar programas personalizados. Cuando una cuenta de "billetera" necesita actualizar un programa que ha desplegado, en realidad se realiza delegando al programa BPF Loader, ya que solo el propietario de un programa tiene la autoridad directa para modificar datos.

Además de los Native Programs, Solana también ofrece un conjunto de cuentas conocidas como Sysvars. Estas cuentas proporcionan a los programas en Solana información y variables globales relacionadas con el estado actual de la red Solana, como el reloj actual y el hash del bloque más reciente.

Renta de Cuentas

En la blockchain de Solana, cada cuenta debe mantener una cantidad mínima de Lamports como saldo mínimo, conocida como renta. A diferencia de la renta en la vida real, la renta en Solana es recuperable. Para garantizar que los datos de una cuenta estén disponibles en la cadena, la cuenta debe mantener una cantidad adecuada de Lamports. La cantidad de renta está relacionada con el tamaño de los datos que ocupa la cuenta.

Cualquier transacción que intente reducir el saldo de la cuenta por debajo del monto de la renta fallará, a menos que reduzca el saldo exactamente a cero. Reducir el saldo a cero indica que la renta de la cuenta ha sido recuperada, y al final de la transacción, Solana eliminará los datos de la cuenta correspondiente en el proceso de recolección de basura.

🧐 Visualización de Cuentas de Solana en Exploradores de Solana

Para comprender mejor los conceptos mencionados anteriormente, utilizamos el proyecto "Hello World" de Solana para desplegar una cuenta de programa, que puede visualizarse usando el explorador de blockchain de Solana, Solscan.

Como se muestra en la imagen anterior, podemos ver primero que la cuenta ha sido etiquetada como "Program". Una porción de Lamports fue deducida del saldo del remitente como renta para esta cuenta, por lo que el campo SOL Balance no está vacío. Además, dado que la cuenta que creamos es un programa, su campo Executable está establecido en Sí. Es posible que te confunda que el campo Executable Data almacena una dirección, en lugar de un programa eBPF. Como se mencionó anteriormente, Solana permite actualizaciones de programas, y en realidad se implementa a través de un patrón de "proxy". Dado que inicialmente no se permiten modificaciones directas a la cuenta del programa, Solana crea una cuenta de datos separada para almacenar el programa eBPF, mientras que el campo Data en la cuenta del programa solo almacena la dirección de esta cuenta de datos.

Siempre que se necesite una actualización del programa, solo es necesario modificar el campo Data de la cuenta de datos. Usando Solscan para ver la cuenta de datos, podemos encontrar que está marcada como "Program Executable Data Account", y su campo Data almacena el programa real.

El campo Owner en la sección "More Info" es el BPF Loader, consistente con lo mencionado anteriormente.

Alguien podría notar que el último campo de "Overview" es Upgrade Authority, que no está presente en el AccountInfo. ¿Qué significa?

Como se mencionó anteriormente, la cuenta de "billetera" delega las actualizaciones del programa al BPF Loader. Antes de actualizar, el BPF Loader verifica si el delegante es la cuenta que originalmente desplegó el programa. Dado que el Owner de la cuenta del programa ya está configurado como BPF Loader, no tiene espacio para almacenar esta información. Por lo tanto, Solana la coloca en el campo Data de la cuenta de datos. Por eso existe un campo Upgrade Authority en "Overview", y en realidad es la dirección de la billetera que desplegó el programa. La imagen a continuación muestra la relación entre la cuenta del programa y la cuenta de datos. Nótese que el campo Data de la cuenta de datos consiste tanto en la dirección de la billetera como en el código eBPF.

Transacciones e Instrucciones en Solana

En Solana, los usuarios ejecutan programas emitiendo transacciones. Un aspecto único de Solana es su capacidad para ejecutar estas transacciones en paralelo, lo cual es una razón clave detrás de sus velocidades de transacción ultrarrápidas. Ahora veamos más de cerca cómo están diseñadas las transacciones en Solana.

Una transacción de Solana consiste en firmas y un mensaje. Una transacción puede incluir múltiples firmas. El mensaje de una transacción está compuesto por cuatro partes, como se ilustra a continuación.

El Header y el Compact Array of Account Addresses especifican todas las cuentas involucradas en una transacción y sus características durante la transacción, incluyendo si la cuenta es un firmante y si es modificable durante la ejecución. Con esta información, Solana puede verificar las firmas proporcionadas por las cuentas firmantes y procesar transacciones en paralelo, siempre que estas transacciones no incluyan cuentas que escriban en el mismo estado.

El Recent Blockhash actúa como una marca de tiempo para la transacción. Si el blockhash de una transacción es 150 bloques más antiguo que el blockhash más reciente, se considera expirado y no se ejecutará.

El Compact Array of Instructions es la parte más importante de la transacción, que contiene una o más instrucciones. Una instrucción esencialmente activa la ejecución de una rutina proporcionada por una cuenta de programa. Cada instrucción consta de tres campos, como se ilustra a continuación.

El primer campo, Program ID Index, especifica el receptor de la instrucción, que es el programa en cadena que necesita procesar la instrucción. En lugar de almacenar una dirección de 32 bytes, esta dirección se coloca dentro del Compact Array of Account Addresses del mensaje de la transacción, y el campo solo almacena un índice u8 que apunta a la dirección en el array.

Similar al primer campo, el segundo campo almacena índices de direcciones de cuentas, conocidos como Compact Array of Account Address Indexes. Este array especifica todas las cuentas involucradas en esta instrucción.

El último campo es un array de bytes que contiene los datos adicionales requeridos por el programa para procesar la instrucción, como los argumentos de la función.

Es importante destacar que Solana procesa todas las instrucciones dentro de una transacción en orden y garantiza la ejecución atómica de la transacción. Esto significa que o se completa totalmente con todas las instrucciones procesadas exitosamente, o falla por completo. No habrá una situación en la que algunas instrucciones sean procesadas y otras no.

🧐 Visualización de Transacciones de Solana en Exploradores de Solana

Usamos otro explorador de Solana para ver la transacción que creó la cuenta del programa anteriormente. En la sección Overview, puedes ver la firma de la transacción de Solana, el blockhash reciente y otra información:

En la sección Account Input, se listan todas las cuentas involucradas en la transacción actual, junto con sus características en la transacción. Podemos ver que, además de las direcciones del remitente y la cuenta del programa, también se han incluido dos cuentas Native Programs y Sysvar.

Dado que es una transacción simple de creación de programa, contiene solo dos instrucciones. El receptor de la primera instrucción es el Programa del Sistema, responsable de crear la cuenta del programa. El receptor de la segunda instrucción es el BPF Loader, que crea una cuenta de datos para almacenar el código eBPF desplegado y escribe su dirección en el campo Data de la cuenta del programa.

Conclusión

Los contratos inteligentes en Solana se desarrollan en Rust y se ejecutan en la máquina virtual eBPF. Solana sigue el modelo de cuentas, donde las cuentas en cadena necesitan mantener suficiente renta para evitar que los datos sean eliminados. Una transacción consiste en una o más instrucciones que definen todas las cuentas requeridas, lo que permite el procesamiento en paralelo y mejora el rendimiento mientras reduce la latencia de respuesta. Estas características en conjunto han contribuido al rápido desarrollo de Solana, convirtiéndola en una de las blockchains favoritas.

Lee otros artículos de esta serie: