Artículo original escrito por: Nico
Artículo original: How to Make an NFT in 14 Lines of Code
Traducido y adaptado por: Michael Liendo

Si eres un desarrollador interesado en el desarrollo de Blockchain, debes saber algo sobre los NFT o tokens no fungibles. Entonces, en este artículo, aprenderemos sobre la ingeniería detrás de ellos para que puedas comenzar a construir el tuyo propio.

Al final del proyecto, tendras tu propia billetera Ethereum con un nuevo NFT. Este tutorial es apto para principiantes y no requiere ningún conocimiento previo de la red Ethereum o contratos inteligentes.

image-46
El contrato NFT solo tiene 14 líneas de código

¿Qué es un NFT?

NFT significa token no-fungible. Está cita de ethereum.org explica esto:

Los NFTs son tokens que podemos usar para representar la propiedad de varios articulos únicos.
Ellos nos dejan tokenisar arte, coleccionables, incluso bienes raíces.
Ellos pueden tener un solo dueño a la vez, y está asegurado por la blockchain de Ethereum.
Nadie puede modificar el registro del dueño o copiar/pegar un nuevo NFT para que exista.

¿Qué es un estándar de un NFT o ERC-721?

El ERC-721 es el estándar NFT más común. Si tu contrato inteligente implementa ciertos métodos API estandarizados, puede denominarse contrato de token no fungible ERC-721.

Estos métodos se especifican en el EIP-721. Los proyectos de código abierto como OpenZeppelin han simplificado el proceso de desarrollo al implementar los estándares ERC más comunes como una biblioteca reutilizable.

¿Qué es minar un NFT?

Al acuñar un NFT, publica un token único en una cadena de bloques. Este token es una instancia de su contrato inteligente.

Cada token tiene un tokenURI único, que contiene metadatos de su activo en un archivo JSON que se ajusta a cierto esquema. Los metadatos es donde almacena información sobre su NFT, como nombre, imagen, descripción y otros atributos.

Un ejemplo del archivo JSON para el "Esquema de metadatos ERC721" se ve así:

{
	"attributes": [
		{
			"trait_type": "Shape",
			"value": "Circle"
		},
		{
			"trait_type": "Mood",
			"value": "Sad"
		}
	],
	"description": "A sad circle.",
	"image": "https://i.imgur.com/Qkw9N0A.jpeg",
	"name": "Sad Circle"
}

¿Cómo almaceno los metadatos de mi NFT?

Hay tres maneras para almacenar los metadatos del NFT

Primero, puedes almacenar la información en la cadena. En otras palabras, puedes ampliar su ERC-721 y almacenar los metadatos en la cadena de bloques, lo que puede resultar costoso.

El segundo método es usar IPFS.  

Y la tercera forma es simplemente hacer que tu API devuelva el archivo JSON.

Por lo general, se prefieren los métodos primero y segundo, ya que no puedes modificar el archivo JSON subyacente.  Para el alcance de este proyecto, optaremos por el tercer método.

Lo que estaremos construyendo

nft

En este tutorial, crearemos y acuñaremos nuestro propio NFT.  Es apto para principiantes y no requiere ningún conocimiento previo de la red Ethereum o contratos inteligentes.  Aún así, tener una buena comprensión de esos conceptos lo ayudará a comprender lo que sucede detrás de escena.

En un próximo tutorial, crearemos una aplicación web React completamente funcional donde puede mostrar y vender sus NFT.

Este proyecto está escrito intencionalmente con un código fácilmente comprensible y no es adecuado para su uso en producción.

Requisitos Previos

MetaMask

image

Necesitamos una dirección de Ethereum para interactuar con nuestro contrato inteligente.  Usaremos Metamask como nuestra billetera.  Es una billetera virtual gratuita que administra sus direcciones de Ethereum. Lo necesitaremos para enviar y recibir transacciones (lea más sobre eso aquí).  Por ejemplo, acuñar un NFT es una transacción.

Descarga su extensión de Chrome y su aplicación móvil.  Necesitaremos ambos ya que la extensión de Chrome no muestra sus NFT.

image-1

Asegúrate de cambiar la red a "Ropsten Test Network" para fines de desarrollo.  Necesitarás algo de Eth para cubrir las tarifas de implementación y acuñación de tu NFT.  Dirígete a Ropsten Ethereum Faucet e ingresa tu dirección.  Pronto deberías ver algunos Eth de prueba en tu cuenta de Metamask.

