DEV Community

Nox Klax
Nox Klax

Posted on

Reduce casi a la mitad el costo de gas para el minting de tu próximo proyecto NFT

Minting Gas Fees

Hoy te voy a hablar de los costos de gas y por qué con tan solo hacer un ajuste simple en tu contrato vas a reducir los costos de minting para tu próxima colección secuencial de NFTs.

Costo de gas

Empecemos explicando brevemente qué es el costo de gas. El costo de gas es un "pequeño" valor que pagas cada vez que quieres hacer una operación de escritura en la blockchain.

Este costo puede variar dependiendo de varios factores:

  • Congestión de la red. Si hay muchas transacciones pendientes por ejecutar en la red, tus costos de gas serán más altos.
  • Número de operaciones de escritura.
  • Tamaño de la información que vamos a almacenar.

Hay factores que están fuera de nuestro alcance, como la congestión de la red, sin embargo, la forma en que almacenamos la información en la blockchain debería ser optimizada al máximo. Especialmente para proyectos pequeños.

Posiblemente si estás tratando de transferir o mintear un NFT con un valor de miles de dólares o más, poco o nada te importe pagar un costo de gas alto. Pero este no es el caso de la mayoría de proyectos.

¿No te ha pasado que intentas mintear un NFT de costo bajo y al intentar hacerlo terminas pagando más por gas que lo que pagas por el NFT en sí?

¿Cómo podemos disminuir los costos de minting de nuestros NFTs para hacerlos más atractivos a posibles compradores?

Entendiendo un poco más el problema

Ya vimos los factores que más influyen en el costo de gas. Pero, ¿cómo podemos disminuirlos?

Algunos proyectos han optado por desplegarse sobre la red de Polygon (u otras) para reducir los costos de minting casi en su totalidad.

Pero, ¿no podríamos tal vez optimizar el código para disminuir los costos de gas por eficiencia? La respuesta es sí. Es muy probable que una pequeña optimización nos ahorre muchos costos para nuestro próximo proyecto.

Si has escrito algunos proyectos con Solidity lo más probable es que hayas escuchado y usado los boilerplates de OpenZeppelin. Son una excelente base para la mayoría de proyectos.

Pero, como casi todo en la vida, los boilerplates de OpenZepelin pueden ser optimizados para casos de uso más específicos.

El principal problema es que un número muy alto de contratos que están usando OpenZeppelin como base para proyectos NFTs, están heredando de ERC721Enumerable.

Este contrato nos permite crear una colección de NFTs muy fácilmente y él mismo se encarga de llevar un control del supply y de relacionar los holders con los NFTs.

Para lograr esto, lo único que debes hacer es escribir esto en tu función de minting:

    function mintNFT() public {
        ...
        uint256 mintIndex = totalSupply() + 1;
        _safeMint(msg.sender, mintIndex);
        ...
    }
Enter fullscreen mode Exit fullscreen mode

BOOM! Con tan solo 2 líneas de código podrás mintear un nuevo NFT y automáticamente quedará relacionado con el usuario.

Sin embargo, heredar de ERC721Enumerable hace que incluyas en tu proyecto mucho más código del que necesitas para hacer este proceso y sobretodo, terminas escribiendo muchísima más información en la blockchain.

La solución al problema

¿Qué podemos hacer entonces para mejorar este proceso?

La respuesta es eliminar la dependencia de ERC721Enumerable y hacer una implementación propia para llevar el conteo de nuestros NFTs minteados y la relación entre usuarios y tokens.

ERC721Enumerable incluye mucho más que la función totalSupply(), sin embargo, la mayoría de proyectos no hacen uso de estas funciones adicionales. (Si estás usando tokenOfOwnerByIndex() y tokenByIndex(), posiblemente te convenga seguir usando ERC721Enumerable de todas formas.)

Así que tratemos de escribir nuestra propia implementación.

En vez de heredar de ERC721Enumerable, heredemos de ERC721.

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract MyCoolProject is ERC721 {}
Enter fullscreen mode Exit fullscreen mode

Ahora necesitamos llevar el conteo por nuestra cuenta. Para hacer esto, usaremos otra utilidad de OpenZeppelin llamada Counters.

Importamos counters y dentro del contrato declaramos una variable que llevara la cuenta por nosotros:

import "@openzeppelin/contracts/utils/Counters.sol";

contract MyCoolProject is ERC721 {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;
}
Enter fullscreen mode Exit fullscreen mode

Luego en el constructor vamos a incrementar por primera vez nuestro counter:

    constructor() ERC721("My Cool Project", "MCP") {
        _tokenIds.increment();
    }
Enter fullscreen mode Exit fullscreen mode

Esto lo hacemos porque el contador iniciará por defecto en 0 y no queremos un NFT con id de 0, especialmente para validaciones futuras. Por lo tanto, al llamar _tokenIds.increment(); durante el constructor, nos aseguraremos que el primer NFT minteado tendrá el id 1.

Por último en nuestra función de minting:

    function mintNFT() public {
        ...
        uint256 newItemId = _tokenIds.current();
        _safeMint(msg.sender, newItemId);
        _tokenIds.increment();
        ...
    }
Enter fullscreen mode Exit fullscreen mode

Aquí tienes el Código completo de implementación mínima:

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract MyCoolProject is ERC721 {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;
    constructor() ERC721("My Cool Project", "MCP") {
        _tokenIds.increment();
    }

    function mintNFT() public {
        ...
        uint256 newItemId = _tokenIds.current();
        _safeMint(msg.sender, newItemId);
        _tokenIds.increment();
        ...
    }
}
Enter fullscreen mode Exit fullscreen mode

Resultados

Veamos los resultados de este experimento. Para esto, lo que hice fue escribir dos contratos identicos, salvo por los cambios que mencioné anteriormente.

Escribí un test que minteara 200 NFTs para cada contrato y estos fueron los resultados en costos de gas.

Resultados

En este caso la reducción promedio fue de más del 50%.

Recuerda, los costos de gas son una de las barreras más grandes en el ecosistema de Ethereum. Las personas detrás del proyecto está haciendo todo lo posible para disminuirlos, pero, nosotros deberíamos también intentar optimizar al máximo nuestros contratos.

Seguiré escribiendo sobre web3, solidity y smart contracts, asi que si te interesa, sígueme en twitter, es allí donde te podrás enterar más fácilmente de mi travesía por la web3.

https://twitter.com/NoxKlax

Discussion (0)