NUEVO: Helius adquiere Light Protocol
Cómo migrar de Ethereum a Solana: guía para desarrolladores
Blog/Investigación

Cómo migrar de Ethereum a Solana: guía para desarrolladores

Developer Experience Engineer0xIchigo en X0xIchigo en LinkedIn0xIchigo en GitHub
41 min de lectura

¿De qué trata este artículo?

Ethereum es una de las innovaciones más importantes de los últimos tiempos. Por primera vez en la historia, contamos con una plataforma global y descentralizada creada para la coordinación social, con el potencial de revolucionar muchas industrias. A pesar de su importancia, el entorno de ejecución de Ethereum, la Ethereum Virtual Machine (EVM), no está diseñado en su estado actual para aplicaciones de nivel de consumo. Es una red de un solo hilo basada en gas y con comisiones volátiles. En cambio, Solana se presenta como una red de alto rendimiento y baja latencia. Ofrece una infraestructura paralelizada con comisiones bajas y predecibles. Aborda directamente las limitaciones de la EVM y mejora su diseño original, por lo que es una opción atractiva para los desarrolladores que buscan crear aplicaciones escalables y eficientes.

Este artículo es una guía completa de migración para desarrolladores de EVM interesados en crear aplicaciones en Solana. Explica las diferencias fundamentales entre ambas, incluidos los mecanismos de consenso de Ethereum y Solana, cómo procesan las transacciones y los lenguajes usados para desarrollar contratos inteligentes. Luego, aborda el modelo de cuentas de Solana, que propone un enfoque más uniforme y versátil. El artículo también analiza Solang y Neon EVM, dos herramientas compatibles con Solidity que mejoran la experiencia de desarrollo en Solana.

Diferencias fundamentales

Esta sección analiza las diferencias clave entre Ethereum y Solana, dos blockchains cuyo objetivo es crear una máquina de estado descentralizada para la coordinación global. Sin embargo, ambas difieren de forma considerable en sus mecanismos de consenso, sus métodos de procesamiento de transacciones y los lenguajes usados para desarrollar contratos inteligentes. Comprender mejor estas diferencias fundamentales permite apreciar la clara ventaja de Solana sobre Ethereum como máquina de estado global de alto rendimiento.

Mecanismos de consenso

Los mecanismos de consenso sustentan todas las redes blockchain. Determinan cómo se verifican las transacciones y cómo se agregan bloques a la blockchain de forma segura, eficiente y descentralizada. Tanto Ethereum como Solana son redes de prueba de participación (PoS). Aunque comparten una base común en PoS, sus métodos para alcanzar el consenso difieren debido a sus reglas de confirmación.

Ethereum usa Gasper, una combinación de Casper the Friendly Finality Gadget (Casper-FFG) y el algoritmo de selección de bifurcaciones LMD-GHOST. Esta combinación forma el mecanismo de consenso que protege Ethereum.

Casper es un sistema de finalidad basado en PoS que cambia el estado de confirmación de un bloque a «finalizado». En Ethereum, un bloque se considera finalizado cuando dos tercios de la participación total votan a favor de incluirlo y se construye otro bloque sobre él. Como la finalidad requiere que dos tercios de la participación total acuerden que un bloque es canónico, un atacante no puede crear una cadena finalizada alternativa sin poseer o manipular dos tercios de la participación total y destruir al menos un tercio mediante penalización. Casper permite que los nuevos participantes se sincronicen con la cadena canónica con confianza. 

LMD-GHOST es el acrónimo de «Latest Message-Driven Greedy Heaviest Observed Sub-Tree». Es un algoritmo que decide qué bifurcación de Ethereum seguir. Para ello, elige la bifurcación que haya recibido más apoyo (es decir, «peso») de los validadores de la red, de ahí el término «greedy heaviest sub-tree». Luego, garantiza que solo se considere el mensaje más reciente de cada validador. Cada vez que se propone un nuevo bloque en Ethereum, los validadores usan esta regla para decidir si debe formar parte de la cadena canónica.

En comparación, Solana usa hashes de prueba de historia (PoH) para alcanzar el consenso. A pesar de su nombre confuso, PoH no es un algoritmo de consenso. Es una forma de demostrar el paso del tiempo en una red hostil. Más concretamente, es una función criptográfica de sellado de tiempo que permite a los nodos acordar un orden de eventos sin comunicarse entre sí. El líder (es decir, el validador que agrega entradas al libro mayor) asigna marcas de tiempo a los bloques para demostrar que ha transcurrido cierto tiempo desde el último bloque. 

Agregar estas marcas de tiempo establece un registro histórico, ya que demuestra que los datos existían en un momento específico. Se crea un registro histórico mediante una función hash secuencial resistente a preimágenes, en la que cada hash depende de su predecesor. Las funciones de retardo verificable (VDF) son fundamentales para generar estos hashes. Garantizan que cada hash se base en el anterior e incorpore el tiempo transcurrido desde entonces. La integración de las VDF añade una dimensión temporal al proceso de hashing, lo que permite crear en Solana una secuencia verificable de eventos con marcas de tiempo.

Después de explicar cómo el mecanismo de prueba de historia de Solana crea una secuencia confiable de eventos mediante marcas de tiempo criptográficas, es importante entender cómo se integra con Tower BFT, el mecanismo de consenso de Solana. Tower Byzantine Fault Tolerance (BFT) es la variante de Solana del modelo tradicional de consenso de tolerancia a fallas bizantinas, optimizada para PoH. Tower BFT usa como marco de referencia el registro histórico creado por PoH. Este marco permite a los validadores votar de forma eficiente y precisa sobre el estado del libro mayor. Tower BFT hace que los validadores emitan votos que quedan bloqueados durante mucho tiempo y cuyo compromiso aumenta a medida que se agregan más votos. Gracias a PoH, los validadores pueden tomar decisiones más rápidas e informadas sobre el estado del libro mayor sin tener que comunicarse entre sí. La combinación de PoH y Tower BFT acelera el consenso y mejora la seguridad y confiabilidad de la red. El resultado es un entorno blockchain escalable y de alto rendimiento, donde las transacciones se confirman rápidamente.

Procesamiento de transacciones y entornos de ejecución

La eficiencia y escalabilidad de una blockchain dependen principalmente de sus capacidades para procesar transacciones y de su entorno de ejecución. Estos factores determinan la velocidad de ejecución de las transacciones y la rentabilidad de las operaciones en la red. El enfoque de una blockchain para procesar transacciones y los matices de sus entornos de ejecución influyen considerablemente en la experiencia de desarrollo.

El entorno de ejecución de Ethereum funciona como una máquina de pila determinista y de un solo hilo, conocida como Ethereum Virtual Machine (EVM). Se comporta como una función matemática. Es decir, la EVM produce un resultado determinista cuando recibe una entrada. Resulta útil definir Ethereum como una función de transición de estado: f(S, T) = S’. A partir de un estado anterior (S) y un nuevo conjunto de transacciones válidas (T), la EVM produce un nuevo estado de salida válido (S’). La EVM siempre alcanzará el mismo estado final si recibe el mismo conjunto de transacciones. Esto es esencial para mantener la coherencia entre los nodos de la red.

La EVM procesa las transacciones de forma secuencial. El procesamiento secuencial garantiza que cada transacción se ejecute en un entorno que refleje con precisión el estado de la red hasta ese momento. La ejecución secuencial permite calcular con exactitud los cambios de estado y los costos de gas. Esta previsibilidad brinda a desarrolladores y usuarios una comprensión clara de los resultados y costos de las transacciones.

