LearnWeb3 Logo

8 min read

·

3 years ago

+4,000 XP
481
164
19

Build your own basic NFT Contract on Ethereum

This is a step-by-step tutorial going over how to build your own simple NFT contract on the Ethereum network using Foundry and OpenZeppelin Contracts!


We will write the Solidity contract code, and deploy it to a test network using Foundry.


Prefer a Video?

If you would rather learn from a video instead of reading this lesson, you can watch the video on our YouTube channel. Note that the video might have certain things that are outdated and the lesson is always more up to date. In this video, we're using Hardhat instead of Foundry.


Prerequisites


Installing Foundry

If you're on a Mac or are using Linux run this command in your terminal

curl -L https://foundry.paradigm.xyz | bash


If you're on Windows, it is recommended that you install wsl and then use the same command. However, if you don't want to install wsl, you'll have to build it from source. Make sure you have the Rust compiler and cargo on your machine. Check if you do by using this command:

rustc --version cargo --version


Once confirmed, use this command

cargo install --git https://github.com/foundry-rs/foundry --profile local --locked forge cast chisel anvil


Setting up Foundry

To build the smart contract, we will use Foundry this time. It is an Ethereum development environment and framework that allows full-stack Ethereum development on your local computer without relying on browser IDEs such as Remix. It also allows for easier debugging, faster iterations, and writing scripts and tests to go along with your contract code.


To set up a Foundry project, first create a new folder on your computer - we will name ours NFT-Tutorial - and go to it through your Terminal.


Once your Terminal is inside NFT-Tutorial, setup a Foundry project using the following:

forge init foundry-app



Installing OpenZeppelin Contracts

We learnt about OpenZeppelin Contracts in the ERC-20 Lesson where we built our own cryptocurrency. OpenZeppelin also provides templates for NFT Contracts - and we will use those as a starting point.


cd into foundry-app and then run the following command:

forge install OpenZeppelin/openzeppelin-contracts


This will fetch Openzeppelin's contracts repository from GitHub and clone it, enabling us to use it in our code.


When you do this, Hardhat would have looked at the import statement and understood you're trying to import a Solidity file that is not one part of your own project . It would then fetch it from the node_modules/ folder because it expects you to have installed the npm dependency for it.


In Foundry, this works a bit differently. Since this is not a Node project and doesn't ship with npm - and instead just git clones the repository you need into the lib folder, imports would normally work something like this:

import {ERC20} from "../lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";


But this code doesn't look that clean - so we have remappings.


Remappings are essentially a way to provide an alias to imports - a shorter-way of writing import statements which are aliasing some short-form path to the real path of that dependency.


To configure them in your project and make sure they're picked up when compiling your code, run the following command:

forge remappings > remappings.txt


This will take the remappings it has understood, and write them to a remappings.txt file in foundry-app which acts as a configuration file for all your remappings. You can also customize this and add new ones if you need to.


Writing the NFT Contract

With OpenZeppelin Contracts now installed, we can move on to writing our Solidity code.


Create a new Solidity file - we'll name ours NFTee.sol - inside the src folder of your Foundry project. Write the following code in that file:


// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; // Import the openzepplin contracts import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; // NFTee is ERC721 signifies that the contract we are creating imports ERC721 and follows ERC721 contract from openzeppelin contract NFTee is ERC721 { constructor() ERC721("NFTee", "ITM") { // mint an NFT to yourself _mint(msg.sender, 1); } }


The code is fairly straightforward. We import the ERC-721 contract from OpenZeppelin, and then initialize it during the constructor. We also use the internal _mint function to mint an NFT to ourself.


To make sure you got the code right check if all the files are compiling. First delete the test folder and then, in your terminal, run

forge build


If there are no errors and your contract compiled just fine, you are good to go!


Deploying the Contract

Let's deploy this contract to the Sepolia Test Network. First, create a .env file inside your foundry-dapp folder and add the

following lines to it:

QUICKNODE_RPC_URL="..." PRIVATE_KEY="..."


Are you wondering what an .env file is?


