5 Maneras en que el Desarrollo de Aplicaciones Ergo Cambió Para Siempre Gracias a Appkit
3 de diciembre de 2019

Con agradecimientos a Robert Kornacki y Denys Zadorozhnyi.
Ergo Appkit es una biblioteca para
desarrollo poliglota de Aplicaciones Ergo basada en
GraalVM. GraalVM tiene muchos grandes
casos de uso. Ampliando eso, en este artículo revisaremos algunas de las características de Appkit
heredadas de GraalVM y te llevaremos paso a paso en el aprendizaje de cómo aprovecharlas.
- 0. Escenario de Ejemplo
- 1. Desarrollo de Aplicaciones Ergo en Java
- 2. Aplicaciones Ergo de Bajo Consumo y Rápido Inicio
- 3. Desarrollar Aplicaciones Ergo en JavaScript, Python, Ruby
- 4. Bibliotecas Compartidas Nativas de Ergo
- 5. Depurar Tu Aplicación Ergo Poliglota
Escenario de Ejemplo
Crearemos una simple aplicación de consola (llamada
FreezeCoin)
en Java que utiliza la biblioteca Appkit. Al usar Appkit, podremos enviar fácilmente una nueva transacción a un nodo Ergo programáticamente. La
transacción transferirá una cantidad dada de Erg a una nueva caja protegida por el
siguiente contrato Ergo escrito en ErgoScript (consulta esta
introducción y más ejemplos
avanzados para aprender más sobre ErgoScript).
// Contrato Freezer
{
// Parámetros
// freezeDeadline: Int - algún número de bloque futuro después del cual la caja puede ser gastada
// ownerPk: SigmaProp - clave pública del nuevo propietario de la caja
sigmaProp(HEIGHT > freezeDeadline) && ownerPk
}
En resumen, una caja (y por lo tanto los fondos dentro de la caja) están bloqueados bajo un contrato (o script) en la blockchain de Ergo. Para que la caja sea gastada, el contrato debe evaluarse como verdadero. Por lo tanto, la persona que desea gastar la caja debe asegurarse de que el contrato se evalúe como verdadero basado en la lógica codificada dentro de él.
Nuestro contrato Freezer anterior verifica las siguientes condiciones antes de permitir que la caja sea gastada:
-
El número de bloque actual de la blockchain de Ergo (también conocido como ALTURA de la blockchain) es
mayor que la fecha límite especificada -
La transacción de gasto debe ser firmada por el propietario de la clave secreta
correspondiente a la clave pública ownerPk.
La primera condición prohíbe a cualquier persona gastar la caja antes de que la blockchain de Ergo
crezca a la altura dada. Dado que los nuevos bloques en la blockchain se minan aproximadamente cada 2 minutos en promedio, usando la altura actual de la
blockchain es fácil definir cualquier duración de retraso que deseemos, como 1 día, 1 semana o 1 mes. (es decir, (60 / 2) * 24 * 7 = 5040, que es el número de bloques por semana).
Ahora profundizaremos en cómo podemos tomar este Contrato Freezer e integrarlo con la biblioteca Apkit para crear la aplicación de consola FreezeCoin para que cualquiera pueda elegir congelar sus monedas si así lo desea. (Ciertamente, este contrato/dApp no es realmente útil, sin embargo, es un ejemplo simple efectivo para mostrar cómo funciona esta pila de tecnología para que tú mismo puedas construir dApps útiles más adelante.)
1. Desarrollo de Aplicaciones Ergo en Java
Appkit tiene como objetivo proporcionar un conjunto de interfaces que se pueden usar idiomáticamente
en Java. Te sentirás como en casa usando Appkit si eres un veterano de Java.
Por favor, sigue las instrucciones de configuración para GraalVM y
Appkit si deseas reproducir los ejemplos a continuación.
Para usar Appkit en nuestra implementación de Java de FreezeCoin, debemos agregar la
siguiente dependencia en el archivo gradle
dependencies {
implementation("org.ergoplatform", "ergo-appkit_2.12", "3.1.0", "compile")
...
}
Además, en tiempo de ejecución, Appkit/nuestra aplicación necesita conectarse a un Nodo Ergo a través de la API REST. A menudo,
el nodo se ejecutará localmente y estará disponible en http://localhost:9052/. Este es el escenario estándar para cualquiera que haya configurado un nodo completo siguiendo estas
instrucciones y esté usando la configuración predeterminada.
Por lo tanto, asumiremos que has configurado y comenzado tu Nodo Ergo para que esté disponible para probar la aplicación.
A continuación, nuestra aplicación necesitará saber cómo conectarse a nuestro nodo local en ejecución, además de otros varios ajustes para funcionar correctamente. Usaremos un archivo json con los siguientes
parámetros de configuración que nuestra aplicación FreezeCoin cargará al inicio.
{
"node": {
"nodeApi": {
"apiUrl": "http://localhost:9052/",
"apiKey": "pon aquí tu clave api secreta generada durante la configuración del nodo"
},
"wallet": {
"mnemonic": "la clave mnemotécnica utilizada para inicializar o restaurar la billetera del nodo",
"password": "la contraseña que elegiste para proteger la billetera",
"mnemonicPassword": "la contraseña que elegiste para proteger la mnemotécnica"
},
"networkType": "TESTNET"
},
"parameters": {
"newBoxSpendingDelay": "30",
"ownerAddress": "3WzR39tWQ5cxxWWX6ys7wNdJKLijPeyaKgx72uqg9FJRBCdZPovL"
}
}
Aquí apiKey es la clave secreta requerida para la autenticación de la API que se puede
adquirir como se describe
aquí.
Tu mnemotécnica es la frase secreta obtenida durante la configuración de una nueva
billetera.
El funcionamiento de nuestra aplicación será que el usuario la lanzará desde la línea de comandos y proporcionará un argumento. Este argumento es la cantidad de valor (en NanoErgs) que desea congelar/bloquear bajo el contrato Freezer que escribimos anteriormente.
Nuestro primer paso para nuestra aplicación FreezeCoin será leer el archivo de configuración json que acabamos de crear y aceptar el argumento de línea de comandos del usuario:
public static void main(String[] args) {
long amountToSend = Long.parseLong(args[0]); // valor positivo en NanoErg
ErgoToolConfig conf = ErgoToolConfig.load("freeze_coin_config.json");
// el resto del código discutido a continuación
...
}
Con esto adquirido, ahora podemos obtener el retraso de gasto y la dirección del propietario que se definieron en el archivo de configuración json.
int newBoxSpendingDelay = Integer.parseInt(conf.getParameters().get("newBoxSpendingDelay"));
Address ownerAddress = Address.create(conf.getParameters().get("ownerAddress"));
A continuación, necesitamos conectarnos al nodo Ergo en ejecución desde nuestra aplicación Java para que podamos usar los datos que acabamos de analizar y publicar algo en la cadena. Esto se hace creando
una instancia de ErgoClient que utiliza nuestros valores predefinidos para nuestro nodo del archivo de configuración json también.
ErgoNodeConfig nodeConf = conf.getNode();
ErgoClient ergoClient = RestApiErgoClient.create(nodeConf);
Ahora que tenemos una instancia de ErgoClient,
podemos ejecutar cualquier bloque de código y tener acceso al contexto actual de la blockchain.
String txJson = ergoClient.execute((BlockchainContext ctx) -> {
// usa ctx aquí para crear y firmar una nueva transacción
// luego envíala al nodo
});
La lambda pasada a execute se llama cuando el contexto actual de la blockchain
se carga desde el nodo Ergo. En esta lambda
pondremos nuestra lógica de aplicación.
Primero comenzamos con algunos pasos auxiliares.
// acceder a la billetera embebida en el nodo Ergo
// (usando la billetera especificada a través de la mnemotécnica que pusimos en freeze_coin_config.json)
ErgoWallet wallet = ctx.getWallet();
// calcular la cantidad total de NanoErgs que necesitamos enviar a la nueva caja
// incluyendo el pago de tarifas de transacción
long totalToSpend = amountToSend + Parameters.MinFee;
// solicitar cajas no gastadas que cubran la cantidad requerida de NanoErgs de la billetera
Optional<List<InputBox>> boxes = wallet.getUnspentBoxes(totalToSpend);
if (!boxes.isPresent())
throw new ErgoClientException(
"No hay suficientes monedas en tu billetera especificada para pagar " + totalToSpend, null);
// crear un "prover", que es un objeto especial que se utilizará para firmar la transacción
// el prover debe configurarse con los secretos de tu billetera, que son necesarios para generar firmas (también conocidas como pruebas)
ErgoProver prover = ctx.newProverBuilder()
.withMnemonic(
nodeConf.getWallet().getMnemonic(),
nodeConf.getWallet().getPassword())
.build();
En este punto, hemos elegido las cajas de entrada para nuestra transacción de gasto, pero ahora necesitamos crear una caja de salida con la amountToSend especificada y bloqueada bajo el contrato Freezer.
// la única forma de crear una transacción es usando el constructor de transacciones obtenido del contexto
// el constructor utiliza el contexto para acceder a los datos necesarios de la blockchain.
UnsignedTransactionBuilder txB = ctx.newTxBuilder();
// crear nueva caja usando el nuevo constructor obtenido del constructor de transacciones
// en este caso compilamos un nuevo ErgoContract a partir del código ErgoScript de Freezer
OutBox newBox = txB.outBoxBuilder()
.value(amountToPay)
.contract(ctx.compileContract(
ConstantsBuilder.create()
.item("freezeDeadline", ctx.getHeight() + newBoxSpendingDelay)
.item("ownerPk", ownerAddress.getPublicKey())
.build(),
"{ sigmaProp(HEIGHT > freezeDeadline) && ownerPk }"))
.build();
Nota, para compilar ErgoContract a partir del código fuente del script Freezer, el método compileContract
requiere que proporcionemos valores para las constantes nombradas que se utilizan dentro del script.
Si no se utilizan tales constantes, entonces se puede pasar ConstantsBuilder.empty() a él.
En este caso, pasamos la clave pública del nuevo propietario de la caja al marcador de posición ownerPk
en el script. Para repetir lo anterior, esto significa que la caja solo puede ser gastada por el propietario de la
clave secreta correspondiente.
A continuación, creamos una transacción no firmada utilizando todos los datos que hemos reunido hasta ahora.
// proporcionar al constructor de transacciones qué cajas vamos a gastar, qué salidas
// deben ser creadas, las tarifas totales de transacción y la dirección a la que se enviará el cambio
UnsignedTransaction tx = txB.boxesToSpend(boxes.get())
.outputs(newBox)
.fee(Parameters.MinFee)
.sendChangeTo(prover.getP2PKAddress())
.build();
Y finalmente:
- Usar el prover para firmar la transacción construida
- Así obtener una instancia de
SignedTransaction - Usar el contexto de la blockchain para enviar la transacción firmada al
nodo Ergo.
El txId resultante se puede usar para referirse a esta transacción
más tarde, sin embargo, no lo usamos aquí.
SignedTransaction signed = prover.sign(tx);
String txId = ctx.sendTransaction(signed);
return signed.toJson(true);
Como habrás notado, para nuestro paso final mostramos que es posible serializar la transacción firmada
en una cadena Json con la impresión bonita activada. Consulta el código fuente completo
del ejemplo para más detalles y para usarlo como plantilla en tu propia
aplicación.
Ahora con todo el código establecido, podemos ejecutar nuestra aplicación FreezeCoin usando los siguientes pasos
(suponiendo que estás en el directorio donde clonaste
ergo-appkit-examples).
$ pwd
the/directory/you/cloned/ergo-appkit-examples
$ ./gradlew clean shadowJar
Esto ensamblará el archivo build/libs/appkit-examples-3.1.0-all.jar que contiene
nuestra aplicación Java FreezeCoin y todas sus dependencias en un solo jar grande.
Nota, este paso debe repetirse después de cualquier cambio realizado en el código fuente Java de nuestra aplicación.
Habiendo creado nuestra aplicación, ahora podemos usar nuestra aplicación FreezeCoin:
$ java -cp build/libs/appkit-examples-3.1.0-all.jar \
org.ergoplatform.appkit.examples.FreezeCoin 1000000000
Recibirás algo similar a esta salida en la consola.
Y con eso tu transacción fue aceptada por el nodo Ergo y transmitida a la red donde permanecerá en la piscina de transacciones para ser añadida a un bloque. Una vez que un minero la seleccione y la añada a un bloque, tus monedas estarán oficialmente "congeladas" dentro de la nueva caja creada basada en los valores que proporcionaste a la aplicación FreezeCoin.
El ejemplo asume que el nodo Ergo (y la billetera embebida) es propiedad del
usuario de FreezeCoin. Sin embargo, esto no es estrictamente necesario y las interfaces de Appkit
se pueden usar para crear y enviar nuevas transacciones utilizando nodos públicos de Ergo arbitrarios.
2. Aplicaciones Ergo de Bajo Consumo y Rápido Inicio
Como sabes, usar Java para procesos de corta duración tiene muchas desventajas.
Las aplicaciones tienden a sufrir de largos tiempos de inicio y un uso de memoria relativamente alto.
Ejecutemos FreezeCoin usando el comando time para
obtener el tiempo real (tiempo transcurrido en reloj de pared) que toma todo el programa para ejecutarse de
principio a fin. Usamos la opción -l para imprimir el uso de memoria también.
$ /usr/bin/time -l java -cp build/libs/appkit-examples-3.1.0-all.jar \
org.ergoplatform.appkit.examples.FreezeCoin 1000000000
...
4.97 real 8.41 user 0.69 sys
513703936 tamaño máximo del conjunto residente
0 tamaño promedio de memoria compartida
0 tamaño promedio de datos no compartidos
0 tamaño promedio de pila no compartida
125010 reclamaciones de páginas
1216 fallos de página
0 intercambios
0 operaciones de entrada de bloque
0 operaciones de salida de bloque
13 mensajes enviados
86 mensajes recibidos
1 señales recibidas
2384 cambios de contexto voluntarios
17409 cambios de contexto involuntarios
Como se ve arriba, esta pequeña aplicación tomó 2 hilos paralelos casi 4
segundos para ejecutarse. La mayor parte de ese tiempo se puede atribuir al inicio de la JVM y
a la ejecución del compilador JIT en segundo plano. Este es un rendimiento bastante deficiente, y sabemos que podemos hacerlo mucho mejor.
Afortunadamente, GraalVM nos proporciona la solución perfecta.
Podemos resolver este problema inherente con la JVM compilando el código Java
a tiempo de ejecución en una imagen ejecutable nativa a través de GraalVM. Esto omite la necesidad de usar el compilador just-in-time de Java
en tiempo de ejecución.
La experiencia para nosotros (los desarrolladores que usan GraalVM) es bastante similar a un compilador convencional como gcc. Nota,
puede que necesitemos ejecutar ./gradlew clean shadowJar primero.
$ ./gradlew clean shadowJar
$ native-image --no-server \
-cp build/libs/appkit-examples-3.1.0-all.jar\
--report-unsupported-elements-at-runtime\
--no-fallback -H:+TraceClassInitialization -H:+ReportExceptionStackTraces\
-H:+AddAllCharsets -H:+AllowVMInspection -H:-RuntimeAssertions\
--allow-incomplete-classpath \
--enable-url-protocols=http,https org.ergoplatform.appkit.examples.FreezeCoin freezecoin
[freezecoin:3133] classlist: 35,217.78 ms
[freezecoin:3133] (cap): 6,063.07 ms
[freezecoin:3133] setup: 8,268.99 ms
[freezecoin:3133] (typeflow): 60,238.25 ms
[freezecoin:3133] (objects): 33,009.06 ms
[freezecoin:3133] (features): 4,796.86 ms
[freezecoin:3133] analysis: 102,876.01 ms
[freezecoin:3133] (clinit): 11,642.43 ms
[freezecoin:3133] universe: 13,718.96 ms
[freezecoin:3133] (parse): 5,053.18 ms
[freezecoin:3133] (inline): 18,317.24 ms
[freezecoin:3133] (compile): 44,806.82 ms
[freezecoin:3133] compile: 72,288.24 ms
[freezecoin:3133] image: 7,955.29 ms
[freezecoin:3133] write: 2,872.25 ms
[freezecoin:3133] [total]: 243,813.30 ms
El simple comando anterior produce un ejecutable nativo completo llamado freezecoin.
Para enfatizar, este ejecutable no es un mero lanzador para la JVM. De hecho, no se vincula a la JVM ni agrupa
tampoco la JVM de ninguna manera. native-image compila el código de FreezeCoin, así como cualquier
biblioteca Java de la que dependa, hasta código de máquina simple.
Si miramos las bibliotecas que utiliza freezecoin, podemos ver que solo utiliza bibliotecas estándar del sistema. Por lo tanto, podemos mover solo este ejecutable a otro sistema
que no tenga una JVM instalada y funcionará allí sin problemas.
$ otool -L freezecoin # ldd freezecoin en Linux
freezecoin:
/usr/lib/libSystem.B.dylib (versión de compatibilidad 1.0.0, versión actual 1252.50.4)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (versión de compatibilidad 150.0.0, versión actual 1455.12.0)
/usr/lib/libz.1.dylib (versión de compatibilidad 1.0.0, versión actual 1.2.11)
Si cronometramos este nuevo ejecutable freezecoin, podemos ver que se inicia aproximadamente 8 veces más rápido y utiliza
alrededor de 6 veces menos memoria. Lo que esto significa es que no sientes esa pausa palpable que siempre obtienes al ejecutar un
programa de corta duración con la JVM.
$ DYLD_LIBRARY_PATH=$GRAAL_HOME/jre/lib /usr/bin/time -l ./freezecoin 1800000000
0.43 real 0.15 user 0.03 sys
81289216 tamaño máximo del conjunto residente
0 tamaño promedio de memoria compartida
0 tamaño promedio de datos no compartidos
0 tamaño promedio de pila no compartida
20079 reclamaciones de páginas
0 fallos de página
0 intercambios
0 operaciones de entrada de bloque
0 operaciones de salida de bloque
13 mensajes enviados
86 mensajes recibidos
0 señales recibidas
11 cambios de contexto voluntarios
138 cambios de contexto involuntarios
Este es solo uno de los grandes beneficios de GraalVM de los que podemos aprovechar con Appkit.
3. Desarrollar Aplicaciones Ergo en JavaScript, Python, Ruby
GraalVM soporta lo que se llama programación poliglota en la que diferentes componentes de
una aplicación pueden ser desarrollados utilizando el lenguaje más adecuado y luego
combinarse sin problemas en tiempo de ejecución. De esta manera, una biblioteca única escrita en, digamos,
Java puede ser utilizada en una aplicación node.js escrita en JavaScript, por ejemplo.
Para soportar la programación poliglota, la plataforma GraalVM tiene sus propias implementaciones de alto rendimiento
de lenguajes populares. Vamos a aprovechar esto para
uestro proyecto de ejemplo FreezeCoin para mostrarte lo fácil que es usar tu lenguaje preferido.
Antes de ejecutar los ejemplos a continuación (en JavaScript, Python y Ruby), asegúrate de que tienes la
versión Java de FreezeCoin funcionando localmente para garantizar que todo esté configurado correctamente.
JavaScript
GraalVM puede ejecutar JavaScript y
Node.js
aplicaciones directamente. Es compatible con la especificación ECMAScript 2019.
Además, los lanzadores js y node aceptan opciones especiales de línea de comandos --jvm y --polyglot
que permiten a los scripts JS acceder a objetos y clases de Java.
Dado que ese es el caso, una implementación JS de FreezeCoin se puede escribir fácilmente utilizando la interfaz API de Appkit.
Consulta el código fuente completo de la implementación de FreezeCoin JS
para más detalles.
El siguiente comando utiliza el lanzador node para ejecutar el script FreezeCoin.js.
$ node --jvm --vm.cp=build/libs/appkit-examples-3.1.0-all.jar \
js-examples/FreezeCoin.js 1000000000
Nota, las rutas en el comando son relativas a la raíz del
directorio del proyecto ergo-appkit-examples.
Python
GraalVM puede ejecutar scripts de Python, aunque
aún la implementación de Python es experimental (consulta también la
sección de compatibilidad
para más detalles).
Ejemplo de Python de
FreezeCoin
p puede ejecutarse utilizando el siguiente comando
$ graalpython --jvm --polyglot --vm.cp=build/libs/appkit-examples-3.1.0-all.jar \
python-examples/FreezeCoin.py 1900000000
Ruby
GraalVM puede ejecutar scripts de Ruby utilizando
la implementación TruffleRuby, que sin embargo sigue siendo experimental (consulta también la
sección de compatibilidad
para más detalles).
TruffleRuby tiene como objetivo ser completamente compatible con la implementación estándar de Ruby, MRI, versión 2.6.2
Ejemplo de Ruby de
FreezeCoin
p puede ejecutarse utilizando el siguiente comando
$ truffleruby --polyglot --jvm --vm.cp=build/libs/appkit-examples-3.1.0-all.jar \
ruby-examples/FreezeCoin.rb 1900000000
4. Bibliotecas Compartidas Nativas de Ergo
Otro gran beneficio de GraalVM es que podemos compilar clases Java en una biblioteca compartida nativa en lugar de un ejecutable.
Para hacer esto, declaramos uno o más métodos estáticos como @CEntryPoint.
public class FreezeCoin {
...
/**
* Punto de entrada llamable desde C que envuelve {@link FreezeCoin#sendTx}
*/
@CEntryPoint(name = "sendTx")
public static void sendTxEntryPoint(
IsolateThread thread,
SignedWord amountToSendW,
CCharPointer configFileNameC,
CCharPointer resBuffer, UnsignedWord bufferSize) throws FileNotFoundException {
long amountToSend = amountToSendW.rawValue();
// Convertir las cadenas C a las cadenas Java de destino.
String configFileName = CTypeConversion.toJavaString(configFileNameC);
String txJson = sendTx(amountToSend, configFileName);
// poner la cadena resultante en el búfer proporcionado
CTypeConversion.toCString(txJson, resBuffer, bufferSize);
}
...
}
Luego podemos compilar a una biblioteca compartida y un archivo de encabezado generado automáticamente.
Nota el uso de la opción --shared.
$ native-image --no-server \
-cp build/libs/appkit-examples-3.1.0-all.jar\
--report-unsupported-elements-at-runtime\
--no-fallback -H:+TraceClassInitialization -H:+ReportExceptionStackTraces\
-H:+AddAllCharsets -H:+AllowVMInspection -H:-RuntimeAssertions\
--allow-incomplete-classpath \
--enable-url-protocols=http,https
--shared -H:Name=libfreezecoin -H:Path=c-examples
$ otool -L c-examples/libfreezecoin.dylib
c-examples/libfreezecoin.dylib:
.../c-examples/libfreezecoin.dylib (versión de compatibilidad 0.0.0, versión actual 0.0.0)
/usr/lib/libSystem.B.dylib (versión de compatibilidad 1.0.0, versión actual 1252.50.4)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (versión de compatibilidad 150.0.0, versión actual 1455.12.0)
/usr/lib/libz.1.dylib (versión de compatibilidad 1.0.0, versión actual 1.2.11)
Ahora tenemos la capacidad de escribir un programa C
que utiliza la biblioteca.
La interfaz de nuestra biblioteca nativa tiene un poco de
boilerplate (porque la VM necesita gestionar un montón, hilos, un recolector de basura
y más), y por lo tanto necesitamos crear una instancia y proporcionarle
nuestro hilo principal.
#include <stdlib.h>
#include <stdio.h>
#include <libfreezecoin.h>
int main(int argc, char **argv) {
graal_isolate_t *isolate = NULL;
graal_isolatethread_t *thread = NULL;
if (graal_create_isolate(NULL, &isolate, &thread) != 0) {
fprintf(stderr, "error graal_create_isolate\n");
return 1;
}
char * configFileName = "freeze_coin_config.json";
// obtener amountToSend de los argumentos cmd y llamar a la creación de transacciones
long amountToSend = atol(argv[1]);
char result[1024 * 16];
sendTx(thread, amountToSend, configFileName, result, sizeof(result));
// imprimir el resultado serializado
printf("%s\n", result);
if (graal_detach_thread(thread) != 0) {
fprintf(stderr, "error graal_detach_thread\n");
return 1;
}
return 0;
}
Podemos compilar esto con nuestras herramientas estándar del sistema y ejecutar fácilmente nuestro ejecutable (configura LD_LIBRARY_PATH=. en Linux).
$ clang -Ic-examples -Lc-examples -lfreezecoin c-examples/freezecoin.c -o call_freezecoin
$ otool -L call_freezecoin
$ DYLD_LIBRARY_PATH=$GRAAL_HOME/jre/lib ./call_freezecoin 1000000000
5. Depurar Tu Aplicación Ergo Poliglota
Puedes depurar JS, Python y Ruby en IntelliJ, pero si por alguna razón esto
o no funciona para ti o no se ajusta a tu editor preferido, GraalVM ofrece otra opción.
Todos los lenguajes de GraalVM (excepto Java) están implementados utilizando el marco común
Truffle.
Truffle permite que herramientas como depuradores se implementen una vez y estén disponibles
para todos los lenguajes soportados.
Como tal, podemos ejecutar nuestro programa con la bandera --inspect que nos dará un enlace para
abrir en Chrome y pausará el programa en el depurador.
$ ruby --polyglot --jvm --inspect --vm.cp=build/libs/appkit-examples-3.1.0-all.jar \
ruby-examples/FreezeCoin.rb 1900000000
Debugger escuchando en el puerto 9229.
Para comenzar a depurar, abre la siguiente URL en Chrome:
chrome-devtools://devtools/bundled/js_app.html?ws=127.0.0.1:9229/30c7da1e-7558a47d09b
...
Desde aquí podemos establecer puntos de interrupción y continuar la ejecución. Cuando se detiene, veremos
los valores de las variables, podemos continuar nuevamente hasta el siguiente punto de interrupción, y hacer todo lo que hemos llegado a esperar de los depuradores.

