Crea tu Pokedex sencilla con Solidity y Remix

Sin conocimientos en Solidity, vamos a crear dos pequeños Smart Contracts simulando una Pokedex, que desplegaremos y podremos realizar pruebas desde nuestro local o con el editor online de Remix. ¿Preparado para desarrollar tu primer Smart Contract?

Lo ideal, sería que aprendiésemos anteriormente Solidity, pero con este breve artículo y si tenemos conocimientos de programación, podremos entender el código e ir aprendiendo Solidity sin tener que esperar para crear nuestros Smart Contracts.

Deberéis haber leído el anterior artículo sobre Remix que habíamos publicado anteriormente, para saber como usar el IDE y como Desplegar.

En el ejemplo que vamos a llevar a cabo, vamos a poder dar de alta pokemon en una pokedex y consultar el listado que hayamos ido añadiendo. Podéis acceder a todo el contenido, a través de Github, y a través de GIST en Gist de Github.

El plugin esta puesto con Javascript, porque no tiene solidity. Como podréis apreciar haremos uso de:

  • Importar
  • Contract
  • Structs
  • Tipos:
    • Arrays
    • Strings
    • Memory
    • Internal y External
    • Public
    • Address
  • Require
  • Funciones
  • Modifier
  • Memory
  • Herencias
  • Funciones propias
    • msg.sender

Gran parte de estas funcionalidades, ya las conoceréis de otros lenguajes y otras las iréis conociendo y las posibilidades que nos aportan.

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;

contract Pokemon {

    // Cualidades para cada pokemon
    struct cualidades {
        string name;
        string tipo_pokemon;
        string ataque;
    }

    // Listado de pokemon que tenemos
    cualidades [] pokedex;

    // Añadir un nuevo pokemon a la pokedex
    function capturar_nuevo_pokemon(string memory _name, string memory _tipo_pokemon, string memory _ataque) internal {
        pokedex.push(cualidades(_name, _tipo_pokemon, _ataque));
    }
}

contract Entrador_pokemon is Pokemon {
    
    // Quien es el propietario de este entrenador pokemon
    address public owner;

    // Asignamos el valor al entrenador Pokemon
    constructor () {
        owner = msg.sender;
    }

    // Conseguimos un pokemon para nuestra pokedex
    function lanzar_pokeball(string memory _nombrePokemon, string memory _tipo_pokemon, string memory _ataque) external {
        require (keccak256(bytes(_nombrePokemon)) != keccak256(bytes(" ")), "Debes poner el nombre al pokemon");
        capturar_nuevo_pokemon(_nombrePokemon, _tipo_pokemon, _ataque);
    }

    // Modifer para poner algún filtro. Solo permitimos conseguir pokemon al owner
    modifier onlyOwner() {
        require(owner == msg.sender, "No tienes permisos para capturar estos pokemon para esta Pokedex");
        _;
    }

    // Obtenemos el listado de pokemon de la pokedex. En el caso de que el owner sea diferente, no le dejaremos ver el resultado
    function getPokedex() public view onlyOwner returns (cualidades [] memory) {
        return pokedex;
    }
}

Como podemos apreciar en el código, hemos creado dos contract, que serían los dos objetos que desplegaremos y haremos uso. En el caso de Pokemon, le hemos asignado tres propiedades que deberemos instanciar posteriormente, cuando los demos de alta. Además, aunque no sea lo más apropiado para tener el código bien organizado, hemos includio un array de dichas cualidades, y lo hemos llamo pokedex, porque será donde iremos almacenando todos los pokemon que demos de alta.

Por último, tenemos una función, que será la encargada de ir añadiendo en el array, los pokemon con los valores que les pasemos. Podéis comprobar que en en dicha función hacemos uso de la propiedad memory, que es propia de solidity, con el objetivo de indicar que dichas propiedades no sean persistentes. Sería como hacer uso de la memoria RAM. Y además, también hemos indicado que será internal, que nos viene a indicar que solo se podrá hacer uso de esta función desde dentro del contract, es decir, que cuando despleguemos los contratos inteligentes, no podremos hacer uso de ella.

El contract Entrenador_pokemon, podemos ver que con la palabra is, estamos haciendo uso de herencia con el anterior contract, con el objetivo de hacer uso de las funciones y el resto de las propiedades. En este apartado, destacaremos la parte del address, donde estamos guardaron al autor, que posteriormente haremos uso en la función de getPokedex, donde al usar un modifier, indicamos que solo podrá ser usado por el owner anteriormente guardado.

En lo referente a la función de lanzar_pokeball, utilizamos un require donde comprobamos que el nombre del pokemon no es un espacio en blanco, y en dicho caso, lanzamos la función de capturar_nuevo_pokemon, que habíamos creado en el contract anterior, donde estamos heredando todas sus funcionalidades.

Una vez hayamos desplegado la aplicación, si habéis seguido el tutorial del anterior artículo, podréis ver en la pantalla:

Los botones que están de color naranja, nos vienen a indicar, que nos costará GAS utilizarlos. Los de color azul, son gratis. Como podéis comprobar, podréis realizar pruebas con diferentes datos, y a través del log del IDE, comprobar que esos datos se están añadiendo correctamente.