erc20 rsk openzeppelin logos

Desarrollo de Token ERC20 en RSK con OpenZeppelin

Reading Time: 8 minutes

  •  
  •  
  •  
  •  
  •  
  •  
  •  

Introducción

En el último artículo (en ingles), hemos visto cómo construir un nodo RSK en nuestra computadora, seleccionar la red adecuada para el desarrollo, configurar Tuffle para conectar y desplegar nuestros futuros contratos, agregar cuentas a nuestro nodo y obtener fondos para usarlos para pagar el gas.

Debería tener ahora su nodo en la red seleccionada totalmente sincronizado, y al menos una cuenta con fondos configurados en los archivos de configuración de Truffle y del nodo RSK para nuestras implementaciones.

En este artículo, discutiremos el despliegue y la interacción de Smart-Contracts sobre la red RSK. Nuestro contrato será un token ERC20, basado en las bibliotecas de OpenZeppelin, y lo implementaremos directamente en el Mainnet.

Creando el Contrato

Lo primero que debemos lograr es saber cómo usar Truffle.

Cuando lo hacemos

Dentro de una carpeta vacía, además de crear el archivo de configuración, también creamos carpetas para nuestros proyectos y el contrato de migración para mantener un registro de los cambios sobre el mismo contrato.

Los archivos de código .sol de los contratos se encuentran en

Los scripts de migración están en

Los contratos compilados están en

Y la prueba está en

Trabajaremos solo en las primeras 2 carpetas por ahora.

Dentro de la carpeta Truffle, importamos las bibliotecas de OpenZeppelin con

Estas bibliotecas instalarán no solo las bibliotecas principales de nuestro token, sino también las bibliotecas de propiedad, matemáticas seguras y muchas otras instalaciones. Vale la pena mencionar que estas bibliotecas han sido revisadas para lograr altos estándares de seguridad, por lo que los contratos que dependen de ellas son menos susceptibles a la piratería cuando se usan correctamente.

Nuestras bibliotecas se instalarán en

Después de eso, podemos importar una biblioteca ABCD.sol a nuestro contrato de esta manera:

Para crear nuestro Token ERC20, importaremos 2 bibliotecas de ese repositorio: el StandardToken.sol, que tiene la funcionalidad principal de un Token y ya importa un montón de bibliotecas más por sí mismo como SafeMath.sol y Ownable.sol. Esto nos permite establecer el control del propietario sobre las funciones en los contratos.

Para heredar los atributos y funciones de las bibliotecas, simplemente definimos nuestro contrato como StandardToken y como Ownable usando la palabra clave “es” de esta manera:

Después de eso, tenemos todas las funciones de esas bibliotecas y de sus bibliotecas importadas hacia arriba.

A continuación, definimos el nombre del Token como CoinFabrik, su símbolo, 18 decimales para la precisión del Token (el estándar en redes similares a Ethereum, que nos da la posibilidad de usar funciones de conversión Ether de web3) y el suministro inicial de tokens a 1000 Me gusta esto:

También vamos a crear otra cadena, una variable no pública no relevante para la funcionalidad Token, para mostrar el uso de las propiedades de la biblioteca Ownable, que solo permite que el creador interactúe con algunas funciones designadas. Ya veremos eso más tarde.

Con nuestros parámetros ya definidos, ahora es el momento de asignarlos a las variables Token a través de la función constructora. Hasta ahora, la función constructora se definía como una función que tenía el mismo nombre que el contrato, pero de ahora en adelante, habrá una función llamada “constructor ()” ya definida que reemplazará el método anterior. El compilador de Solidity te avisará si llamas al constructor como antes.

El número de INITIAL_SUPPLY multiplicado por la precisión de los decimales se asignará a la totalSuply_ del contrato de BasicToken con

Y deposítalos en la cuenta del creador

Con esto, tenemos un Token simple y estándar listo para ser utilizado pero, como dijimos, vamos a agregar algunas funcionalidades usando el contrato de Ownable. Primero, definiremos un par de funciones: una que modifique el estado de nuestra variable no pública, pero solo si tiene permisos de propietario, y la otra, que devuelve el mensaje de la cadena. Las definiciones son las siguientes:

Ambos son públicos, por lo que cualquiera puede intentar llamarlos, pero para el primero, solo la dirección del propietario no causará una reversión. Si usted es el propietario y se llama a la función, la cadena se guarda en nuestra variable Owner (con letras mayúsculas) y también devolverá un valor verdadero que podemos verificar en la transacción.

Como la variable Owner no es pública y no tiene un Getter, necesitamos una función que devuelva el valor de la variable sin cambiar el estado de la cadena de bloques. Esta es la segunda función.

También crearemos una función alternativa que emite un evento si alguien llama erróneamente nuestro contrato

Finalmente, agregamos una capacidad destruible al contrato en el que el propietario es el único que puede ejecutarlo.

Nuestro Token simple está terminado. El código todo juntosdebería verse

Creando la Migración

Para cada contrato, necesitamos decirle a Truffle qué contrato es el que queremos implementar y dónde podemos encontrarlo. Esto se hace a través de un archivo de migración en la carpeta ~ / Truffle / migrations.

La migración 02_deploy_token.js debería verse como

Hemos configurado Truffle, nuestro nodo está sincronizado, nuestro contrato ya está escrito y nuestra migración configurada; es tiempo de implementación.

Implementación

Si hemos detenido nuestro nodo anteriormente, lo pondremos nuevamente en línea y luego lo conectaremos con Truffle con

Allí, compilamos nuestro contrato con

No debemos recibir ningún error o advertencia para nuestro contrato. Luego migramos nuestro contrato con

