How to Make an NFT in 14 Lines of Code

nft121212

If you are a developer interested in blockchain development, you should know something about NFTs or non-fungible tokens. In this article, we'll take a look at the engineering behind them so you can start building your own.

At the end of the project, you will have your own Ethereum wallet containing a new NFT. This tutorial is suitable for beginners and does not require any prior knowledge of the Ethereum network or smart contracts.

image 46

What are NFTs?

NFT stands for non-fungible token. This quote from ethereum.org explains it well :

NFTs are tokens that we can use to represent ownership of unique items. They let us tokenize things like art, collectibles, and even real estate. They can only have one official owner at a time and are protected by the Ethereum blockchain - no one can modify ownership records or copy/paste new NFTs.

What is the NFT standard or ERC-721?

ERC-721 is the most common NFT standard. If your smart contract implements certain standardized API methods, it can be called an ERC-721 non-fungible token contract.

These methods are specified in EIP-721 . Open source projects like OpenZeppelin simplify the development process by implementing the most common ERC standards as reusable libraries.

What is a minted NFT?

By minting an NFT, you issue a unique token on the blockchain. This token is an instance of your smart contract.

Each token has a unique tokenURI that contains your asset's metadata in a JSON file that conforms to a specific pattern. Metadata is where you store information about your NFT, such as name, image, description, and other attributes.

An example JSON file for "ERC721 Metadata Schema" looks like this:

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

How to store metadata of NFT?

There are three main ways to store NFT metadata.

First, you can store information on-chain. In other words, you could extend your ERC-721 and store the metadata on the blockchain, but that could be expensive.

The second way is to use IPFS .

A third approach is to have your API return a JSON file.

The first and second methods are usually preferred because you cannot adjust the underlying JSON file. For the scope of this project, we will choose the third approach.

For an excellent tutorial on using NFTs in IPFS, read this post from the Alchemy team .

what will we build

emotional shape

In this article, we will create and mint our own NFT. It is beginner-friendly and does not require any prior knowledge of the Ethereum network or smart contracts. Still, a good understanding of these concepts will help you understand what's going on behind the scenes.

In what follows, we'll build a fully functional React web application where you can display and sell your NFTs.

This project is intentionally written in easy-to-understand code and is not intended for production use.

prerequisites

MetaMask

image 32

We need an Ethereum address to interact with our smart contract. We will use Metamask as our wallet. This is a free virtual wallet that manages your Ethereum addresses. We will need it to send and receive transactions ( read more here ). For example, minting an NFT is a transaction.

Download the Chrome plugin and mobile app. We need both because the Chrome extension won't reveal your NFT.

image 34

For ease of development, change the network to "Ropsten Test Network". You will need some Eth to pay for deploying and minting the NFT. Go to the Ropsten Ethereum faucet and enter your address. You should see some test Eth in your Metamask account shortly.

image 35

Alchemy

To interact with the Ethereum network, you need to connect to an Ethereum node.

Running your own node and maintaining the infrastructure is a project in itself. Fortunately, there are Node-as-a-Service providers who host the infrastructure for you. There are many options such as Infura, BlockDaemon, and Moralis. We will use Alchemy as our node provider.

Head over to their website, create an account, choose Ethereum as your network and create your application. Select Ropsten as your network.

image 36

On your panel, click "view details" on the app, then click "view key". Save your http key somewhere as we'll need it later.

image 38

NodeJS/NPM

We will use NodeJS in our project. If you don't have it installed, follow this simple tutorial from freeCodeCamp .

Initialize the project

In your terminal, run the following command to create a new directory for your project:

mkdir nft-project
cd nft-project

Now, let's create another directory under nft-project/the directory ethereum/and initialize it with Hardhat . Hardhat is a development tool that allows you to easily deploy and test your Ethereum software.

mkdir ethereum
cd ethereum
npm init

Then, run these commands to create a Hardhat project:

npm install --save-dev hardhat
npx hardhat

You will see this prompt:

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

