How to Create an NFT on Ethereum

Batoul Alkarim
8 min readJan 6, 2023

--

By the end of this tutorial you will know how to write and deploy a Non Fungible (ERC721) Token smart contract using Ethereum and IPFS.

This is a 10 step walk through and should take you less than 20 minutes to complete if you choose to follow along. Alchemy does an incredible job of explaining the steps to create an NFT in their tutorial, I have adopted their explanations here.

Prerequisites:

  1. You need to have both Node.js(>14) and npm on your local machine.
  2. You need to create a free Alchemy account
  3. Have the Metamask extension installed in your browser

STEP 1:

  • After you have created your free Alchemy account, navigate to the Apps drop down menu and click “Create App”.
  • Provide a name and description.
  • For the Chain, select Ethereum and for Network select Goerli.
  • Click the ‘Create App’ button
Alchemy Create App- Step 1

STEP 2: Create a Metamask Wallet 🦊

If you don’t already have Metamask installed to your browser you can do so here.

Once you have downloaded Metamask make sure to make a new account.

The final part to this step is to ensure you switch your network to the Goerli Test Network.

NOTE: If you do not see Goerli Test Network as an option you may need to follow these steps:

  • Open your Metamask wallet and click on your avatar in the top right corner.
  • Press Settings
  • Press Advanced
  • Scroll down and navigate to “Show test networks” and toggle that to ON.

STEP 3: Get Faucet GoerliEth 💸

Faucet Eth is just fake Eth we can use to execute transactions. Since we’ll be working on the Goerli test network, we’ll need GoerliEth.

To get your free Eth you’ll need to have an Alchemy account (which you do by now) and to navigate to this website. Login with your Alchemy account and enter your wallet address. Boom, you’re done!

Go to this link to get your GoerliEth:

https://goerlifaucet.com/

STEP 4: Create a Node Project

In your command line all you need to type are these two commands:

After these commands successfully execute, we are in a good position to install Hardhat.

STEP 5: Create a Hardhat Project ⛑

Hardhat is a development environment to help you compile, deploy, test, and debug your smart contracts. It is used to help devs create dApps locally before deploying them to a live chain.

In your terminal, run these two commands:

You should see something like this:

You want to select: Create a JavaScript project and then agree to all of the default settings (project root, adding a .gitignore, and installing all sample project dependencies).

If you want to check that everything is running properly, run:

Finally, now that we have our hardhat dev environment configured, we just need to install the OpenZeppelin contract package. This is going to give us access to all of the ERC721 implementations (which is the standard for NFTs). You can install OpenZeppelin by executing this command:

STEP 6: Write the Smart Contract ✍🏼

Alright! Half way done and we’re ready to do the fun stuff. Open up the project in your favorite code editor and navigate to the contracts folder. There, you need to create a new file called MyNFT.sol.

This is what will be in that file, we’ll break down the code line by line.

In lines 4–6 we imported three OpenZeppelin smart contract classes:

  • @openzeppelin/contracts/token.ERC721/extensions/ERC721URIStorage.sol : this contains the implementation of the ERC721 standard which our NFT smart contract will inherit. This is because if we want our NFT to be valid, it must adhere to all the methods of the ERC721 standard. To learn more about inherited ERC721 functions, you can look here.
  • @openzeppelin/contracts/utils/Counters.sol : this import is providing us with a counter that can only increase or decrease by one. Our smart contract uses this counter to keep track of the total number of NFTs we have minted and sets the unique ID to our new NFT.
  • @openzeppelin/contracts/access/Ownable.sol : this import is setting up access control. This means that only the owner of the smart contract (you) can mint an NFT. If you want anyone who interacts with this contract to be able to mint an NFT you can remove this import and remove the word Ownable on line 8 and remove onlyOwner on line 16.

In lines 8–27 we have our custom NFT smart contract. It’s pretty short, it only has a counter, constructor, and one function. We were able to have such a short contract because we implemented most of the methods needed to create an NFT using OpenZeppelin.