Ethereum simplifica el entorno de ejecución de contratos inteligentes al adoptar un modelo de ejecución de un solo hilo. Esto ofrece a los desarrolladores la ventaja de contar con cambios de estado predecibles, ya que cada transacción se procesa de forma secuencial. Podría decirse que los cambios de estado predecibles hacen que el entorno de desarrollo de Ethereum sea más accesible para los nuevos desarrolladores, pues pueden concentrarse más en la lógica de sus contratos inteligentes que en las complejidades de la ejecución. Sin embargo, esta simplicidad dificulta la escalabilidad. El procesamiento secuencial limita el rendimiento de la red. Esto puede provocar congestión, tiempos de espera más largos para las transacciones y comisiones de gas más altas durante periodos de alta demanda. Como cada transacción consume gas, los desarrolladores deben optimizar la eficiencia del gas. Esta optimización mejora la experiencia general del usuario y combate los periodos de congestión, durante los cuales un código ineficiente puede hacer que las aplicaciones sean inutilizables para el usuario promedio.

Los desarrolladores de Solana no tienen que preocuparse por optimizar el uso de gas como los desarrolladores de Ethereum. Solana está diseñada como una máquina de estado de alto rendimiento y baja latencia conocida como Solana Virtual Machine (SVM). Un componente esencial de la SVM es Sealevel. Es un motor de ejecución que procesa transacciones en paralelo. En Solana, cada transacción indica al entorno de ejecución qué partes del estado leerá o escribirá al ejecutarse. El entorno de ejecución procesa en paralelo las transacciones que no entran en conflicto y las que leen el mismo estado. Sealevel optimiza la ejecución de contratos inteligentes al distribuir la carga de trabajo de las transacciones entre varios hilos del hardware de un validador. Así, mientras el validador procesa una transacción en un núcleo, puede procesar otra simultáneamente en otro.

El paralelismo intrínseco de Solana reduce considerablemente los costos de las transacciones. Las transacciones de Solana tienen dos comisiones: una comisión base y una comisión de prioridad. La comisión base es fija por firma y equivale a 5000 lamports; la mayoría de las transacciones solo tienen una firma. La comisión de prioridad es opcional y permite que las transacciones se prioricen frente a otras. El planificador prioriza de forma no determinista las transacciones con una comisión de prioridad más alta. Las comisiones por transacción suelen ser inferiores a $0.001 USD, y la comisión promedio de las transacciones sin voto se encuentra en el rango de 0.000005 a 0.00007 SOL. El límite superior es más alto de lo habitual debido al reciente aumento en el uso de comisiones de prioridad. Con el precio actual de SOL de ~$98.96, esta comisión equivale aproximadamente a entre $0.000494 y $0.006968 USD. 

Estas comisiones también son predecibles. Solana usa mercados de comisiones localizados para gestionar la demanda. El espacio de bloques está estructurado para evitar que un foco específico de actividad (por ejemplo, la acuñación de un NFT muy esperado) monopolice el espacio de bloques y aumente las comisiones en toda la red. Solo aumentarán las comisiones de las transacciones que intenten acceder a un foco específico con alta demanda. Los mercados de comisiones localizados permiten usar comisiones de prioridad sin provocar guerras de gas generalizadas. Este enfoque localizado difiere del de las redes basadas en gas, como Ethereum, donde las transacciones se procesan de forma secuencial y la congestión global produce comisiones volátiles.

Ethereum es un entorno de ejecución de un solo hilo que procesa solo un contrato a la vez. Actualmente, no aprovecha el hardware moderno con varios núcleos, por lo que el hardware de los validadores está subutilizado. El objetivo de mantener requisitos de hardware bajos para los nodos agrava las limitaciones de Ethereum para procesar transacciones. En comparación, las capacidades de procesamiento paralelo de Solana le permiten procesar más transacciones mediante el uso de todos los núcleos disponibles de un validador. Junto con los mercados de comisiones localizados, esto convierte a Solana en una máquina de estado global con un rendimiento mucho mayor. 

Lenguajes para contratos inteligentes

El lenguaje principal para desarrollar contratos inteligentes en Ethereum es Solidity. Es un lenguaje de tipado estático y llaves, diseñado para crear contratos inteligentes que se ejecutan en la EVM. Está muy influenciado por JavaScript, C++ y Python, por lo que los desarrolladores familiarizados con estos lenguajes pueden aprenderlo con facilidad.

Yul es un lenguaje intermedio de bajo nivel optimizado para blockchains compatibles con EVM. Yul ofrece a los desarrolladores mayor control sobre la ejecución del bytecode, por lo que resulta muy eficiente para ajustar el consumo de gas y gestionar otras operaciones de bajo nivel. Los desarrolladores pueden crear contratos más eficientes al programar directamente en Yul o usarlo como destino de compilación.

Vyper es un popular lenguaje similar a Python que prioriza la simplicidad y la seguridad. Tiene deliberadamente menos funciones que Solidity, pues busca reducir la complejidad y las posibles vulnerabilidades de seguridad. La filosofía de diseño de Vyper prioriza ante todo la legibilidad y la facilidad de auditoría. Este enfoque ha inspirado el desarrollo de lenguajes similares, como Fe, y de lenguajes que se compilan a Vyper, como Dasy.

Rust es la lingua franca para desarrollar contratos inteligentes (conocidos coloquialmente como programas) en Solana. Es un lenguaje rápido y eficiente en el uso de memoria, con un rendimiento comparable al de C++. Estas características lo hacen adecuado para desarrollar aplicaciones destinadas a una red de alto rendimiento y baja latencia. El completo sistema de tipos y el modelo de propiedad de Rust garantizan la seguridad de la memoria y de los hilos, lo que obliga a los desarrolladores a crear aplicaciones confiables y seguras. 

Aunque Rust presenta una curva de aprendizaje pronunciada para quienes no conocen la programación de sistemas, la ventaja es que permite crear código sólido y eficiente. La mayor parte del desarrollo en Rust se realiza con Anchor. Anchor es un framework con convenciones definidas que simplifica el desarrollo de programas al reducir el código repetitivo, realizar varias comprobaciones de seguridad estándar y agilizar el proceso de (des)serialización. Por eso, no es tan importante tener conocimientos avanzados de Rust para comenzar. Como referencia, la documentación de Anchor recomienda que los usuarios conozcan los primeros nueve capítulos del libro de Rust (es decir, los fundamentos de Rust). Solana Playground incluye varios tutoriales de Anchor para ayudarte a comenzar.

Aunque Rust es la opción preferida, los desarrolladores no están limitados a este lenguaje. Se puede usar C, C++ y cualquier lenguaje compatible con el backend BPF de LLVM (es decir, cualquier lenguaje que pueda compilarse como bytecode BPF). Para quienes conocen lenguajes similares a Python, como Vyper, Seahorse Lang permite escribir programas en Python. Así, los desarrolladores obtienen la facilidad de uso de Python y conservan las mismas garantías de seguridad que si programaran en Rust. Hay varios tutoriales útiles de Seahorse, como Seahorse University y Seahorse Cookbook, para que comiences hoy mismo a programar en Solana.

Los desarrolladores que migran de Ethereum a Rust no están obligados a usar solo Rust. Aunque se recomienda aprender y usar frameworks como Anchor y Seahorse debido a su popularidad y sus garantías de seguridad, no siempre es viable. Gracias a los avances recientes de Solang y Neon Labs con su compilador y entorno de desarrollo compatible con EVM, los desarrolladores pueden usar Solidity para desarrollar programas. Solidity tiene cabida en Solana. Para comenzar a desarrollar programas con Solidity, debemos analizar con mayor detalle los matices del modelo de programación de Solana. Comprender el modelo de cuentas de Solana es esencial para los desarrolladores que realizan esta transición, ya que constituye la base para desarrollar programas e interactuar con la red.