Choose to create an empty hardhat.config.js. This will generate an empty hardhat.config.jsfile, which we will update later.

For the web application, we'll use Next.js to initialize a fully functional web application. Go back to the root directory nft-project/, and initialize a directory called web, and the Next.js application:

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

Your project now looks like this:

nft-project/
	ethereum/
	web/

We're ready to dive into some real coding.

How to define our .env variables

Remember the Alchemy key we got from the test project earlier? We'll use this to interact with the blockchain along with our Metamask account's public and private keys.

Run the following commands to create a file named in your ethereum/directory .envand install dotenv . We'll use them later.

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

For your .envfile, enter the key you exported from Alchemy, then follow these instructions to get the private key for Metamask.

Here is your .env file:

DEV_API_URL = YOUR_ALCHEMY_KEY
PRIVATE_KEY = YOUR_METAMASK_PRIVATE_KEY
PUBLIC_KEY = YOUR_METAMASK_ADDRESS

Smart contract for NFT

Go to that ethereum/folder and create two more directories: contracts and scripts. A simple hardhat project contains these folders.

  • contracts/Contains the source file of the contract
  • scripts/Contains scripts to deploy and mint our NFT
mkdir contracts
mkdir scripts

Then, install OpenZeppelin. OpenZeppelin Contract is an open-source library with pre-tested reusable code that makes smart contract development easier.

npm install @openzeppelin/contracts

Finally, we will write a smart contract for the NFT. Go back to your contracts directory and create a file named EmotionalShapes.sol. You can name your NFT whatever you want.

This .solextension refers to the Solidity language, which we will use to write our smart contracts. We'll only write 14 lines of code using Solidity, so don't worry if you haven't seen it before.

cd contracts
touch EmotionalShapes.sol

Here is our smart contract:

// 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();
    }
}

Let's walk through the code and understand what's going on.

  1. At the top of the file, we specify the OpenZeppelin modules to import. We need the ERC721 contract as it is the "base" of our smart contract. It already implements all the methods specified in EIP-721 , so we can use it safely.
  2. Counters are useful for generating incremental IDs for our NFTs. We name the variable as_tokenIdCounter
  3. In the constructor we initialize our ERC721 with its name and symbol. I chose EmotionalShapes and ESS.
  4. We override the default _baseURIfunction by returning our own function. We'll build this in a second. All in all, it will be added as a "prefix" to URLs in all of our tokenURIs. In the example above, our NFT's metadata will be saved in a JSON file at YOUR_API_URL/api/erc721/1.
  5. We implemented the "mint" function. This function allows you to publish an instance of this smart contract on the blockchain. I require _tokenIdCounterthe variables to be less than 3 because I'm only going to create three instances of the NFT. You can delete it if you want to mint more.
  6. Finally, in the mint function, we _tokenIdCounterincrement the variable by 1, so our id will be 1, then 2, then 3. Then, we call a function provided by OpenZeppelin _safeMintto issue tokens.

How to build metadata for NFT

As mentioned earlier, there are three main ways to store the tokenURI. We'll build a simple API endpoint that parses the NFT's information into JSON.

Our Next.js project provides us with a convenient way to develop API routes. Go to web/the directory, find api/the directory , pages/under the directory, erc721/and create our dynamic [id].jsroute in the directory ([here](https://www.freecodecamp.org/news/p/18513919-9e93-4ab3 -9f52-2448aafa8835/develop API routes) read more about routing):

// 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.https://img.chengxuka.comur.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.https://img.chengxuka.comur.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.https://img.chengxuka.comur.com/hMVRFoJ.jpeg",
    name: "Bored Triangle",
  },
};

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

