Introducción al desarrollo de contratos inteligentes en RSK
Motivación
Estos últimos años ha habido un crecimiento en el desarrollo de Smart Contracts, predominantemente en la Blockchain de Ethereum. Ethereum, al ser un tipo diferente de blockchain que Bitcoin, puede ejecutar líneas concisas de código dentro de su cadena, un trabajo que Bitcoin (diseñado específicamente para enviar transacciones fácilmente) no puede hacer. Aquí es donde RSK interviene construyendo una sidechain atada a Bitcoin a través de un sistema de 2 vías, gestionado por los socios de la federación, que posibilita la ejecución del código. En lugar de diseñar un nuevo lenguaje de programación para desarrollar Smart Contracts, utilizaron Solidity, el mismo lenguaje que utiliza Ethereum. Esto tiene dos ventajas: no solo los programadores no tendrán que aprender una nueva habilidad, sino que los contratos en la red de Ethereum podrían implementarse en RSK sin mucho esfuerzo, aprovechando la gran capitalización bursátil que tiene Bitcoin.
En estos artículos, explicaré cómo crear un nodo RSK, cómo configurarlo correctamente y finalmente cómo implementar contratos e interactuar con ellos.
Instalación
Entorno de Sistema
El software del nodo se basa en EthereumJ. El equipo desarrollador de RSK ofrece diferentes formas para que diferentes sistemas operativos configuren un nodo. Para este artículo, vamos a aprender a configurar RSKj 4.2 en Linux, más específicamente en Ubuntu LTS 16.04. Cuando comencé este tutorial, el último Ubuntu LTS fue 16.04 y hace unos días, se liberó la versión 18.04. Debido a eso y otros problemas de estabilidad en el nuevo sistema operativo lanzado, voy a utilizar la versión 16.04.
De acuerdo, empecemos. Voy a suponer que vas a instalar el nodo desde una nueva instalación del SO, por lo que algunos programas probablemente ya estén instalados en tu PC y puedes omitir los pasos. Pero para aquellos que no los tienen, esto sería de ayuda.
Programas Esenciales
Nuestras primeras herramientas son git y curl. Con ellos podemos obtener bibliotecas y códigos de muchos desarrolladores y usarlos en nuestro trabajo. Para instalarlos, solo tenemos que escribir:
$ sudo apt-get install git $ sudo apt-get install curl
Necesitamos una instancia de Java para que funcione porque se ejecuta en su máquina virtual. La última versión de Java fue la décima en el momento de escribir esta guía, pero en nuestro caso, vamos a utilizar la octava versión de la branch Oracle en lugar de OpenJRE. Cualquiera de ellos debería funcionar bien. Para hacerlo, primero agregamos el repositorio a nuestro sistema y luego lo instalamos.
$ sudo add-apt-repository ppa:webupd8team/java $ sudo apt-get update $ sudo apt-get install oracle-java8-installer
Si tenemos otra versión de Java instalada, debemos asegurarnos de que la predeterminada es la que queremos:
$ sudo apt-get install oracle-java8-set-default
Luego, verificamos cuál está en uso:
$ java -version
Después de eso, debemos establecer la ruta para que Java agregue una línea en el archivo /etc/environment como Root. La línea es:
JAVA_HOME="/usr/lib/jvm/java-8-oracle"
En resumen:
¿Java? Hecho.
¿Git & curl? Doble hecho.
¿Qué es lo siguiente? El nodo RSKj en sí.
Node.js y nodo RSK
Vamos a instalar la versión 8:
$ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - $ sudo apt-get install -y nodejs $ sudo apt-get install -y build-essential
Y luego el proyecto RSK ya empaquetado como rskj y lo colocó en un PPA :
$ sudo add-apt-repository ppa:rsksmart/rskj $ sudo apt-get update $ sudo apt-get install rskj
Cuando termine, el instalador nos preguntará en qué red nos gustaría trabajar. No tengas miedo de elegir una, puedes cambiarlo más tarde con algunos ajustes que veremos. Seleccionemos Testnet por ahora.
El nodo está instalado. Para usarlo, debe habilitarlo como servicio
$ sudo service rsk start $ sudo service rsk status $ sudo service rsk stop
Estos son, respectivamente, para iniciar el nodo, observar lo que está sucediendo (registros y problemas en el servicio) y detenerlo.
Estas son algunas recomendaciones nacidas de la experiencia. NO TRATES DE:
- Apagar tu PC mientras se está ejecutando
- Utilizar controladores / hardware conflictivos que puedan congelar el sistema operativo (Ehmm .. Nvidia)
- Editar los archivos de configuración mientras se está ejecutando.
Cuando la base de datos no se cierra correctamente, termina corrupta y la manera simple de sincronizar el nodo nuevamente es reiniciarlo y comenzar nuevamente el proceso de sincronización desde cero. Intenta tener una UPS en caso de cortes de energía frecuentes.
Los lugares donde el nodo guarda su configuración, registros y bases de datos son:
Configurations files: /etc/rsk/ Databases: /var/lib/rsk/databases/ Logs: /var/logs/rsk/
Entorno de Desarrollo
Hay algunas formas de interactuar con rskj. Puede usar Node.js, la consola de RSK, llamadas RPC, Truffle y cualquier libreria web3 que funcione. Por ahora, usaremos Truffle porque también nos permite compilar e implementar en pocos pasos.
Para instalarlo globalmente, usamos la herramienta npm de los paquetes Node.js que hemos instalado.
$ sudo npm install -g truffle
Luego creamos una carpeta y le pedimos que descomprima la plantilla básica de desarrollador. Advertencia: necesitamos que la carpeta esté completamente vacía. De lo contrario Truffle terminará con errores.
$ mkdir ~/Truffle && cd ~/Truffle $ truffle init
Para conectar Truffle a nuestro nodo, debemos configurar la red en la que está trabajando el nodo. En nuestro caso, el puerto predeterminado es 4444 sobre localhost, por lo que el archivo debería verse así:
module.exports = { networks: { rsk: { host: "localhost", port: 4444, network_id: "*" // Match any network id } } };
Una vez hecho esto, nos podemos conectar al nodo con:
$ truffle console --network rsk
Si todo fue bien, deberias poder usar la consola de Truffle mostrando la linea de comando:
truffle(rsk)>
Ahora deberíamos poder ver el estado de sincronización de nuestro nodo, el último número de bloque que tenemos y el número de pares a los que estamos conectados. Para hacerlo, debe usar la libreria web3 de la misma manera que en Ethereum.
Solo una pequeña advertencia: el último web3 incluido en Truffle es un poco viejo, 0.20.6, así que ten en cuenta que algunos comandos tienen una sintaxis diferente en las versiones más nuevas. Busque los comandos disponibles usando la función de autocompletar (tecla TAB dos veces) después de web3.
Para las funciones que hemos mencionado, los comandos en su respectivo orden son:
truffle(rsk)> web3.eth.syncing truffle(rsk)> web3.eth.blockNumber truffle(rsk)> web3.net.peerCount
Selección de Red
Hasta ahora, el procedimiento era independiente de la red RSK que estábamos usando (Mainnet, Testnet o Regtest). Para configurarlos, hablamos sobre lo que necesitamos editar editar en su archivo de configuración que se encuentra en /etc/rsk/ . Allí encontramos tres archivos de configuración y un enlace simbólico a uno de ellos. El enlace simbólico, node.conf, es el que lee el servicio RSK.
Entonces, si queremos cambiar su red, detenemos el nodo, vamos a la carpeta, cambiamos el enlace al archivo de configuración correcto e inicializamos el servicio de esta manera:
$ sudo service rsk stop $ cd /etc/rsk $ sudo rm -f node.conf $ sudo ln -s ABCDEFG.conf node.conf $ sudo service rsk start
Donde ABCDEFG puede ser “testnet“, “mainnet” o “regtest“. El procedimiento es el mismo en los tres casos.
Si ha instalado el nodo como expliqué, debería tener la mayoría de los parámetros ya establecidos. Si abrimos uno de esos archivos, vemos desde dónde el nodo obtiene pares, el puerto activo (5050 para Mainnet y 50505 para Testnet), nuestra clave privada de nodo, algunos parámetros para la configuración del peer, la ID de red (775 para Mainnet, 779 para Testnet y 34567 para Regtest), donde se guarda la base de datos en particular, si queremos empezar desde cero y restablecer la base de datos (esto es útil cuando nuestra DB está dañada. En ese caso, cambie el booleano a “true” una vez y luego inicie el nodo), el puerto donde podemos conectarnos desde programas como Truffle y, por último, la configuración de la Wallet.
Wallet (billetera) y configuración de la cuenta
En el archivo por defecto tenemos:
wallet { accounts = [] }
Con esta configuración no podemos implementar contratos o enviar transacciones, tampoco crear cuentas, etc. Para habilitar todo eso debemos agregar la siguiente línea:
wallet { accounts = [] enabled = true }
Luego podemos crear una nueva cuenta en Truffle haciendo:
truffle(rsk)> web3.personal.newAccount(‘somePassword’) truffle(rsk)> web3.personal.unlockAccount(web3.eth.accounts[0],'somePassword')
También, si ya tenemos una cuenta en la red RSK, simplemente la agregamos en el archivo de config
wallet { accounts = [ { "privateKey" = "PRIVATEKEY" "address" = "0xADDRESS" } ] enabled = true }
“PRIVATEKEY” y “0xADDRESS” son las claves privadas y la dirección de tu cuenta donde los fondos de la red pueden ser usados.
Habiendo cambiado eso, podemos agregar esa dirección en el archivo de configuración de truffle.js para que nuestras transacciones e implementaciones se originen desde esa dirección de manera predeterminada y también, si usa Testnet, establezca el límite de gas más elevado y el precio de gas en cero. Estos 2 parámetros se agregan porque si no configuramos el gas nuestra transacción nunca podría ser minada por la red, y para el segundo, Testnet no nos cobra dinero real para trabajar por lo que incluso con un precio nulo los mineros pueden procesar nuestras transacciones.
Ahora nuestro truffle.js para Testnet debería verse así:
module.exports = { networks : { rsk: { gas : 2500000, gasPrice : 0, from : "0xADDRESS", host : "localhost", port : 4444, network_id : "*" // Match any network id } } };
Después de haber configurado todo eso, y después de esperar un tiempo para sincronizar nuestro nodo en TestNet o MainNet, entre 1 y 3 días, podemos comenzar a implementar contratos y realizar transacciones. Felicitaciones!!
Herramientas Adicionales
Mientras esperamos que esto ocurra, quiero agregar al RSK algunas herramientas para nuestro nodo que figuran en su Github. Entre ellas: hay una consola, un explorador local de bloques que funciona en el navegador y un modulo de prueba.
Para utilizarlos, clonamos el respositorio:
$ mkdir Utils && cd Utils $ git clone https://github.com/rsksmart/utilities.git
Luego entramos a la carpeta de herramientas, por ej. console y procedemos:
$ cd utilities/console/ $ npm install
Luego de eso, podemos conectarnos a nuestro nodo:
$ node console.js -server localhost:4444
En el cual podemos utlizar funciones como de costumbre:
RSK > web3.eth.blockNumber
No lo recomiendo porque tiene una versión de web3 anterior a la de Truffle (¡que ya es vieja!).
Para el explorador, proceder de la misma manera y agregar un paso adicional: cambie el host:port en config.json por localhost: 4444 después de ejecutar la instalación de npm.
Luego, para cargar el explorador:
$ npm start
El cual se puede browsear en http://localhost:3000.
El Modo Java
Hay otros métodos para inicializarlo como ejecutar el paquete .jar con Java e introducir el archivo de configuración como:
$ java -Drsk.conf.file=ABCDEFG.conf -cp rskj-core-0.4.1-BAMBOO-all.jar co.rsk.Star
Desde donde, la clave pública y privada, el ID del nodo se pueden obtener de
$ java -cp rskj-core-0.4.1-BAMBOO-all.jar co.rsk.GenNodeKeyId
Sin embargo, con este método, debe establecerse todos los parámetros de la plantilla, y puede ser confuso para un principiante.
Nodo Dedicado
También, si alguien usa una computadora únicamente para ejecutar el nodo, seria mejor utilizarla como servidor y conectarse a ella a través de ssh. De antemano, debe instalar en esa computadora el servidor ssh con:
$ sudo apt-get install openssh-server openssh-client
Para luego conectarse desde otra computadora haciendo:
$ ssh user@host
Obteniendo Fondos
Para obtener fondos en su cuenta, dependiendo de la red en la que esté trabajando. Para el Mainnet, debe cambiar sus BTC a través de un Peg de 2 vías para obtener SBTC en el lado de RSK y ser capaz de pagar el gas y las recompensas de los mineros / RSK Labs. Para hacerlo, primero necesita incluir su cuenta de BTC en la whitelist utilizando este formulario.
Luego, una vez que esté en la whitelist, debe llamar a la dirección del Contrato de federación (0x0000000000000000000000000000000001000006) y solicitar la dirección de depósito. Eso se puede hacer de la misma manera
truffle(rsk)> web3.sha3("getFederationAddress()").slice(0,10); // = 0x6923fa85 truffle(rsk)> web3.eth.call({data: "6923fa85", to: "0x0000000000000000000000000000000001000006"});
El resultado es un largo número hexadecimal que tiene 3 partes. Los primeros 32 bytes representan la longitud, los segundos 32 bytes representan la longitud del string y el resto es la dirección codificada en ASCII seguida de ceros. Entonces, si convertimos esta última parte del mensaje, obtenemos nuestra dirección BTC (o tBTC) de la Federación para depositar nuestros fondos.
truffle(rsk)> web3.toAscii(‘LAST_PART’)
Después de enviar la transacción, debe esperar +100 confirmaciones en ese bloque más un período de 5 minutos para ver sus fondos en la red RSK. Su cuenta en el otro lado se deriva de su cuenta BTC original a través de su clave privada. Para obtener el control de su nueva cuenta, puede ingresar al sitio de utils y obtener la clave privada de su cuenta derivada.
En este caso, como solo tenía sincronizado Testnet, lo hice solo en esa red en particular. Además, mis cuentas de BTC y tBTC aún no figuraban en la whitelist, así que no puedo decirles cómo funciona el sistema (¡espero que pronto!). Solo una última cosa: la dirección de Mainnet es diferente a la de Testnet. Tienes que hacer el mismo procedimiento para tu red seleccionada. ¡Cuidado!
Aunque no necesita fondos en su cuenta de Testnet (¡el gas es gratis! :D), se recomienda obtener algunos solo para probar si tiene un problema con su cuenta, nodo o cualquier otra cosa mientras debugea un contrato. A veces, el sistema no funciona y no se pueden implementar contratos; en ese caso, si no sabe lo que está sucediendo y se le está cayendo el cabello, puede probar si la red está bien simplemente enviando una transacción a otra cuenta suya y ver qué sucede en el bloque. Si no quiere hacer el Peg de 2 vías o esperar para ser incluido en la whitelist, puede solicitar fondos de prueba desde la faucet.
Conectando Metamask a nuestro nodo RSK
Si desea utilizar Metamask para enviar transacciones, debe configurar dos cosas: la primera está en node.conf, en la cual tenemos que cambiar el parámetro cors decors = “*.rsk.co” a cors = “*” y luego reiniciar nuestro nodo; el segundo es establecer la red RPC local en Metamask como http://localhost:4444, o como lo ha configurado en el archivo node.conf.
Después de eso, se debe importar la clave privada de su cuenta a Metamask y luego debería aparecer el saldo de su cuenta. La unidad dice ETH pero realmente es SBTC. No te preocupes.
Conclusiones
En esta primera parte del tutorial, hemos presentado una introducción para crear el entorno en desarrollo de RSK. Hemos visto cómo:
- construir un nodo RSK en diferentes redes,,
- seleccionar una red para sincronizar,
- configura Truffle para interactuar con nuestro nodo,
- agregar una cuenta para hacer transacciones en la red,
- interactuar con el sistema Peg de 2 vías y transferir nuestros fondos.
En el próximo capítulo crearemos e implementaremos contratos en la red, e interactuaremos con ellos por Mainnet. Ya puedes chequearlo aquí (en inglés).