Comprender el modelo de cuentas

Ethereum divide las cuentas en dos categorías principales: cuentas de propiedad externa (EOA) y cuentas de contrato. Las EOA son el tipo de cuenta estándar para los usuarios. Están controladas por claves privadas y pueden mantener saldos de Ether, enviar transacciones e interactuar con cuentas de contrato. Por otro lado, las cuentas de contrato se distinguen porque sus operaciones se rigen por el código del contrato inteligente que contienen. No pueden iniciar transacciones de manera autónoma y solo pueden actuar en respuesta a transacciones recibidas de EOA u otras cuentas de contrato.

Solana adopta un modelo de cuentas más uniforme y las trata como contenedores versátiles que almacenan datos de forma persistente. Este modelo permite que cualquier cuenta sea un programa, lo que difumina el límite tradicional entre una cuenta y un contrato inteligente. A diferencia de Ethereum, donde el código y el estado se combinan en una sola cuenta, los programas de Solana no tienen estado. Esto significa que no almacenan ningún estado internamente. En cambio, todos los datos que necesitan para operar se guardan en una cuenta independiente y se pasan por referencia mediante una transacción. Pasar cuentas por referencia permite implementar una sola vez un programa genérico capaz de interactuar con distintas cuentas. El modelo de cuentas de Solana separa el código y los datos, lo que favorece un entorno de desarrollo más eficiente y modular. Esto beneficia a los usuarios que quieren interactuar con varios protocolos sin mover activos entre diferentes programas. Todo en Solana es una cuenta. 

Las cuentas de Solana pueden clasificarse, en términos generales, como ejecutables y no ejecutables. En pocas palabras, las cuentas ejecutables pueden ejecutar código. Las cuentas no ejecutables se usan para almacenar datos y no pueden ejecutar código. Esto se debe a que no almacenan código.

Las cuentas ejecutables son cuentas que contienen programas. Los programas pueden poseer cuentas adicionales, leer otras cuentas o añadirles fondos, modificar datos o retirar fondos de las cuentas que poseen. Las cuentas ejecutables pueden dividirse a su vez en programas on-chain o nativos. Los programas on-chain son código escrito por usuarios e implementado en la red. Su autoridad de actualización, que suele ser la cuenta que los implementó, puede actualizarlos. Los programas nativos son un subconjunto especial de cuentas ejecutables, similares a los contratos precompilados de Ethereum, pero con funciones más amplias. Estos programas están integrados en el núcleo de Solana y ofrecen las funciones necesarias para que operen los validadores. Un ejemplo de programa nativo es el System Program. Este programa se encarga de crear cuentas nuevas, asignar espacio para los datos de las cuentas, asignar cuentas a programas, transferir lamports desde las cuentas que posee y pagar las comisiones por transacción. Puedes consultar una lista completa de programas nativos aquí.

Sin importar si son ejecutables o no ejecutables, todas las cuentas tienen los mismos campos: 

  • Un campo de lamports para registrar el saldo nativo de una cuenta en SOL
  • Un campo de datos, que corresponde al arreglo de bytes de datos sin procesar almacenado por la cuenta
  • Un campo de propietario que indica el programa que puede modificar esta cuenta
  • Un campo de firmante, usado en las transacciones para indicar si la cuenta puede aprobarlas
  • Un campo de escritura para especificar si se pueden modificar los datos de una cuenta. Esto facilita el procesamiento paralelo al marcar las cuentas incluidas en las transacciones como de solo lectura o de escritura
  • Un campo ejecutable para indicar si una cuenta almacena un programa
  • Un campo de época de renta para indicar la próxima época en la que la cuenta debe pagar renta

La renta es un costo de almacenamiento que mantiene activas las cuentas en Solana y garantiza que permanezcan en la memoria de los validadores. Esto exige que las cuentas mantengan un saldo mínimo para seguir activas. La renta reduce la acumulación de estado al garantizar que la red recupere con el tiempo las cuentas sin uso o con fondos insuficientes. Las actualizaciones recientes hicieron que ya no haya cuentas que paguen renta en la red principal. En cambio, todas las cuentas deben estar exentas de renta al crearse. Una cuenta está exenta de renta si mantiene un saldo mínimo equivalente a dos años de pagos de renta. Puedes usar herramientas como Test Drive y el subcomando de renta de Solana CLI para calcular la cantidad de SOL necesaria para que una cuenta quede exenta de renta. Esto difiere del sistema de asignación de recursos de Ethereum, donde el almacenamiento persiste a menos que se borre explícitamente. El enfoque de Solana ofrece una estructura de costos más predecible para almacenar el estado y, al mismo tiempo, reduce su acumulación.

Direcciones y direcciones derivadas de programas (PDA)

Cada cuenta se identifica mediante su dirección, una clave pública única de 32 bytes. Esto difiere del modelo de datos de Ethereum, donde las direcciones tienen 20 bytes. Solana usa ed25519 (es decir, un esquema de firma EdDSA que usa SHA-512 y la curva elíptica Curve22519) para generar direcciones. Una cuenta debe ser un punto de la curva ed25519 para tener un par de claves válido. 

Las direcciones derivadas de programas (PDA) son cuentas generadas fuera de la curva mediante un bump (es decir, un valor que desplaza el resultado fuera de la curva). Las PDA requieren tres componentes principales: la dirección de su programa principal, un conjunto de seeds y un bump. Las seeds son un arreglo de cadenas que pueden tener valores arbitrarios. Sin embargo, la mayoría de los desarrolladores crean seeds específicas relacionadas con las variables de estado del programa principal para crear estructuras de datos similares a hashmaps. Por lo tanto, una PDA se crea aplicando la función hash SHA-512 al ID del programa, las seeds y el bump.

El objetivo de que las PDA estén fuera de la curva es garantizar que solo el programa del que se deriva una PDA pueda firmar en su nombre. Esto agiliza el flujo de transacciones al generar sus firmas mediante programación, de modo que las dApps sin confianza puedan operar con fluidez y sin intervención.

Interactuar con una cuenta

Una transacción de Ethereum es una acción que cambia el estado y que inicia una EOA. Los contratos inteligentes no pueden iniciar transacciones por sí solos; solo pueden reaccionar ante ellas. El código del contrato determina estas reacciones y el costo de ejecutar la transacción se mide en gas. Los usuarios deben proporcionar suficiente Ether para cubrir esta comisión de gas.

Por lo general, las transacciones de Ethereum realizan una sola operación, como llamar a una función específica de un contrato inteligente. Aunque una sola transacción puede producir varios cambios de estado dentro de un contrato, todos se limitan al alcance de esa única llamada al contrato.

En Solana, una transacción incluye un arreglo de cuentas para leer o escribir, una o más firmas y una o más instrucciones. Una instrucción es una directiva para una sola invocación de un programa. Es la unidad más pequeña de lógica de ejecución y la unidad operativa más fundamental. Las instrucciones especifican el programa que se ejecutará, todas las cuentas involucradas y los datos operativos. Los programas interpretan los datos de una instrucción y operan sobre las cuentas especificadas. Esta estructura permite que una sola transacción realice de forma atómica una serie de acciones en varios programas. Esto significa que todas las instrucciones se completan correctamente o fallan en conjunto. El flujo de transacciones de Solana difiere del modelo de Ethereum, donde una transacción suele estar vinculada a un solo contrato inteligente o a una acción de una EOA.