A .env file is a file that contains environment variables that are used to configure an application's environment. Environment variables are variables that are set in the operating system's environment and are used to configure an application's behavior.

Environment variables are used to store configuration information that an application needs to run. For example, an application might need to know the location of a database or the API key for a third-party service. By storing this information in environment variables, the application can be configured without having to modify the application code.


The .env file is a convenient way to manage environment variables for an application. It is a plain text file that contains key-value pairs, where each key is the name of an environment variable and the value is the value of that variable. The .env file is typically stored in the root directory of an application and is loaded when the application starts up.



Head over to Quicknode and sign up for an account if you haven't already. Quicknode is a node provider that runs blockchain nodes for various networks and gives you access to them so you don't have to run your own. We will use them to deploy our contract through Foundry by connecting Foundry to their node.


After creating an account at Quicknode, click on Create an Endpoint, select Ethereum and then select the Sepolia network. Finish this process, and then copy the HTTP Provider link you receive. Update your .env file to have that URL as the value for QUICKNODE_RPC_URL.


Now, for the private key. When you deploy using Remix, Remix just prompts you to deploy the contract through MetaMask since it operates in the browser. However, since we are running Foundry directly on your computer, we need to give it the private key directly.


💡

IMPORTANT: If you haven't already created a separate account for development that DOES NOT HAVE FUNDS on Ethereum Mainnet - DO SO NOW! Many people have made a mistake with this and accidentally ended up revealing their private key which has led to a loss of funds. MAKE SURE THE PRIVATE KEY YOU USE HERE ONLY HAS TESTNET ETH AND NO REAL MONEY ON MAINNET.


To get your private key, you can export it from MetaMask. To do so, open up MetaMask, click on Account Details for the account you want to export, and click on Export Private Key. Copy-paste the value and put it in your .env file as the value for PRIVATE_KEY.


💡

At this point, double check you have named your .env file properly and it is properly located in the NFT-Tutorial folder - not a subdirectory or anything else. Also make sure that in the .gitignore file that Foundry automatically set up for you, .env is listed. You can never be too safe about your private keys, especially when you're just learning about this stuff.



Now we'll have to load our environment variables into the terminal's environment. For doing this, run the following command in your terminal

source .env


This command just specifies that the source of the variables we're about to enter is the .env file.


Finally, to deploy your contract, run the following command:


forge create --rpc-url $QUICKNODE_RPC_URL --private-key $PRIVATE_KEY src/NFTee.sol:NFTee


Notice how variable names are prefixed with $


This command will output some logs to your console where it will compile your contract and then deploy to the Sepolia Test Network. It will also give you the contract address of the deployed contract.


Copy the contract address it gives you, and look it up on Sepolia Etherscan - open up the first transaction there and it will show you that a NFT was minted and transfered to your address!


Congratulations!

Awesome! If you got this far, you have probably deployed your first NFT contract to an Ethereum testnet! You also learnt about Foundry and setting it up.


If you had any trouble, or just want to share your success, message us on the Discord Server and we'll be there for you!


Why should you use Environment Variables and not just enter the values in the terminal directly?

  • Because these values are visible to anyone who views your terminal's history.

  • Because Environment Variables automatically encrypt the values and keep them safe


*You must be signed in to submit quiz
You must be signed in to post comments
User avatar

ResidentPetal

·

15 days ago

Hi, I just literally saw a 2 versions of this page, is it possible to have a hardhat version in text too? Thanks!

0
User avatar

LingarajPatil

·

last month

Day 7

0
User avatar

ElementaryCorpsman

·

3 months ago

nice adventure in web3

0
User avatar

DiversifiedCistern

·

4 months ago

- add "--broadcast" when you use forge create -quicknode sucks.. use an Alchemy Node -verifying contract in foundry sucks... -actually foundry just sucks.. having to type everything in the command line is like walking on eggshells.. damn. use hardhat!!

0
User avatar

Mahatma

·

8 months ago

if you're watching it in 2024 , you need to get all these links from official documents as some seems to be outdated

4
BUGG Logo