image-2

Alchemy

Para interactuar con la red Ethereum, deberás estar conectado a un nodo Ethereum.

Ejecutar tu propio Nodo y mantener la infraestructura es un proyecto en sí mismo. Afortunadamente, existen proveedores de nodos como servicio que alojan la infraestructura por usted.  Hay muchas opciones como Infura, BlockDaemon y Moralis.  Usaremos Alchemy como nuestro proveedor de nodos.

Dirígete a su sitio web, crea una cuenta, elige Ethereum como tu red y crea tu aplicación.  Elige Ropsten como tu red.

image-3

En su tablero, haz clic en "ver detalles" en su aplicación, luego haz clic en "ver clave".  Guarda tu clave http en algún lugar, ya que la necesitaremos más adelante.

image-4

NodeJS/NPM

Nosotros usaremos Node.js para este proyecto. Si no lo tienes instalado sigue este simple tutorial de freeCodeCamp

Iniciamos el proyecto

En tu terminal, ejecuta este comando para crear un nuevo directorio para tu proyecto

mkdir nft-project
cd nft-project

Ahora, haremos otro directorio, ethereum/, dentro de nft-project/, y inicializamos con Hardhat. Hardhat es una herramienta de desarrollo que facilita la implementación y prueba de su software Ethereum.

mkdir ethereum
cd ethereum
npm init

Contesta las preguntas como quieras.  Luego, ejecuta esos comandos para hacer un proyecto Hardhat:

npm install --save-dev hardhat
npx hardhat

Verás este mensaje:

888    888                      888 888               888
888    888                      888 888               888
888    888                      888 888               888
8888888888  8888b.  888d888 .d88888 88888b.   8888b.  888888
888    888     "88b 888P"  d88" 888 888 "88b     "88b 888
888    888 .d888888 888    888  888 888  888 .d888888 888
888    888 888  888 888    Y88b 888 888  888 888  888 Y88b.
888    888 "Y888888 888     "Y88888 888  888 "Y888888  "Y888

Welcome to Hardhat v2.0.8

? What do you want to do? …
  Create a sample project
❯ Create an empty hardhat.config.js
  Quit

Selecciona crear un hardhat.config.js vacío.  Esto generará un archivo hardhat.config.js vacío que luego actualizaremos.

Para la aplicación web, usaremos Next.js para inicializar una aplicación web completamente funcional.  Vuelve al directorio raíz nft-project/ e inicializa una aplicación estándar de Next.js llamada web:

cd ..
mkdir web
cd web
npx create-next-app@latest

Tu proyecto ahora se ve así:

nft-project/
	ethereum/
	web/

¡Impresionante!  Estamos listos para sumergirnos en la codificación real.

Cómo definir nuestras variables .env

¿Recuerdas la clave de Alchemy que tomamos de nuestro proyecto de prueba anterior?  Lo usaremos junto con las claves públicas y privadas de nuestra cuenta Metamask para interactuar con la cadena de bloques.

Ejecuta los siguientes comandos, crea un archivo llamado .env dentro de tu directorio `/ethereum` instala dotenv.  Los usaremos más tarde

cd ..
cd ethereum
touch .env
npm install dotenv --save

Para tu archivo .env, ingresa la clave que has exportado de Alchemy y sigue estas instrucciones para obtener la clave privada de tu Metamask.

Aquí está tu archivo .env:

DEV_API_URL = YOUR_ALCHEMY_KEY
PRIVATE_KEY = YOUR_METAMASK_PRIVATE_KEY
PUBLIC_KEY = YOUR_METAMASK_ADDRESS

El contrato inteligente para NFT

Ve a la ethereum/carpeta y crea dos directorios más: contratos y scripts. Un proyecto de casco simple contiene esas carpetas.

  • contracts/contiene los archivos fuente de sus contratos
  • scripts/contiene los scripts para implementar y acuñar nuestros NFT
mkdir contracts
mkdir scripts

Luego, instala OpenZeppelin. OpenZeppelin Contract es una biblioteca de código abierto con código reutilizable probado previamente para facilitar el desarrollo de contratos inteligentes.

npm install @openzeppelin/contracts

Finalmente, escribiremos el contrato inteligente para nuestro NFT.  Navega a tu directorio de contratos y cree un archivo titulado EmotionalShapes.sol.  Puedes nombrar tus NFT como mejor le parezca.

