---
title: "How to mint an NFT using web3.js"
description: "Discover the step-by-step guide on minting NFTs using Web3.js and unlock the world of digital assets with ease and empower your creativity!"
---

# How to mint an NFT using web3.js

This tutorial describes how to mint an NFT on the Ethereum blockchain using Web 3 and our smart contract from Part I: How to Create an NFT

_Estimated time to complete this guide: ~10 minutes_

Plus, be sure to check out the rest of our NFT tutorial series:

- 🪄  [How to mint an NFT with Ether.js](https://www.alchemy.com/blog/how-to-mint-an-nft-with-ethers-js)
- 👛  [How to view your NFT in your mobile wallet](https://www.alchemy.com/blog/how-to-view-your-nft-in-your-mobile-wallet)
- 💸  [How to set a price on an NFT](https://www.alchemy.com/blog/how-to-set-a-price-on-an-nft)
- 💻  [NFT minter tutorial: How to create a full stack dApp](https://www.alchemy.com/blog/nft-minter-tutorial-how-to-create-a-full-stack-dapp)

"Minting an NFT" is the act of publishing a unique instance of your ERC721 token on the blockchain. Now that we successfully [deployed a smart contract to the Ropsten network in Part I ](https://www.alchemy.com/blog/how-to-create-an-nft)of this NFT tutorial series, let's flex our web3 skills and mint an NFT!

At the end of this tutorial, you'll be able to mint as many NFTs as you'd like with this code —let's get started!

## Step 1: install Web3

If you followed the first tutorial on [creating your NFT smart contract](https://www.alchemy.com/docs#create-and-deploy-your-smart-contract-using-hardhat), you already have experience using Ethers.js. Web3 is similar to Ethers, as it is a library used to make creating requests to the Ethereum blockchain easier. In this tutorial we'll be using [Alchemy Web3](https://www.alchemy.com/docs), which is an enhanced web3 library that offers automatic retries and robust WebSocket support.

In your project home directory run:

## Step 2: create a mint-nft.js file

Inside your scripts directory, create an mint-nft.js file and add the following lines of code:

## Step 3: grab your contract ABI

Our contract ABI \(Application Binary Interface\) is the interface to interact with our smart contract. [Hardhat](https://www.alchemy.com/dapps/hardhat) automatically generates an ABI for us and saves it in the MyNFT.json file. In order to use this we'll need to parse out the contents by adding the following lines of code to our **mint-nft.js** file:

If you want to see the ABI you can print it to your console:

To run **mint-nft.js** and see your ABI printed to the console navigate to your terminal and run

## Step 4: configure the metadata for your NFT using IPFS

If you remember from our tutorial in Part I, our mintNFT smart contract function takes in a tokenURI parameter that should resolve to a JSON document describing the NFT's metadata— which is really what brings the NFT to life, allowing it to have configurable properties, such as a name, description, image, and other attributes.

<CalloutBlock>

Interplanetary File System \(IPFS\) is a decentralized protocol and peer-to-peer network for storing and sharing data in a distributed file system.

</CalloutBlock>

We will use [Pinata](https://pinata.cloud/), a convenient IPFS API and toolkit, to store our NFT asset and metadata to ensure our NFT is truly decentralized. If you don't have a [Pinata](https://www.alchemy.com/dapps/pinata) account, sign up for a free account at [pinata.cloud](https://pinata.cloud/) and complete the steps to verify your email.

Once you've created an account:

- Navigate to the "Pinata Upload" button on the top right
- Upload an image to pinata - this will be the image asset for your NFT. Feel free to name the asset whatever you wish
- After you upload, at the top of the page, there should be a green popup that allows you to view the hash of your upload —\> Copy that hashcode. You can view your upload at: `https://gateway.pinata.cloud/ipfs/<hash-code>`

For the more visual learners, the steps above are summarized here:Now, we're going to want to upload one more document to Pinata. But before we do that, we need to create it!

<ImageBlock
  src="https://media.alchemy.com/1704625396-pinata-upload.gif"
  alt="Pinata dashboard: uploading the NFT image asset to IPFS"
  width={844}
  height={480}
  caption="Uploading files to Pinata"
/>

In your root directory, make a new file called nft-metadata.json and add the following json code:

​Feel free to change the data in the json. You can remove or add to the attributes section. Most importantly, make sure the image field points to the location of your IPFS image— otherwise, your NFT will include a photo of a \(very cute!\) dog.

Once you're done editing the json file, save it and upload it to Pinata, following the same steps we did for uploading the image.

<ImageBlock
  src="https://media.alchemy.com/1704625535-upload-json-file-to-pinata.gif"
  alt="Pinata dashboard: uploading the NFT metadata JSON file"
  width={844}
  height={480}
  caption="Uploading json file to Pinata"
/>

## Step 5: create an instance of your contract

Now, to interact with our contract, we need to create an instance of it in our code. To do so we'll need our contract address which we can get from the deployment or [Etherscan](https://sepolia.etherscan.io/) by looking up the address you used to deploy the contract.

<ImageBlock
  src="https://media.alchemy.com/1704625679-create-an-instance-of-contract.png"
  alt="Etherscan: locating the deployed NFT contract address"
  width={2880}
  height={1510}
  caption="Create an instance of your contract"
/>

In the above example, our contract address is 0x81c587EB0fE773404c42c1d2666b5f557C470eED.

Next we will use the web3 [contract method](https://web3js.readthedocs.io/en/v1.2.0/web3-eth-contract.html?highlight=constructor#web3-eth-contract) to create our contract using the ABI and address. In your **mint-nft.js** file, add the following:

## Step 6: update the .env file

Now, in order to create and send transactions to the Ethereum chain, we'll use your public ethereum account address to get the account **nonce** \(will explain below\).

Add your public key to your **.env** file —if you completed part 1 of the tutorial, our **.env** file should now look like this:

## Step 7: create your transaction

First, let's define a function called `mintNFT(tokenData)` and create our transaction by doing the following:

1. Grab your **PRIVATE_KEY** and **PUBLIC_KEY** from the .env file.
1. Next, we'll need to figure out the account nonce. The nonce specification is used to keep track of the number of transactions sent from your address— which we need for security purposes and to prevent [replay attacks](https://www.alchemy.com/docs). To get the number of transactions sent from your address, we use [getTransactionCount](https://www.alchemy.com/docs).
1. Finally we'll set up our transaction with the following info:
1. **'from': PUBLIC_KEY** : The origin of our transaction is our public address
1. **'to': contractAddress** : The contract we wish to interact with and send the transaction
1. **'nonce': nonce** : The account nonce with the number of transactions send from our address
1. **'gas': estimatedGas** : The estimated gas needed to complete the transaction
1. **'maxPriorityFeePerGas': estimatedFee** : The estimated fee to bid per gas.
1. **'data': nftContract.methods.mintNFT\(PUBLIC_KEY, md\).encodeABI\(\)** : The computation we wish to perform in this transaction— which in this case is minting an NFT

Your `mint-nft.js` file should look like this now:

<CalloutBlock>

**How can I mint multiple NFTs:** To mint x number of NFTs in a single command, we can use a simple for loop running from 0 to x-1 within a function wrapping the minting process.  This would allow us to effectively mint x NFTs every time the wrapper mint function is called.

</CalloutBlock>

## Step 8: sign the transaction

Now that we've created our transaction, we need to sign it in order to send it off. Here is where we'll use our private key.

`web3.eth.sendSignedTransaction` will give us the transaction hash, which we can use to make sure our transaction was mined and didn't get dropped by the network. You'll notice in the transaction signing section, we've added some error checking so we know if our transaction successfully went through.‍

## Step 9: call mintNFT and run node contract-interact.js

Remember the metadata.json you uploaded to Pinata? Get its hashcode from Pinata and pass the following into a call to mintNFT [https://gateway.pinata.cloud/ipfs/](https://gateway.pinata.cloud/ipfs/%3Chash-code%3E)​

Here's how to get the hashcode:

<ImageBlock
  src="https://media.alchemy.com/1704625935-get-the-hashcode-on-pinata.gif"
  alt="Pinata dashboard: copying the IPFS hash of the uploaded metadata"
  width={844}
  height={480}
  caption="Get your hashcode on pinata"
/>

<CalloutBlock>

Double check that the hashcode you copied links to your `metadata.json` by loading [https://gateway.pinata.cloud/ipfs/](https://gateway.pinata.cloud/ipfs/%3Chash-code%3E) into a separate window. The page should look similar to the screenshot below:

</CalloutBlock>

<ImageBlock
  src="https://media.alchemy.com/1704626043-returned-hashcode-on-pinata.png"
  alt="NFT metadata JSON returned from the Pinata IPFS gateway"
  width={2878}
  height={1714}
  caption="Returned hashcode on Pinata"
/>

Altogether, your code should look something like this:

Now, run `node scripts/mint-nft.js` to deploy your NFT. After a couple of seconds, you should see a response like this in your terminal:

Next, visit your [Alchemy mempool](https://dashboard.alchemy.com/mempool) to see the status of your transaction \(whether it's pending, mined, or got dropped by the network\). If your transaction got dropped, it's also helpful to check [Ropsten Etherscan](https://sepolia.etherscan.io/) and search for your transaction hash.

<ImageBlock
  src="https://media.alchemy.com/1704626257-search-for-transaction-hash.png"
  alt="Block explorer search for the NFT mint transaction hash"
  width={2846}
  height={1586}
  caption="Search for your transaction hash"
/>

And that's it! You've now deployed AND minted with an NFT on the Ethereum blockchain 🎉

Using the `mint-nft.js` you can mint as many NFT's as your heart \(and wallet\) desires! Just be sure to pass in a new `tokenURI` describing the NFT's metadata --otherwise, you'll just end up making a bunch of identical ones with different IDs.

Presumably, you'd like to be able to show off your NFT in your wallet 😉— so be sure to check out Part III: [How to View Your NFT in Your Wallet](/blog/how-to-view-your-nft-in-your-mobile-wallet).