Las invocaciones entre programas (CPI) permiten que un programa invoque a otro durante la misma transacción. La cantidad de bytes de datos de cuentas que se cobra por unidad de cómputo durante una CPI es de 250. Esto equivale aproximadamente a 50 MB con 200,000 unidades. Las CPI permiten usar firmas generadas mediante programación al realizar llamadas entre programas. Esto es similar a cuando un contrato inteligente de Ethereum llama a otro contrato de forma eficiente y atómica. Sin embargo, el programa que realiza la invocación se detiene hasta que el programa invocado termina de procesar la instrucción. La reentrada está limitada a la autorrecursión directa con una profundidad máxima fija de 4. Esto evita situaciones en las que un programa invoque a otro desde un estado intermedio sin saber que más adelante podrían volver a llamarlo.

Las transacciones de Solana respetan un límite de tamaño para mantener la eficiencia, similar al límite de gas de Ethereum. Sin embargo, el enfoque se centra en el tamaño de los datos. Las transacciones de Solana cumplen los estándares de unidad máxima de transmisión (MTU) de IPv6 para garantizar una transmisión de datos confiable. Después de reservar el espacio necesario para el encabezado, quedan 1232 bytes disponibles para los datos del paquete. Solana introdujo las transacciones con versiones para admitir varios formatos de transacción y superar las restricciones de tamaño. Además del formato heredado (es decir, el formato de transacción original), se lanzó la versión 0 para admitir las tablas de búsqueda de direcciones (ALT). Las ALT almacenan direcciones on-chain en una estructura de datos similar a una tabla, donde cada dirección se indexa mediante un índice u8 de 1 byte. Esto reduce considerablemente el tamaño de las transacciones, ya que cada cuenta solo necesita 1 byte en lugar de 32 bytes.

Solang

Solang es un compilador de Solidity para Solana y Polkadot. Busca lograr compatibilidad de archivos fuente con la versión 0.8 del compilador de Solidity de EVM, aunque con algunas variaciones para adaptarse a las arquitecturas de Solana y Polkadot. Un aspecto importante de Solang es que utiliza LLVM, una potente infraestructura de compilación. La flexibilidad de LLVM permite que Solang admita otros lenguajes de programación en el futuro, lo que facilita las implementaciones y compilaciones. Esta característica coincide con el objetivo de Solang de facilitar la transición de los desarrolladores a Solana o Polkadot y ampliar el alcance del desarrollo con Solidity. Solang está en desarrollo continuo y se centra en mejorar la compatibilidad, la eficiencia y la facilidad de uso. Es fundamental que los desarrolladores de Ethereum que quieran llevar sus habilidades a otras cadenas comprendan Solang y sus particularidades.

Instalación

Hay varias formas de instalar Solang. En Mac, puedes descargar Solang con Brew mediante un tap privado:

Código
brew install hyperledger/solang/solang

Otra forma de instalar Solang es usar los contenedores de Solang. Es ideal si prefieres usar Docker, ya que las imágenes nuevas se publican automáticamente en estos contenedores. Hay una etiqueta v.0.3.3 y una etiqueta latest:

Código
docker pull ghcr.io/hyperledger/solang:latest

Una de las formas más sencillas de instalar y usar Solang es mediante Ancor. Para comenzar, asegúrate de tener Rust y Node.js instalados en tu sistema. Si usas Windows, también tendrás que configurar el Subsistema de Windows para Linux. Ahora debes instalar el conjunto de herramientas de Solana. En Mac y Linux, puedes hacerlo con el siguiente comando:

Código
 sh -c "$(curl -sSfL https://release.solana.com/v1.17.13/install)"

Si prefieres otra versión del software, reemplaza “v1.17.13” por la etiqueta de versión correspondiente. También puedes usar uno de estos nombres de canal simbólicos: stable, beta o edge. Según tu sistema, quizás debas actualizar la variable de entorno PATH. Si encuentras este mensaje, copia y pega el comando recomendado a continuación para actualizar PATH. Puedes confirmar la versión deseada de solana ejecutando solana --version.

En Windows, abre una instancia del Símbolo del sistema como administrador. Copia y pega el siguiente comando para descargar el instalador de Solana en un directorio temporal:

Código
cmd /c "curl https://release.solana.com/v1.17.13/solana-install-init-x86_64-pc-windows-msvc.exe --output C:\solana-install-tmp\solana-install-init.exe --create-dirs"

Luego, copia y pega el siguiente comando para instalar la versión más reciente de Solana: C:\solana-install-tmp\solana-install-init.exe v1.17.13. Cuando termine la instalación, presiona Enter.

Cierra la ventana del Símbolo del sistema y abre una nueva instancia como usuario normal. Confirma que la versión deseada de solana esté instalada ejecutando solana –-version.

A continuación, instala Anchor.

Se recomienda instalar Anchor mediante el administrador de versiones de Anchor (avm). Puedes hacerlo a través de cargo con el comando:

Código
cargo install -git https://github.com/coral-xyz/anchor avm --locked --force.

Luego, instala y usa la versión más reciente:

Código
avm install latest
avm use latest

# Verify the installation
avm –version

Anchor 0.28 permite que los desarrolladores compilen directamente con Solang. Puedes crear un nuevo proyecto de Solang con el comando: anchor init project_name —solidity. Esto crea un nuevo programa de Solang y un archivo de prueba que muestra cómo interactuar con el programa mediante el cliente.

Si usas Visual Studio Code, considera instalar la extensión de Solang para facilitar el resaltado de sintaxis. Desactiva cualquier otra extensión de Solidity activa para asegurar que la extensión de Solang funcione correctamente.

Crear un proyecto nuevo

Crea un proyecto nuevo con el comando anchor-init project_name –solidity. Esto crea un directorio nuevo con el nombre de tu proyecto. La marca de Solidity le indica a Anchor que queremos usar Solang. El directorio ./solidity del proyecto incluirá un programa inicial. El contrato tendrá este aspecto:

Código
@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC")
contract test {
    bool private value = true;

    @payer(payer)
    constructor() {
        print("Hello, World!");
    }

    /// A message that can be called on instantiated contracts.
    /// This one flips the value of the stored `bool` from `true`
    /// to `false` and vice versa.
    function flip() public {
            value = !value;
    }

    /// Simply returns the current value of our `bool`.
    function get() public view returns (bool) {
            return value;
    }
}

Este programa tiene un constructor para crear el programa, inicializar la variable de estado value en true y registrar “Hello, World!” en los registros del programa. La función flip actualiza la variable de estado cuando se invoca. La función get devuelve el valor actual de la variable de estado. Esto parece un contrato inteligente normal de Solidity, aunque tiene algunas particularidades. La diferencia más importante es el uso de anotaciones.

Anotaciones

Las anotaciones se usan para administrar cuentas. Observa la anotación @program_id(“...”). Se utiliza para especificar la dirección on-chain del programa si se conoce de antemano. Si quieres invocar un contrato mediante una llamada externa, el programa debe tener la notación @program_id o invocarse mediante el argumento {program_id: … }:

Código
@program_id(“...”);

contract Foo {
	function hello() public pure {
		print(“Hello”);
	}
}

contract Foo2 {
	function bye() public pure {
		print(“Bye”);
	}
}

contract Bar {
	function new_foo() external {
		Foo.new();
	}
}

contract Bar2 {
	function new_foo(address new_foo_id) external {
		Foo2.new{program_id: new_foo_id}();
	}
}

Cuando creamos un proyecto nuevo, el contrato de ejemplo incluido tenía la anotación @payer sobre el constructor. Esta anotación define la cuenta que pagará la inicialización de la cuenta de datos del programa. La sintaxis @payer(payer) declara una cuenta llamada payer, que será necesaria en cada llamada al constructor.