Conclusiones
Y con todo eso dicho y hecho, vemos lo fácil que es usar Appkit para
desarrollar Aplicaciones Ergo. Appkit se basa en las mismas bibliotecas centrales exactas que
se utilizaron en la implementación del protocolo de consenso de Ergo. Estas bibliotecas incluyen
the compilador de ErgoScript, criptografía, intérprete de bytecode, serializadores de datos
y otros componentes centrales. Usando GraalVM podemos reutilizar estos componentes probados
y comprobados en diferentes contextos de aplicación sin ninguna modificación
ni reescribirlos nosotros mismos.
No importa si estás usando Java, JavaScript, Python o Ruby, puedes aprovechar
Appkit con GraalVM para simplificar drásticamente el proceso de
interactuar con la blockchain de Ergo mientras creas (d)Apps que se ejecutan de forma nativa.
Mantente atento. En futuras publicaciones te presentaremos otras aplicaciones potenciales interesantes
impulsadas por Appkit.
Referencias
Share post
13 de agosto de 2025
12 de agosto de 2025
9 de julio de 2025
12 de mayo de 2025

9 de febrero de 2022

8 de febrero de 2022

5 de febrero de 2022

1 de febrero de 2022

27 de enero de 2022

20 de enero de 2022

18 de enero de 2022

6 de enero de 2022

4 de enero de 2022

30 de diciembre de 2021

28 de diciembre de 2021

23 de diciembre de 2021