Finally, on line 14 we have our function mintNFT() which is what allows us to actually mint! This function takes in two variables:

  1. address recipient: this is specifying the address that will receive the NFT that was just minted
  2. string memory tokenURI: this is a string that should resolve to a JSON document that describes the NFT’s metadata. An NFT’s metadata is very important because it’s what brings the NFT to life with attributes like name, description, image, and any others.

Our mintNFT() function will essentially call some methods from the inherited ERC721 library and ultimately return a number that represents the ID of the new NFT.

STEP 7: Connecting Alchemy and Metamask to your Project 🫱🏻‍🫲🏼

We now have a Metamask account, Alchemy account, and our very own smart contract. We need to connect the three.

Every transaction from your wallet requires a signature and that signature is verified using your wallets private key. To give our smart contact permission we can store our private key and Alchemy API key in an environment file.

NOTE: Be very careful if you are pushing your work up to github. Your private key is only for you and should never be shared with anyone. We are going to be putting it in a .env file so ensure that your .env file is in your .gitignore file or your wallet may be compromised.

You need to install the dotenv package in your project directory. You can do this by running:

You can now create your .env file in your root directory. It should be named exactly .env, nothing else.

You need to get your Metamask private key, if you don’t know how to do that, follow these instructions.

You will also need your API key from Alchemy, to do that:

  • Head to the Alchemy dashboard and under the Apps tab, select your App that you created earlier.
  • On the top left select View Key
  • Copy your API KEY to the clipboard.

Now you can fill out your .env file. It should look something like this:

NOTE: you can copy the API_URL and just paste your API key at the end where it says “your-api-key”

STEP 8: Update your hardhat.config.js File ⛑

We have added some new plugins and dependencies so we need to update our hardhat.config.js file so that our project knows all about them! This is what your updated file should look like:

STEP 9: Write the Deployment Script ✍🏼

Now it’s time to add our last file!

Under the scripts/ folder you should already see a deploy.js file. Remove it’s contents and replace it with the code from below:

Hardhat has a Contracts tutorial where they do a great job of explaining what each of these lines do. You can read it here, but for now I will give the explanation Alchemy provided:

A ContractFactory in ethers.js is an abstraction used to deploy new smart contracts, so MyNFT here is a factory for instances of our NFT contract. When using the hardhat-ethers plugin, ContractFactory and Contract instances are connected to the first signer by default.

Calling deploy() on a ContractFactory will start the deployment and return a Promise that resolves to a Contract. This is the object that has a method for each of our smart contract functions.

STEP 10: Deploy the Contract 🚀

We made it to the final step!! We’re finally ready to deplloy the smart contract! In your terminal, ensure you are at the root directory and run this command:

Command to execute deployment

You should see something like this displayed:

Now, if you go to Goerli Etherscan and search the address that was just displayed in your terminal (that is your contract address), you should see that your contract was successfully deployed! The transaction will look something like this:

The From address should match your Metamask account address, and the TO address should say Contract Creation.

CONGRATULATIONS!! 🎉 🎊 🍾 You just deployed your NFT smart contract tot the Ethereum chain!

If you want to understand more about whats going on “under the hood”, you can do so by navigating back to your Alchemy dashboard and clicking “Explorer”.

Here you’re going to see a bunch of JSON-RPC calls that Hardhat/Ethers made for us when we called the .deploy() function.

The two important ones to note are eth_sendRawTransaction, which is the request to actually write our smart contract on the the Goerli chain, and eth_getTransactionByHash, which is the request to read information about our transaction given the hash.

STAY TUNED! 💫

In Part 2 we will actually be interacting with our smart contract by minting an NFT!

If you enjoy my content or would like to learn more about me, you can visit my socials!

Website 🌸 Instagram 🌸 Github 🌸 LinkedIn

--

--

Batoul Alkarim

I'm a Full Stack developer transitioning into web3 and writing about it along the way!