Cuando se instancia un contrato, se necesita una cuenta de programa para almacenar el código ejecutable y una cuenta de datos para guardar las variables de estado. La cuenta de datos puede crearse mediante código del cliente y luego incluirse en la transacción que invoca el constructor. También puede crearla el constructor. Como mínimo, debe proporcionarse la anotación @payer. Si la cuenta de datos será una PDA, debes proporcionar una semilla y un bump. La anotación @seed especifica una semilla para derivar la PDA y puede ser un literal de cadena o una cadena hexadecimal con el formato hex”1234”. Si aparece antes de un argumento, la anotación de semilla debe hacer referencia a un argumento de tipo bytes, address o a un arreglo de bytes de longitud fija. La anotación @bump especifica el valor utilizado para producir una dirección fuera de la curva. Debe ser un solo byte de tipo bytes1. La anotación opcional @space permite especificar el tamaño de la cuenta de datos. Es una expresión uint64 que puede ser una constante o usar uno de los argumentos del constructor. Según la documentación de Solang, como mínimo, @space debe ser el tamaño indicado al ejecutar el comando solang -v:

Código
$ solang compile --target solana -v examples/solana/flipper.sol
...
info: contract flipper uses at least 17 bytes account data
…

Si un programa no tiene constructor, estas anotaciones pueden combinarse con un constructor vacío. La documentación de Solang ofrece el siguiente ejemplo:

Código
@program_id("Foo5mMfYo5RhRcWa4NZ2bwFn4Kdhe8rNK5jchxsKrivA")
contract Foo {

    @space(500 + 12)
    @seed("Foo")
    @payer(payer)
    constructor(@seed bytes seed_val, @bump bytes1 bump_val) {
        // ...
    }
}

Las anotaciones de función se usan para declarar las cuentas necesarias para las funciones externas:

  • @account(foo) declara la cuenta foo como una cuenta de solo lectura
  • @mutableAccount(bar) declara la cuenta bar como una cuenta mutable
  • @signer(fizz) declara la cuenta fizz como un firmante de solo lectura
  • @mutableSigner(buzz) declara la cuenta buzz como un firmante mutable

Puedes acceder dentro del constructor a las cuentas declaradas en él con la anotación @payer. Las cuentas declaradas con anotaciones de función están disponibles en el vector tx.accounts. Por ejemplo, usarías tx.accounts.ichigo para acceder a la cuenta declarada @account(ichigo). Esto devuelve la estructura integrada AccountInfo. Esta estructura sigue la misma organización que describimos en la sección “Comprender el modelo de cuentas”. Los nombres son un poco diferentes:

  • key: la dirección o clave pública de la cuenta. Es de tipo address
  • lamports: el saldo en lamports de la cuenta. Es de tipo uint64
  • data: los datos de la cuenta. Son de tipo bytes
  • owner: el propietario de la cuenta. Es de tipo address
  • rent_epoch: la siguiente época en la que vence el alquiler de la cuenta. Es de tipo uint64
  • is_signer: especifica si la cuenta firmó la transacción. Es de tipo bool
  • is_writable: especifica si se puede escribir en la cuenta durante esta transacción. Es de tipo bool
  • executable: especifica si la cuenta es un programa. Es de tipo bool

Limitaciones

Las principales incompatibilidades entre Solang y el desarrollo tradicional en Ethereum son:

  • msg.sender no está disponible en Solana. Con el modelo de cuentas, un contrato de Rust puede acceder a varias cuentas de datos, pero ¿cuál de ellas consideraríamos como la que realiza la llamada? En muchos casos no podemos identificar una sola cuenta como la que realiza la llamada. Además, el entorno de ejecución no tiene un mecanismo para obtener las cuentas que realizan llamadas
  • No existe una función ecrecover(), pero sí una función signatureVerify() para verificar firmas ed25519.
  • Las sentencias try-catch no funcionan. El entorno de ejecución detendrá la ejecución y revertirá toda la transacción si falla cualquier llamada externa o creación de contrato.
  • Las definiciones de errores y las reversiones con mensajes de error todavía no funcionan
  • La transferencia de valor nativo mediante una llamada a una función no funciona.
  • Muchas funciones integradas de Yul no están disponibles. Solang admite la mayoría de las funciones integradas, pero las operaciones de memoria y cadena no están implementadas.
  • El formato ERC-20 no es compatible actualmente. Los tokens SPL se definen según el Token Program. Token Program es la forma nativa de Solana de crear, acuñar, transferir y quemar tokens. Debes copiar el archivo spl_token.sol en tu árbol de código fuente e importarlo donde sea necesario para usar la biblioteca SplToken

Además, los registros de SVM tienen 64 bits de ancho, por lo que es preferible usar enteros de 64 bits (es decir, uint64 e int64) en lugar de enteros de 256 bits. Una operación con tipos de más de 64 bits, como uint256 o int256, se divide en varias operaciones. Esto las hace más lentas y consume más unidades de cómputo.

En cuanto a las direcciones, debes especificar un literal de dirección mediante la sintaxis address"36VtvSbE6jVGGQytYWSaDPG7uZphaxEjpJHUUpuUbq4D". La sintaxis hexadecimal de Ethereum (por ejemplo, 0xE0f5206BBD039e7b0592d8918820024e2a7437b9) no es compatible. Todos los saldos y valores en Solana tienen 64 bits de ancho. Esto significa que las funciones integradas para direcciones (es decir, .balance(), .transfer() e .send()) usan enteros de 64 bits.

Aunque Solang ofrece una vía interesante para que los desarrolladores de EVM se adentren en el ecosistema de Solana, tiene varias limitaciones que deben considerarse con cuidado. El cambio al modelo basado en cuentas de Solana no es meramente sintáctico: representa un cambio fundamental en la lógica de los contratos inteligentes. Ciertas funciones, patrones de programación y características específicas de EVM no están disponibles con Solang. Los desarrolladores no pueden migrar un contrato inteligente de Ethereum a Solang y esperar que funcione sin ajustes importantes. Las funciones faltantes, como la ausencia de definiciones de errores adecuadas y reversiones con mensajes de error, pueden ser muy perjudiciales. Sin embargo, es importante reconocer que Solang es una herramienta en evolución constante y que cada actualización busca mejorar la experiencia de los desarrolladores de Solidity en Solana. Solang ofrece varias ventajas específicas para mejorar esta experiencia.

Ventajas

A pesar de estas limitaciones, hay varias funciones integradas y decisiones de diseño que mejoran la experiencia de desarrollo. Por ejemplo, los contratos desarrollados en Solang pueden interactuar con programas de Anchor. Para hacerlo, puedes generar una interfaz de Solidity a partir del IDL de un programa de Anchor. IDL significa “lenguaje de descripción de interfaces”. En esencia, es un archivo JSON que contiene todas las especificaciones de un programa. Incluye todo lo necesario para interactuar con un programa de Anchor. Anchor genera automáticamente un IDL cuando desarrollas un programa con su framework. Es muy similar a las ABI de Ethereum. Para generar una interfaz de Solidity a partir de un IDL, usa el siguiente comando: solang idl [-output directory] [IDL file]. Ahora puedes importar el archivo con la sintaxis import “...”;.

Solang proporciona la biblioteca de Solana, un conjunto de bibliotecas que permite a los contratos de Solidity interactuar con instrucciones específicas de Solana. Solang proporciona la biblioteca SPL Token para acuñar, quemar y transferir tokens. Puede considerarse un equivalente de ERC-20 y ERC-721. Solang también proporciona la biblioteca System Instructions para que los desarrolladores puedan interactuar con System Program de Solana.