For this project, I made the code as easy to understand as possible. This is definitely not suitable for production (please don't use https://img.chengxuka.comur url for your NFT). Make sure to define metadata for any NFTs you intend to mint.

Now, change to the web directory and start the Next.js application with the following command:

npm run dev

Your application should be running on localhost:3000. To make sure our endpoint is working, visit http://localhost:3000/api/erc721/1, which should parse with a JSON object of your first NFT's metadata.

How to expose metadata for NFTs

Since your application is hosted locally, other applications cannot access it. Using tools like ngrok , we can expose our localhost to publicly accessible URLs.

image 39

  1. Visit ngrok.com and complete the registration process
  2. Unzip the downloaded package
  3. In your terminal, make sure you cd into the folder where you extracted the ngrok package
  4. Follow the instructions on the panel to run
./ngrok authtoken YOUR_AUTH_TOKEN
  1. Then, run this command to create a tunnel to the web application hosted on localhost:3000
./ngrok http 3000
  1. about there! On your terminal, you should see something like this:
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                             

Go to YOUR_NGROK_ADDRESS/api/erc721/1to make sure your endpoint is working.

How to deploy our NFT

Now that we've done all the groundwork (oof), let's go back to our ethereum/folder, ready to deploy our NFT.

ethreum/contracts/YOUR_NFT_NAME.solChange _baseURIthe function in the file to return your ngrok address.

// ethereum/conrtacts/EmotionalShapes.sol

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

To deploy our NFT, we first need to compile it with Hardhat . To make this process easier, we'll install ethers.js .

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

Let's update our 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}`],
    },
  },
};

To learn more about hardhat configuration files, check out their documentation . We've configured the ropsten network with our Alchemy URL and provided it with your MetaMask account's private key.

Finally, run:

npx hardhat compile

This makes hardhat generate two files for each compiled contract. We should see a newly created artifacts/folder containing the contracts you compiled in the folder contracts/. To learn more about how it works, read this tutorial from the Hardhat team .

Now, let's write a script that will finally deploy our NFT to the testnet. In your scripts/folder, create a file named 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);
  });

This code was inspired by the hardhat deployment tutorial .

In ethers.js ContractFactoryis the abstraction for deploying new smart contracts, so EmotionalShapeshere is our factory for token contract instances. ContractFactoryCalling on deploy()will start the deployment and return a resolve Contractto Promise. This is the object that provides methods for each of your smart contract functions.

How to View NFTs on the Blockchain

Run the deployment script:

node ./scripts/deploy.js

You should see this in the terminal EmotionalShapes deployed: SOME_ADDRESS. This is the address where your smart contract will be deployed on the ropsten testnet.

If you go https://ropsten.etherscan.io/address/SOME_ADDRESS, you should see the newly deployed NFT.

How to mint your NFT

Now that you've deployed your NFT, it's time to mint it for yourself! Create a new file mint.jscalled . We'll use ethers.js to help us.

First add ethers.jsthe package:

npm install --save ethers

Then, write mint.jsthe file:

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();

We first get the interface (ABI) of the contract. From ethereum.org:

The Application Binary Interface (ABI) is the standard way to interact with contracts in the Ethereum ecosystem , both from outside the blockchain and for contract-to-contract interactions.

Your ABI defines how others can interact with your contract. We then created our provider using Alchemy (remember Node as a Service). Finally, we initialize our wallet with our private key.

In main()the function call mintmethod, the method in the smart contract we just deployed. This mintmethod accepts only one parameter, to, which represents the recipient of the token. Since we're minting for ourselves, we'll put our Metamask account's public address.

If all goes well, you should see the transaction logged in the terminal. Get hashthe attribute, and go https://ropsten.etherscan.io/tx/YOUR_HASH. You should see the minting transaction there!

How to view NFT in Metamask wallet

You need to download the mobile version of Metamask first. Then, log into your account.

You should see an NFT tab and an Add NFT button. Click the button and enter the address of your smart contract along with your minted id. If you're following the tutorial, you should start with the id 1.

https://img.chengxuka.com_0376

at last

Congratulations! You just minted your own NFT. In the next part of the project, we'll build the front-end React application to interact with our contract. The ultimate goal is to build a fully functional web application where you can sell your own NFTs.

Original link: https://www.freecodecamp.org/news/how-to-make-an-nft/

Guess you like

Origin blog.csdn.net/hanru723/article/details/125673403