Los .solLa extensión hace referencia al lenguaje Solidity, que es el que usaremos para programar nuestro Smart Contract.  Solo escribiremos 14 líneas de código con Solidity, así que no te preocupes si no lo has visto antes.

Comienza con este artículo para obtener más información sobre los lenguajes de contratos inteligentes. También puedes saltar directamente a esta hoja de trucos de que contiene la sintaxis principal.

cd contracts
touch EmotionalShapes.sol

Este es nuestro contrato inteligente:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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

contract EmotionalShapes is ERC721 {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIdCounter;

    constructor() ERC721("EmotionalShapes", "ESS") {}

    function _baseURI() internal pure override returns (string memory) {
        return "YOUR_API_URL/api/erc721/";
    }

    function mint(address to)
        public returns (uint256)
    {
        require(_tokenIdCounter.current() < 3); 
        _tokenIdCounter.increment();
        _safeMint(to, _tokenIdCounter.current());

        return _tokenIdCounter.current();
    }
}

Repasemos el código y entendamos lo que está pasando.

  1. En la parte superior del archivo, especificamos qué módulo de OpenZeppelin importar.  Necesitamos el contrato ERC721 ya que es la 'base' de nuestro contrato inteligente.  Ya ha implementado todos los métodos especificados en EIP-721 para que podamos usarlo de manera segura.
  2. Un contador es útil para generar identificadores incrementales para nuestros NFT.  Nombramos la variable _tokenIdCounter
  3. En el constructor, inicializamos nuestro ERC721 con su nombre y su símbolo.  Elegí EmotionalShapes y ESS.
  4. Anulamos la función _baseURI predeterminada al devolver la nuestra. Llegaremos a construir eso en un segundo.  En resumen, es la URL que se agregará como 'prefijo' a todos nuestros tokenURI.  En el ejemplo anterior, los metadatos de nuestras NFT vivirán en un archivo JSON en YOUR_API_URL/api/erc721/1.
  5. Implementamos la función 'mint'. Es la función que le permite publicar una instancia de este contrato inteligente en la cadena de bloques.  Requiero el _tokenIdCountervariable sea inferior a 3, ya que solo crearé tres instancias de mi NFT.  Puede eliminar eso si desea acuñar más.
  6. Finalmente, dentro de la función mint, incrementamos el _tokenIdCountervariable por 1, por lo que nuestro id será 1, seguido de 2, seguido de 3. Luego, llamamos a la función proporcionada por OpenZeppelin _safeMintpara publicar el token.

No te preocupes si te sientes perdido.  Puedes asistir a un taller dirigido por voluntarios de freeCodeCamp, donde invitamos a desarrolladores de niveles de habilidad similares para construir cosas juntos, incluido este proyecto NFT.

Los eventos son gratuitos y a distancia, por lo que puedes consultar cualquier duda directamente. Puedes registrarte aquí . Los asientos son limitados, por lo que se te invitará a los próximos eventos disponibles.

Cómo construir los metadatos para nuestro NFT

Como se mencionó anteriormente, hay tres formas principales de almacenar su tokenURI.  Construiremos un punto final de API simple que se resolverá en la información de nuestro NFT como JSON.

Nuestro proyecto Next.js nos brinda una forma práctica de desarrollar rutas de API.  Ve a la web/carpeta, busque la api/ carpeta dentro de la pages/carpeta, y hacer nuestra dinámica [id].jsruta en un erc721/ carpeta (lee más sobre el enrutamiento aquí ):

// web/pages/api/erc721/[id].js

const metadata = {
  1: {
    attributes: [
      {
        trait_type: "Shape",
        value: "Circle",
      },
      {
        trait_type: "Mood",
        value: "Sad",
      },
    ],
    description: "A sad circle.",
    image: "https://i.imgur.com/Qkw9N0A.jpeg",
    name: "Sad Circle",
  },
  2: {
    attributes: [
      {
        trait_type: "Shape",
        value: "Rectangle",
      },
      {
        trait_type: "Mood",
        value: "Angry",
      },
    ],
    description: "An angry rectangle.",
    image: "https://i.imgur.com/SMneO6k.jpeg",
    name: "Angry Rectangle",
  },
  3: {
    attributes: [
      {
        trait_type: "Shape",
        value: "Triangle",
      },
      {
        trait_type: "Mood",
        value: "Bored",
      },
    ],
    description: "An bored triangle.",
    image: "https://i.imgur.com/hMVRFoJ.jpeg",
    name: "Bored Triangle",
  },
};