Solang también incluye funciones integradas que pueden importarse con solana. Entre ellas se encuentran las estructuras AccountMeta e AccountInfo. La estructura AccountMeta se usa para especificar qué cuentas deben enviarse al destinatario de una llamada externa (es decir, una CPI). La estructura AccountMeta tiene la siguiente organización:

  • pubkey: la dirección o clave pública de la cuenta. Es de tipo address
  • is_writable: especifica si el destinatario de la llamada puede escribir en esta cuenta. Es de tipo bool
  • is_signer: especifica si el destinatario de la llamada puede asumir que esta cuenta firmó la transacción. Es de tipo bool

Si se omite el argumento accounts en una llamada externa, el compilador de Solang genera automáticamente un arreglo AccountMeta. Esto solo funciona si la función se declara como externa. De lo contrario, debes crear manualmente el arreglo AccountMeta según el orden de las cuentas especificado en el IDL. Si una llamada determinada no necesita cuentas, pasa un vector vacío: {accounts: []}. La documentación de Solang ofrece un buen ejemplo de cómo crear el arreglo AccountMetas:

Código
function build_this() external {
	// When calling a constructor from an external function, the data account for the contract
	// 'BeingBuilt' should be passed as the 'BeingBuilt_dataAccount' in the client code.
	BeingBuilt.new("my_seed");
}

function build_that(address data_account, address payer_account) public {
	AccountMeta[3] metas = [
		AccountMeta({
			pubkey: data_account,
      is_signer: true,
      is_writable: true
		}),
    AccountMeta({
    	pubkey: payer_account,
      is_signer: true,
      is_writable: true
    }),
    AccountMeta({
      pubkey: address"11111111111111111111111111111111",
      is_writable: false,
      is_signer: false
    })
  ];
  BeingBuilt.new{accounts: metas}("my_seed");

	// No accounts are needed in this call, so we pass an empty vector.
	BeingBuilt.say_this{accounts: []}("It's summertime!");
}

Solang también tiene funciones integradas para:

Solang acorta la distancia entre Solana y Ethereum mediante un compilador con un amplio conjunto de herramientas que facilita la transición de los desarrolladores de EVM. A pesar de sus limitaciones, Solang ofrece varias funciones para mejorar la experiencia de desarrollo, como la capacidad de interactuar con programas de Anchor, acceder a bibliotecas específicas de Solana y usar funciones integradas. La integración de conceptos conocidos, como los IDL y los estándares de tokens, facilita aún más el aprendizaje. No tener que preocuparse por el gas ni optimizarlo también es una ventaja bienvenida. Solang representa un paso importante hacia la interoperabilidad entre Solana y Ethereum. Para los desarrolladores de EVM que buscan ingresar al mundo de alto rendimiento de Solana, Solang se presenta como una herramienta posible.

Neon EVM

Solang no es la única opción para los desarrolladores de Solidity que quieren desarrollar en Solana. Neon EVM se describe como la primera EVM paralelizable del mundo. Es un entorno de Ethereum totalmente compatible en Solana. Es una solución sinérgica para quienes buscan escalar dApps de Ethereum en Solana de una manera accesible para los desarrolladores. Puedes implementar tus dApps sin reconfigurar sus contratos inteligentes, escritos en los lenguajes que prefieres y con las herramientas que ya usas.

Arquitectura

Neon EVM consta de tres componentes principales: el programa Neon EVM, Neon Proxy y Neon DAO.

Neon EVM es un programa de Solana que acepta transacciones similares a las de Ethereum y las procesa en Solana según las reglas de EVM. Estas transacciones similares a las de Ethereum dirigidas a Neon EVM se denominan Neon Transactions. Son un subconjunto de métodos JSON RPC conforme a la API JSON-RPC de Ethereum.

Neon Proxy permite que los desarrolladores de Ethereum migren sus dApps a Neon con cambios mínimos. Empaqueta transacciones de EVM en transacciones de Solana y funciona como una solución en contenedores para los Neon Operators. Estos operadores ejecutan servidores de Neon Proxy, aceptan pagos en NEON y realizan pagos dentro del ecosistema de Solana en SOL. NEON es un token de utilidad y gobernanza: los Neon Operators lo reciben para pagar las tarifas de gas necesarias para ejecutar transacciones, y sus propietarios pueden participar en Neon DAO.

Neon DAO es un modelo de gobernanza impulsado por la comunidad y diseñado para dar a los titulares de tokens NEON poder de decisión sobre Neon EVM. Está compuesto por usuarios, operadores, colaboradores y desarrolladores principales y de aplicaciones que deliberan en conjunto sobre las reglas de gobernanza y la evolución del protocolo. La DAO funciona mediante varias asambleas descentralizadas centradas en el ecosistema, el desarrollo y la seguridad. Cada asamblea facilita la toma colaborativa de decisiones y la evaluación de propuestas en su área respectiva. La asamblea centrada en el ecosistema supervisa su crecimiento sostenible y administra fondos para subvenciones e iniciativas. La asamblea centrada en el desarrollo gestiona las actualizaciones técnicas del programa Neon y las intervenciones de emergencia. La asamblea centrada en la seguridad protege la tesorería de Neon y el programa Neon frente a posibles amenazas.

Compatibilidad con EVM

Neon EVM facilita las interacciones con EVM en Solana al:

  • Implementar la mayoría de los métodos de la API JSON-RPC de Ethereum
  • Usar un proxy especial para gestionar llamadas de Ethereum
  • Adaptarse a las diferencias y limitaciones de la arquitectura de Solana

Interactuar con Neon EVM es similar a interactuar con cualquier otra EVM. Puedes usar métodos conocidos de la API RPC dirigidos a Neon Proxy, lo que facilita una experiencia de desarrollo fluida. Entre sus características principales se incluyen:

  • Compatibilidad con contratos inteligentes de Solidity y Vyper, así como con herramientas estándar de desarrollo de Ethereum como Metamask, Foundry y Remix
  • Compatibilidad literal con la mayoría de los opcodes de Ethereum
  • Aceptación de solicitudes de transacciones de Ethereum tipo 0 o heredadas. Las transacciones EIP-1559 no son compatibles actualmente

Por supuesto, Neon EVM necesita ciertas adaptaciones para funcionar correctamente en Solana. Entre las diferencias más importantes se incluyen:

  • Neon EVM admite todos los contratos precompilados definidos en evm.code. Sin embargo, no se ejecutarán los contratos de Solidity que contengan las siguientes llamadas: bigModExp, bn256Add, bn256ScalarMult e bn256Pairing. Neon EVM necesita implementar llamadas del sistema de Solana para admitir estos contratos en el futuro
  • Aunque la mayoría de los opcodes son compatibles de forma literal, los opcodes COINBASE, PREVRANDAO (FKA DIFFICULTY), GASLIMIT, BASEFEE e GAS no lo son. Se conocen como opcodes variantes y están adaptados para usarse en Neon EVM.
  • El consumo de gas y el cálculo de tarifas difieren de Ethereum. Por lo general, generan costos más bajos debido a que Solana actúa como capa de liquidación
  • Los métodos transfer() e send() de Solidity no son seguros frente a la reentrada en Neon EVM debido a las diferencias en el cálculo del gas
  • El modelo de cuentas de Solana afecta el almacenamiento de contratos inteligentes mediante diferentes funciones de almacenamiento y permisos de acceso para cuentas ejecutables y no ejecutables
  • Neon EVM usa transacciones con versiones, lo que limita a 64 la cantidad máxima de cuentas utilizadas en una sola transacción
  • Neon EVM usa Berkeley Packet Filter (BPF) de Solana con un límite de memoria heap de 256 KB. Esto restringe el tamaño de las llamadas a contratos y exige estrategias de optimización para administrar eficazmente el uso de memoria
  • Las funciones basadas en tiempo, como block.number e block.timestamp, se comportan de forma diferente. Se recomienda enfáticamente no usarlas al desarrollar en Neon EVM