Dado que el tiempo es caro, podemos ejecutar ambos comandos en una línea con

El contrato de migración se implementará primero. Truffle nos proporciona los hashes de transacción de cada operación, por lo que podemos verificar los detalles o los registros más adelante. Aquí está el resultado completo que he recibido

Si verificamos las transacciones, podemos calcular el costo de gas de todo el proceso de implementación. En mi caso, fue: gas 2340788 (277462 + 42008 + 1994310 + 27008).

Entonces, al cambiarlo a SBTC real, obtenemos 2340788 * 183000000/10 ^ 18 = 0,000428364 SBTC. Eso es alrededor de ~ 4 USD en el momento de escribir este artículo.

Nuestro contrato ahora está implementado en 0xc341678c01bcffa4f7362b2fceb23fbfd33373ea.

Felicidades!

Interacción con el contrato

Simplificación de sintaxis

Con la dirección dada por la migración de Truffle, y con la ABI del contrato, creamos una instancia de la misma para que la sintaxis sea más fácil para manejar las funciones. Para hacer esto, después de implementarlo, escribimos

En caso de que el contrato ya esté implementado, y conociendo su dirección y ABI, podemos simplemente hacer

Donde Contract_ABI es el ABI comprimido en una línea y Contract_ADDRESS no necesita explicación.

Creé 2 cuentas antes, y ahora las cambiamos de nombre por conveniencia

acc0 es el que implementó el contrato. Acc0 se agregó a los archivos de configuración truffle.js y node.conf.

Control de propiedad

Primero probaremos la función de propiedad de nuestro contrato utilizando la biblioteca que hemos discutido.

Si llamamos a la función getON desde cualquier cuenta, dado que es pública y no tiene ningún problema de propiedad, obtenemos

Ahora, la función setON tiene una propiedad de propiedad. Cualquier transacción hecha desde una cuenta diferente será descartada. Vemos, por ejemplo, que intentar firmar el contrato con mi nombre desde acc1 no cambiará su valor.

Con el hash de la transacción vemos que el valor devuelto era falso y la función no se ejecutó correctamente. Volviendo a llamar a la función getON, vemos que la variable no cambió su valor.

Firmando ahora la misma transacción, pero desde la cuenta del propietario acc0, obtenemos un estado ‘0x01’ y la función se ejecuta correctamente.

Volviendo a llamar a la función getON, vemos que la biblioteca de propiedad funcionó como esperábamos.

Ownable.sol también tiene una función que nos permite cambiar el propietario del contrato a otra dirección. No lo usaremos Sin embargo, su uso es el siguiente

Con eso, acc1 sería el nuevo propietario del contrato.

Pasemos al Token.

Operaciones del Token

Lo primero que hacemos es verificar si los saldos del Token fueron asignados correctamente en la creación del contrato.

Comprobamos nuestros saldos en cada cuenta de esta manera:

Entonces podemos ver que todos los tokens fueron asignados correctamente a nuestra cuenta inicial.

La primera transacción que haremos es transferir tres tokens a la segunda cuenta, acc1, tres veces.

Para hacerlo para la primera transacción

Vemos que los tokens tomados de nuestra cuenta de implementación tenían la misma cantidad que los recibidos en el acc1.

Con el contrato StandardToken también obtenemos permisos de permisos para gastar tokens en nombre de cierta cuenta, en este caso, acc1. Si queremos hacer esto antes de obtener la aprobación, la transacción fallará (estado ‘0x00’)

Después de verificar que acc0 no puede enviar desde acc1

Autorizamos a acc0 a gastar 10 tokens en nombre de acc1, a partir de una transacción realizada por acc1

En el registro de salida, vemos que la función se completó con éxito con verdadero y el registro muestra la cantidad permitida para acc0 para gastos. Comprobando con tolerancia

Ahora si ejecutamos nuevamente la transacción de gasto

obtenemos una transacción exitosa con el estado ‘0x01’.

Comprobando los saldos de nuevo

Por último, si firmamos una transacción llamando a una función que no está disponible, se llamará a nuestra función alternativa. Firmando una transacción como

Nos devolverá un registro cuyos datos representan la cadena “Error 404: Function not found :P” en hexadecimal

( '0x00...00204572726f72203430343a2046756e6374696f6e206e6f7420666f756e64203a50').

Nuestra última función, que no vamos a ejecutar por razones obvias, es la función de suicidio. Necesitamos que el contrato no se destruya para mostrar las transacciones. Para llamarlo, el propietario debe hacer

Conclusiones

En esta segunda parte del tutorial, he mostrado un ejemplo para desarrollar un contrato inteligente simple en la red RSK. Hemos visto cómo

  • Importar bibliotecas y contratos desde el paquete OpenZeppelin,
  • Crear un Token simple usando estas bibliotecas,
  • Configurar el proceso de migración para Truffle,
  • Implementar nuestro contrato a la red principal de RSK,
  • Interactuar con el contrato a través de diferentes cuentas,
  • Verificar el registro del bloque para obtener realimentacion sobre las transacciones.

Como hemos visto, el uso de una red RSK para el despliegue e interacción de Solidity Smart Contracts es prácticamente el mismo que en un nodo Ethereum. Por supuesto, esta sigue siendo una red beta y se esperan problemas e inconvenientes, principalmente en el nodo, pero el equipo de RSK Labs está haciendo un gran trabajo para resolverlos tan rápido como puedan cuando aparezcan. Con el tiempo, se logrará robustez.

Estén atentos para el próximo artículo (en ingles), donde hablaré sobre la implementación y la interacción con Web3.py.


  •  
  •  
  •  
  •  
  •  
  •  
  •