export default function handler(req, res) {
  res.status(200).json(metadata[req.query.id] || {});
}

Por el bien de este proyecto, hice que el código fuera lo más comprensible posible.  Esto definitivamente no es adecuado para la producción (no use una URL de Imgur para su NFT).  Asegúrese de definir los metadatos para todos los NFT que pretende acuñar.

Ahora, vaya al directorio web e inicie su aplicación Next.js con este comando:

npm run dev

Tu aplicación debería estar ejecutándose en localhost:3000. Para asegurarse de que nuestro punto final funcione, vaya a http://localhost:3000/api/erc721/1 y debería resolverse con un objeto JSON de los metadatos de su primer NFT.

Cómo exponer los metadatos para nuestro NFT

Dado que tu aplicación está alojada localmente, otras aplicaciones no pueden acceder a ella. Usando una herramienta como ngrok , podemos exponer nuestro host local a una URL de acceso público.

imagen-39
  1. Ve a ngrok.com y complete el proceso de registro
  2. Descomprimir el paquete descargado
  3. En tu terminal, asegúrete de ingresar a la carpeta donde descomprimió su paquete ngrok
  4. Sigue las instrucciones en tu tablero y ejecuta
./ngrok authtoken YOUR_AUTH_TOKEN

5. Luego, ejecuta este comando para crear un túnel a tu aplicación web alojada en localhost:3000

./ngrok http 3000

6. ¡Ya casi llegas!  En tu terminal, deberías ver algo como esto:

ngrok by @inconshreveable                                                                            (Ctrl+C to quit)
                                                                                                                     
Session Status                online                                                                                 
Account                       YOUR_ACCOUNT (Plan: Free)                                                                       
Version                       2.3.40                                                                                 
Region                        United States (us)                                                                     
Web Interface                 http://127.0.0.1:4040                                                                  
Forwarding                    http://YOUR_NGROK_ADDRESS -> http://localhost:3000                             
Forwarding                    https://YOUR_NGROK_ADDRESS -> http://localhost:3000                             

Ir a YOUR_NGROK_ADDRESS/api/erc721/1para asegurarse de que su terminal funcione correctamente.

Cómo implementar nuestro NFT

Ahora que hemos hecho todo el trabajo preliminar (oof), volvamos a nuestro ethereum/carpeta y prepárate para implementar nuestro NFT.

Cambiar el _baseURIfuncionar en su ethreum/contracts/YOUR_NFT_NAME.solarchivo para devolver su dirección ngrok.

// ethereum/conrtacts/EmotionalShapes.sol

contract EmotionalShapes is ERC721 {
...
	function _baseURI() internal pure override returns (string memory) {
		return "https://YOUR_NGROK_ADDRESS/api/erc721/";
	}
...
}

Para implementar nuestro NFT, primero necesitaremos compilarlo usando Hardhat . Para facilitar el proceso, instalaremos ethers.js .

npm install @nomiclabs/hardhat-ethers --save-dev

Actualicemos nuestro hardhat.config.js:

require("dotenv").config();
require("@nomiclabs/hardhat-ethers");

module.exports = {
  solidity: "0.8.0",
  defaultNetwork: "ropsten",
  networks: {
    hardhat: {},
    ropsten: {
      url: process.env.DEV_API_URL,
      accounts: [`0x${process.env.PRIVATE_KEY}`],
    },
  },
};

Para obtener más información sobre el archivo de configuración del casco, consulte su documentación. Hemos configurado la red ropsten con nuestra URL de Alchemy y le hemos proporcionado la clave privada de su cuenta metamask.

Finalmente, ejecuta:

npx hardhat compile

Esto permite que hardhat genere dos archivos por contrato compilado.  Deberíamos ver una recién creada artifacts/ carpeta que contiene sus contratos compilados en el contracts/carpeta. Para obtener más información sobre cómo funciona, lea este tutorial del equipo de Hardhat.

Ahora, escribamos un script para implementar finalmente nuestro NFT en la red de prueba.  En tus scripts/carpeta, cree un archivo llamado deploy.js.

// ethereum/scripts/deploy.js