Aunque Neon EVM ofrece un entorno conocido y compatible, los desarrolladores de EVM deben conocer las diferencias clave y adaptarse a ellas para migrar y desarrollar con éxito en Solana.

Conectarse a un RPC de Neon

Puedes conectarte fácilmente a un RPC de Neon mediante Chainlist. Aquí puedes conectarte a Neon EVM Mainnet o Devnet. Haz clic en Conectar billetera en el modal de Mainnet o Devnet y, cuando aparezca tu billetera, haz clic en Aprobar.

Debes elegir el operador óptimo antes de enviar transacciones a Neon EVM. Expande los detalles de la tarjeta para ver los endpoints RPC disponibles para cada red:

Si eliges un operador distinto del predeterminado que se proporciona al conectar la billetera, tendrás que realizar una conexión manual. La documentación de Neon EVM ofrece guías completas para conectarte a un Proxy mediante Foundry, Hardhat, Remix y Truffle. En la sección de implementación veremos cómo conectarte con Foundry.

Una vez conectado, puedes usar el Neon Faucet para obtener NEON u otros tokens de prueba ERC-20. También puedes usar el endpoint request_neon para solicitar tokens mediante programación:

Código
curl -i -X POST \
	-d '{"wallet": "Your wallet", "amount": 1}' \
	'http://localhost:3333/request_neon'

Este comando envía una solicitud POST para recibir tokens en la dirección de billetera especificada.

Ciclo de vida de las transacciones y tarifas de gas

Hay tres pasos principales para ejecutar una transacción desde una dApp de Ethereum en Solana mediante Neon EVM:

  • Un usuario inicia una transacción firmada similar a las de Ethereum y la dirige a un endpoint RPC de Neon
  • La transacción se envía a Neon Proxy mediante la API de Ethereum. El Proxy calcula el gas necesario para ejecutarla, inicia una difusión envolviendo la transacción similar a las de Ethereum en una transacción de Solana y envía la transacción envuelta a Neon EVM. Esto genera un recibo de Solana y el recibo correspondiente de la transacción en Neon EVM. El contrato inteligente de Neon desenvuelve la transacción, verifica la firma del usuario y carga el estado de EVM desde el almacenamiento de Solana. La transacción se ejecuta dentro del BPF de Solana
  • Solana y Neon EVM actualizan sus estados para completar la solicitud de transacción

Este es el ciclo de vida completo de una transacción en Neon EVM, desde su inicio hasta su ejecución. Puedes visitar NeonScan para ver las transacciones y los bloques más recientes, así como consultar cuentas, tokens, bloques o hashes de transacciones.

También puedes enviar transacciones sin gas. Esta función se implementó para ayudar a los usuarios que no tienen suficientes tokens NEON para cubrir las tarifas de sus primeras transacciones. Puedes obtener un paquete inicial de transacciones sin gas escribiendo a info@neonevm.org. El Proxy Operator que elijas seguirá procesando estas transacciones, pero Neon cubrirá el costo. Por lo general, se ofrecen al menos tres transacciones sin gas por cada cuenta nueva de Neon.

El proceso de las transacciones sin gas es el siguiente:

  • Un usuario final inicia una transacción mediante una dApp
  • La dApp solicita el precio actual del gas al Proxy Operator elegido. Si la cuenta es apta, el Proxy Operator marca la cuenta de Neon para una cantidad determinada de transacciones sin gas
  • Para esas transacciones, la dApp mostrará un costo de gas de cero
  • El usuario final firma la transacción sin tarifa de gas
  • El Proxy Operator ejecuta la transacción y Neon Foundation paga la tarifa de gas en SOL

La documentación de Neon EVM proporciona el siguiente extracto para mostrar cómo solicitar una transacción sin gas:

Código
try {
	// Get gasless transaction if user account is eligible
  const rawGasPrice = await axios.post(rpcApiUrl, {
  	method: 'neon_gasPrice',
    params: [{ from: address }],
    jsonrpc: "2.0",
    id: new Date().getTime()
   })

   tx.gasPrice = rawGasPrice.data?.result;
	} catch (e) {
  	//Else, get standard GAS price
   	setError('Can\'t retrieve gas price for transaction')

    const rawGasPrice = await web3.eth.getGasPrice();

    tx.gasPrice = web3.utils.toHex(rawGasPrice);
} finally {
    setTx(tx)
}

NeonPass

NeonPass es una herramienta para transferir tokens entre Solana y Neon EVM. Permite transferir activos sin fricción entre las cuentas de tokens asociadas de Solana y las cuentas de tokens ERC-20 de Neon EVM. NeonPass usa el contrato de interfaz de Neon EVM y almacenamiento especializado de cuentas. Los tokens de Solana Program Library (SPL) se empaquetan en una interfaz ERC-20 dentro del contrato de fábrica de Neon EVM. Esto permite almacenar los SPL en cuentas de tokens ERC-20 compatibles con dApps de Solidity. NeonPass permite transferir tokens de forma bidireccional entre cuentas de Solana y Neon EVM. A diferencia de los puentes tradicionales, que bloquean activos y acuñan otros nuevos, mueve los tokens directamente entre los dos tipos de cuenta. Esto permite una transición fluida de tokens de Solana y Neon EVM.

Implementación

Puedes implementar en Neon EVM mediante Hardhat, Foundry, Truffle y Remix. Como la forma más sencilla de usar Solang es mediante Anchor, todas las pruebas se realizan en TypeScript. Sin embargo, por fin podemos probar e implementar dApps de Solidity en Solana mediante Foundry, para todos los maximalistas de Solidity.

Primero, asegúrate de tener una billetera compatible con EVM conectada a Neon EVM Devnet. Luego, clona el proyecto de ejemplo de Foundry de Neon y entra en su directorio:

Código
git clone https://github.com/neonlabsorg/neon-tutorials
cd neon-tutorials/foundry

Luego, instala Foundryup, el instalador de la cadena de herramientas de Foundry, y ejecuta foundryup para instalar los binarios precompilados más recientes (nightly), es decir, force, cast, anvil y chisel:

Código
curl -L https://foundry.paradigm.xyz | bash
foundryup

Instala las bibliotecas necesarias:

Código
forge install foundry-rs/forge-std --no-commit
forge install openzeppelin/openzeppelin-contracts --no-commit

Ahora obtén la clave privada de tu cuenta de billetera. En Metamask, por ejemplo, puedes ver tu clave privada haciendo clic en el menú de hamburguesa y accediendo a Account Details > Show Private Key. Se te pedirá que ingreses tu contraseña. Haz clic en Confirmar para acceder a la clave privada de tu cuenta. Recuerda no compartir esta clave con nadie y toma las medidas necesarias para protegerla.

Luego, crea un archivo .env con las siguientes variables:

Código
RPC_URL_DEVNET=https://devnet.neonevm.org
CHAIN_ID_DEVNET=245022926
RPC_URL_MAINNET=https://neon-proxy-mainnet.solana.p2p.org
CHAIN_ID_MAINNET=245022934
PRIVATE_KEY=
VERIFIER_URL_BLOCKSCOUT=https://neon-devnet.blockscout.com/api

Reemplaza <YOUR_PRIVATE_KEY> por tu clave privada y ejecuta source .env.

Para compilar los contratos del proyecto, entra en el directorio src y ejecuta forge build. La consola debería indicar que la ejecución del compilador se completó correctamente. También puedes probar los contratos con el comando forge test. Para implementar el contrato del proyecto, ejecuta el siguiente comando:

Código
forge create --rpc-url $RPC_URL_DEVNET --private-key $PRIVATE_KEY src/TestERC20/TestERC20.sol:TestERC20 --constructor-args "Test ERC20 Token" "TERC20" --legacy

Deberías ver un resultado similar al siguiente:

Código
[⠰] Compiling...
No files changed, compilation skipped
Deployer: 0x4455E84Eaa56a01676365D4f86348B311969a4f4
Deployed to: 0x5537599aa2F97Dd60a66342522a465A7f2e40Ff9
Transaction hash: 0x6de9dab8a526cbac33008056d185b93dff725605efb791bf116b6bece4f0c486

Para verificar tu contrato, ejecuta el siguiente comando:

Código
forge verify-contract --chain-id $CHAIN_ID_DEVNET  src/TestERC20/TestERC20.sol:TestERC20 --verifier-url $VERIFIER_URL_BLOCKSCOUT --verifier blockscout

Reemplaza <contract_address> por la dirección de tu contrato inteligente. Deberías recibir una respuesta OK con una URL que apunte a la dirección del contrato en BlockScout, el explorador de Devnet de Neon. También puedes configurar tu archivo .env para usar NeonScan en lugar de BlockScout, que también admite devnet.

Ventajas y limitaciones

Los desarrolladores que quieran una experiencia similar al desarrollo en Ethereum deberían elegir Neon EVM. Es un entorno compatible con EVM que envía transacciones similares a las de Ethereum y usa herramientas conocidas. Funciones como NeonPass, la compatibilidad con la mayoría de los opcodes de EVM y la disponibilidad de transacciones sin gas facilitan mucho la transición a Solana. Sin embargo, Neon EVM no es perfecto. Presenta ciertas limitaciones, como cambios en la lógica de los contratos inteligentes para adaptarse a la infraestructura de Solana, la necesidad de operar dentro de las restricciones de Berkeley Packet Filter (BFP) y los modelos de cuentas de Solana, y ciertas restricciones sobre opcodes y contratos precompilados. Comprender y abordar estos matices es fundamental para implementar con éxito en Solana desde un entorno compatible con EVM.

Migraciones anteriores

Un protocolo grande de Ethereum debe completar varias tareas complejas para implementarse en una cadena que no sea EVM. En concreto, debe contratar ingenieros que no trabajen con Solidity para reconstruir su código base desde cero, encontrar socios de auditoría confiables, volver a auditar el nuevo código base y adaptar los contratos de gobernanza para hacer cumplir las decisiones de la DAO. Estas tareas pueden costar millones de dólares y requerir meses de trabajo dedicado. Para la mayoría, esto no es viable. Sin embargo, ya ha ocurrido antes.

Helium es una red LoRaWAN cuyo objetivo es crear una infraestructura inalámbrica descentralizada para dispositivos del Internet de las cosas (IoT). Para ello, utiliza hotspots: dispositivos pequeños y de bajo consumo, similares a torres celulares en miniatura, que se conectan con otros hotspots a grandes distancias. Originalmente, Helium operaba en su propia blockchain de capa 1 (L1), pero su equipo de desarrollo propuso migrar a Solana mediante HIP 70. La migración permitiría a Helium lograr una mayor disponibilidad, una mejor capacidad de composición y una experiencia de usuario más rápida, sin sacrificar un alto nivel de seguridad ni un bajo costo de uso. La comunidad votó de forma abrumadora a favor de la propuesta y Helium migró a Solana en abril de 2023. Scott Sigel, COO de Helium, describió la migración como un evento aburrido: nada salió mal con la red ni con la infraestructura de Helium. Fue el sueño de cualquier ingeniero. El equipo también detalló todo el proceso de migración en una serie de guías en su documentación. La migración de Helium fue un gran éxito y benefició enormemente a la comunidad.

Esta migración no es un caso aislado. The Render Network, la primera plataforma descentralizada de renderizado con GPU del mundo, actualizó correctamente su infraestructura central de Ethereum a Solana en noviembre de 2023. La comunidad votó a favor de RNP-002 para migrar a Solana. Jules Urbach, fundador de Render, describió la migración como un momento decisivo. Declaró: “Las increíbles velocidades de transacción, los bajos costos y el compromiso de Solana con una arquitectura a escala web la convierten en la opción perfecta para Render Network mientras seguimos construyendo una infraestructura de metaverso escalable y descentralizada”.

La migración de Render no tuvo un efecto excesivamente negativo en sus usuarios. Los usuarios pueden transferir fondos de Ethereum a Solana mediante Render’s Upgrade Assistant. Solo deben conectar su billetera de Ethereum, indicar la cantidad de RNDR que desean migrar y esperar a que los tokens lleguen a la billetera de Solana especificada. 

Maker es un proyecto emblemático de Ethereum. Su objetivo es liberar el potencial de las finanzas descentralizadas con Maker Platform, una plataforma inclusiva diseñada para mejorar el empoderamiento económico y el acceso equitativo al mercado financiero global. La plataforma consta de MakerDAO, que administra el proyecto Maker, y el protocolo Maker para DAI, “la primera moneda imparcial del mundo y la principal stablecoin descentralizada”. Rune Christensen, fundador de Maker, publicó en Twitter sobre el uso de una bifurcación del código base de Solana para desarrollar una cadena específica para Maker: 

Las migraciones son complejas por naturaleza. A pesar de los costos económicos, reputacionales y temporales de migrar toda la infraestructura de un proyecto de Ethereum a Solana, los proyectos están eligiendo Solana. Con herramientas como Solang y Neon EVM, las migraciones no tienen por qué ser inherentemente complejas. Al igual que la migración de Helium, pueden ser aburridas y tener poco o ningún impacto negativo en los fondos de los usuarios, como ocurrió con Render Network. Solana es la blockchain con mayor rendimiento del mercado y está diseñada para operar a escala web. Este es el lugar para desarrollar, y cada vez más proyectos se están dando cuenta.

Conclusión

Solidity es la lingua franca del desarrollo de contratos inteligentes. EVM ha sido el entorno dominante para contratos inteligentes desde su creación. Sin embargo, tiene sus debilidades. Las aplicaciones de nivel de consumo y a escala web requieren una red de alto rendimiento y baja latencia para respaldar sus operaciones. El entorno monohilo de Ethereum, con costos de gas volátiles, no puede sustentar un proyecto de red de infraestructura física descentralizada (DePIN) y alto rendimiento como Helium. 

Ante estos desafíos, Solana surge como una alternativa potente. La mejor manera de aprovechar sus verdaderos beneficios es desarrollar directamente en Solana. Gracias a los avances recientes, herramientas como Solang y Neon EVM permiten que los desarrolladores de EVM interesados migren usando lenguajes y herramientas conocidos. Este artículo ofrece una guía completa sobre la arquitectura de Solana, cómo se compara con Ethereum y cómo un desarrollador de EVM podría comenzar a desarrollar en Solana. Solana es la blockchain con mayor rendimiento del mercado. Está ganando impulso, reconocimiento y aplicaciones de nivel de consumo con buena reputación. ¿Por qué esperar a que Ethereum escale si hoy puedes aprovechar los beneficios de una blockchain rápida y escalable?

Si llegaste hasta aquí, ¡gracias, anónimo! Ingresa tu dirección de correo electrónico a continuación para no perderte ninguna novedad sobre Solana. ¿Quieres profundizar? Únete a nuestro Discord para comenzar hoy mismo a construir el futuro sobre la blockchain con mayor rendimiento.

Recursos adicionales

Suscríbete a Helius

Mantente al día con las novedades del desarrollo en Solana y recibe actualizaciones cuando publiquemos

Imagen ampliada