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.
¿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
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
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.
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.
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.
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.
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 contratosscripts/
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 .sol
La 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.
- 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.
- Un contador es útil para generar identificadores incrementales para nuestros NFT. Nombramos la variable
_tokenIdCounter
- En el constructor, inicializamos nuestro ERC721 con su nombre y su símbolo. Elegí EmotionalShapes y ESS.
- 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 enYOUR_API_URL/api/erc721/1
. - 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
_tokenIdCounter
variable sea inferior a 3, ya que solo crearé tres instancias de mi NFT. Puede eliminar eso si desea acuñar más. - Finalmente, dentro de la función mint, incrementamos el
_tokenIdCounter
variable por 1, por lo que nuestro id será 1, seguido de 2, seguido de 3. Luego, llamamos a la función proporcionada por OpenZeppelin_safeMint
para 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].js
ruta 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.
- Ve a ngrok.com y complete el proceso de registro
- Descomprimir el paquete descargado
- En tu terminal, asegúrete de ingresar a la carpeta donde descomprimió su paquete ngrok
- 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/1
para 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 _baseURI
funcionar en su ethreum/contracts/YOUR_NFT_NAME.sol
archivo 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 .
AContractFactory
en ethers.js es una abstracción utilizada para implementar nuevos contratos inteligentes, por lo queEmotionalShapes
aquí hay una fábrica para instancias de nuestro contrato de token. Vocacióndeploy()
en unContractFactory
comenzará la implementación y devolverá unPromise
que se resuelve en unContract
. 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.js
en tu carpeta scripts/. Usaremos ethers.js para ayudarnos.
Comience agregando el ethers.js
paquete:
npm install --save ethers
Luego, llena el mint.js
expediente:
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 mint
mé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
.
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!