async function main() {
  const EmotionalShapes = await ethers.getContractFactory("EmotionalShapes");
  const emotionalShapes = await EmotionalShapes.deploy();

  console.log("EmotionalShapes deployed:", emotionalShapes.address);
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

Este código está inspirado en el tutorial de implementación .

A ContractFactoryen ethers.js es una abstracción utilizada para implementar nuevos contratos inteligentes, por lo que EmotionalShapesaquí hay una fábrica para instancias de nuestro contrato de token.  Vocación deploy()en un ContractFactorycomenzará la implementación y devolverá un Promiseque se resuelve en un Contract.  Este es el objeto que tiene un método para cada una de sus funciones de contrato inteligente.

Cómo ver el NFT en la cadena de bloques

Ejecute el script de implementación:

node ./scripts/deploy.js

Debes ver en tu terminal EmotionalShapes deployed: SOME_ADDRESS.  Esta es la dirección donde se implementa su contrato inteligente en la red de prueba de ropsten.

Si te diriges a https://ropsten.etherscan.io/address/SOME_ADDRESS, debes ver tu NFT recién implementado.  ¡Sí!  ¡Lo hiciste!

Cómo acuñar su NFT

Ahora que has implementado su NFT, ¡es hora de acuñarlo tu mismo!  Crear un nuevo archivo llamado mint.jsen tu carpeta scripts/.  Usaremos ethers.js para ayudarnos.

Comience agregando el ethers.jspaquete:

npm install --save ethers

Luego, llena el mint.jsexpediente:

require("dotenv").config();
const { ethers } = require("ethers");

const contract = require("../artifacts/contracts/EmotionalShapes.sol/EmotionalShapes.json");
const contractInterface = contract.abi;

// https://docs.ethers.io/v5/api/providers
const provider = ethers.getDefaultProvider("ropsten", {
  alchemy: process.env.DEV_API_URL,
});

// https://docs.ethers.io/v5/api/signer/#Wallet
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);

//https://docs.ethers.io/v5/api/contract/contract
const emotionalShapes = new ethers.Contract(
  YOUR_NFT_ADDRESS,
  contractInterface,
  wallet
);

const main = () => {
  emotionalShapes
    .mint(process.env.PUBLIC_KEY)
    .then((transaction) => console.log(transaction))
    .catch((e) => console.log("something went wrong", e));
};

main();

He dejado comentarios donde puedes encontrar más información sobre los diferentes métodos.  Primero tomamos la interfaz del contrato (ABI).  De ethereum.org:

Una interfaz binaria de aplicación, o ABI, es la forma estándar de interactuar con contratos en el ecosistema Ethereum, tanto desde fuera de la cadena de bloques como para interacciones de contrato a contrato.

Tu ABI define cómo otros interactúan con tu contrato.  Luego, creamos nuestro proveedor con Alchemy (recuerda el nodo como servicio). Finalmente, inicializamos nuestra billetera con nuestra clave privada.

los main() función llama a la mintmétodo en el contrato inteligente que acabábamos de implementar.  Él mint método toma sólo un parámetro, to, que indican el receptor del token.  Como estamos acuñando para nosotros mismos, ponemos la dirección pública de nuestra cuenta de Metamask.

Si todo va bien, deberías ver la transacción registrada en tu terminal.  Toma el hash propiedad e ir a https://ropsten.etherscan.io/tx/YOUR_HASH.  ¡Deberías ver la transacción de acuñación allí!

Cómo ver el NFT en su billetera Metamask

Debes comenzar descargando la versión móvil de Metamask.  Luego, inicie sesión en su cuenta.

Deberías ver una pestaña de NFT junto con un botón para agregar NFT.  Has clic en el botón e ingresa la dirección de tu contrato inteligente junto con las identificaciones que has acuñado.  Si has seguido el tutorial, debes comenzar con una identificación de 1.

IMG_0376
Ver NFT en su billetera Metamask

Conclusión

¡Felicidades! Acabas de acuñar tu propio NFT.  En la siguiente parte del proyecto, construiremos la aplicación React front-end para interactuar con nuestro contrato.  El objetivo final es crear una aplicación web completamente funcional en la que pueda vender sus propios NFT.

Por último, puedes unirse a nuestros talleres en vivo con voluntarios de freeCodeCamp donde construiremos este proyecto junto con otros desarrolladores.

Los eventos son gratuitos para todos en todo el mundo y las invitaciones se envían por orden de llegada. Si deseas dirigir los talleres, envíeme en Twitter , ¡nos encantaría contar con usted! También organizamos otro tipo de eventos como ferias de contratación y encuentros sociales.

Déjame saber lo que quieres construir.  Los NFT aún están en pañales y las ideas novedosas son más que bienvenidas.  ¡No puedo esperar a ver qué loca idea tienes!