How to Write, Deploy, and Mint an NFT

·

The rise of non-fungible tokens (NFTs) has transformed digital ownership, empowering creators to tokenize art, collectibles, and more on the blockchain. Whether you're an artist, developer, or enthusiast, learning how to write, deploy, and mint your own NFT opens doors to innovation and monetization in the Web3 space. This comprehensive guide walks you through every step—from setting up your development environment to viewing your freshly minted NFT in MetaMask—using industry-standard tools like Solidity, Hardhat, Alchemy, and IPFS.

By the end of this tutorial, you’ll have deployed an ERC721 smart contract on the Ropsten test network and minted your first NFT using real blockchain interactions—all without spending a single dollar in real ETH.


Core Keywords

These keywords naturally align with search intent for developers and creators exploring how to enter the NFT ecosystem. They are seamlessly integrated throughout the content to enhance SEO performance while maintaining readability.


Setting Up Your Development Environment

Before writing any code, you need a solid foundation. This section covers setting up essential tools: Alchemy for API access, MetaMask for wallet management, and Hardhat for local development.

Step 1: Connect to the Ethereum Network via Alchemy

To interact with Ethereum without running your own node, we’ll use Alchemy, a powerful blockchain development platform offering reliable APIs and real-time monitoring. Alchemy supports major NFT platforms like OpenSea, Dapper Labs, and MakersPlace—making it a trusted choice for serious developers.

👉 Get started with Alchemy today and unlock advanced blockchain analytics.

Sign up for a free Alchemy account at alchemy.com. Once registered, you can generate API keys to communicate with Ethereum testnets like Ropsten.

Step 2: Create Your Application and API Key

After signing in:

  1. Hover over "Apps" in the navigation bar and click Create App.
  2. Name your app (e.g., “MyNFT”), add a description, select Staging under Environment, and choose Ropsten as the network.
  3. Click Create App.

Your new app will appear in the dashboard with an associated HTTP API endpoint—this is what your code will use to send requests to the Ethereum blockchain.

Step 3: Set Up MetaMask Wallet

MetaMask is a browser extension and mobile app that acts as an Ethereum wallet. It allows you to manage accounts, sign transactions, and connect to decentralized applications (dApps).

Download MetaMask from metamask.io and create a new wallet. After setup, switch the network to Ropsten Test Network in the top-right corner to avoid using real funds during testing.

Step 4: Get Test ETH from a Faucet

Since we’re deploying on the Ropsten testnet, you’ll need fake ETH. Visit the FaucETH website, enter your MetaMask public address, select Ethereum Testnet Ropsten, and request funds. Within seconds, test ETH should appear in your wallet.

Step 5: Verify Your Balance Using Alchemy

To confirm receipt of test ETH, use Alchemy’s Composer Tool to send an eth_getBalance request:

  1. Go to composer.alchemyapi.io.
  2. Select eth_getBalance.
  3. Enter your MetaMask address and execute.

The response returns balance in Wei (1 ETH = 10¹⁸ Wei). For example:

{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}

Convert 0xde0b6b3a7640000 to decimal: it equals 1×10¹⁸ Wei → 1 ETH.

You're now ready to start coding!


Writing and Deploying Your NFT Smart Contract

With tools configured, let’s write a secure ERC721-compliant smart contract using Solidity and deploy it with Hardhat.

Step 6: Initialize Your Project

Open your terminal and run:

mkdir my-nft
cd my-nft
npm init -y

This creates a package.json file to manage dependencies.

Step 7: Install Hardhat

Hardhat is a development environment for compiling, testing, and deploying Ethereum software:

npm install --save-dev hardhat

Then initialize Hardhat:

npx hardhat

Choose Create an empty hardhat.config.js.

Step 8: Organize Project Structure

Create two folders:

mkdir contracts scripts

Step 9: Write the NFT Smart Contract

In contracts/MyNFT.sol, paste the following Solidity code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";

contract MyNFT is ERC721URIStorage, Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() ERC721("MyNFT", "NFT") {}

    function mintNFT(address recipient, string memory tokenURI)
        public
        onlyOwner
        returns (uint256)
    {
        _tokenIds.increment();
        uint256 newItemId = _tokenIds.current();
        _mint(recipient, newItemId);
        _setTokenURI(newItemId, tokenURI);
        return newItemId;
    }
}

Install OpenZeppelin contracts:

npm install @openzeppelin/contracts

Understanding the Code


Configuring and Deploying the Contract

Step 10: Securely Store Secrets with .env

Install dotenv:

npm install dotenv --save

Create .env in the root:

API_URL="https://eth-ropsten.alchemyapi.io/v2/your-api-key"
PRIVATE_KEY="your-metamask-private-key"
PUBLIC_KEY="your-metamask-public-address"

⚠️ Never commit .env to version control. Add it to .gitignore.

Step 11: Install Ethers.js

Ethers.js simplifies Ethereum interactions:

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

Update hardhat.config.js:

require('dotenv').config();
require("@nomiclabs/hardhat-ethers");
const { API_URL, PRIVATE_KEY } = process.env;

module.exports = {
  solidity: "0.8.1",
  defaultNetwork: "ropsten",
  networks: {
    hardhat: {},
    ropsten: {
      url: API_URL,
      accounts: [`0x${PRIVATE_KEY}`]
    }
  },
};

Step 12: Compile and Deploy

Compile the contract:

npx hardhat compile

Create scripts/deploy.js:

async function main() {
  const MyNFT = await ethers.getContractFactory("MyNFT");
  const myNFT = await MyNFT.deploy();
  await myNFT.deployed();
  console.log("Contract deployed to address:", myNFT.address);
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});

Deploy:

npx hardhat --network ropsten run scripts/deploy.js

You’ll see output like:

Contract deployed to address: 0x81c587EB0fE773404c42c1d2666b5f557C470eED

Verify deployment on Ropsten Etherscan by searching the address.


Minting Your First NFT

Now that your contract is live, let’s mint an NFT with custom metadata.

Step 13: Use IPFS for Decentralized Metadata

NFTs rely on metadata (name, image, attributes) typically stored off-chain. We’ll use Pinata, an IPFS service, for permanent storage.

  1. Sign up at pinata.cloud.
  2. Upload an image file (e.g., nft-image.png) under Files.
  3. Copy its CID and form the URL:
    https://gateway.pinata.cloud/ipfs/Qm...image-hash

Create nft-metadata.json:

{
  "name": "Ramses",
  "description": "The world's most adorable pup.",
  "image": "https://gateway.pinata.cloud/ipfs/QmWmvTJmJU3pozR9ZHFmQC2DNDwi2XJtf3QGyYiiagFSWb",
  "attributes": [
    { "trait_type": "Breed", "value": "Maltipoo" },
    { "trait_type": "Eye color", "value": "Mocha" }
  ]
}

Upload this JSON to Pinata and copy its gateway URL.

👉 Discover how blockchain storage powers true digital ownership.

Step 14: Mint Using a Script

Install Alchemy Web3:

npm install @alch/alchemy-web3

Create scripts/mint-nft.js:

require("dotenv").config();
const API_URL = process.env.API_URL;
const PUBLIC_KEY = process.env.PUBLIC_KEY;
const PRIVATE_KEY = process.env.PRIVATE_KEY;

const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
const web3 = createAlchemyWeb3(API_URL);

const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json");
const contractAddress = "0x81c587EB0fE773404c42c1d2666b5f557C470eED";
const nftContract = new web3.eth.Contract(contract.abi, contractAddress);

async function mintNFT(tokenURI) {
  const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest");

  const tx = {
    from: PUBLIC_KEY,
    to: contractAddress,
    nonce: nonce,
    gas: 500000,
    data: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(),
  };

  const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY);
  signPromise
    .then((signedTx) => {
      web3.eth.sendSignedTransaction(
        signedTx.rawTransaction,
        function (err, hash) {
          if (!err) {
            console.log("The hash of your transaction is:", hash);
          } else {
            console.log("Error submitting transaction:", err);
          }
        }
      );
    })
    .catch((err) => {
      console.log("Promise failed:", err);
    });
}

mintNFT("https://gateway.pinata.cloud/ipfs/QmYueiuRNmL4MiA2GwtVMm6ZagknXnSpQnB3z2gWbz36hP");

Run:

node scripts/mint-nft.js

Check status via Alchemy Mempool or Ropsten Etherscan.


Viewing Your NFT in MetaMask

Step 15: Add NFT to MetaMask

  1. Open MetaMask mobile app.
  2. Switch network to Ropsten.
  3. Tap Collectibles > Import NFTs.
  4. Enter:

    • Contract Address: 0x81c587EB...
    • Token ID: Check transaction details on Etherscan (likely 1).
  5. Confirm import.

After a refresh, your NFT will appear in your collection.


Frequently Asked Questions

Q: What is an NFT?

An NFT (non-fungible token) is a unique digital asset verified on a blockchain. Unlike cryptocurrencies, each NFT has distinct value and cannot be exchanged one-to-one.

Q: Why use the Ropsten testnet?

Ropsten lets you test smart contracts with free ETH before deploying on mainnet, reducing risk and cost.

Q: Can anyone mint my NFT?

By default, only the contract owner can mint due to the onlyOwner modifier. Remove it if you want public minting.

Q: Where is my NFT metadata stored?

Metadata is stored off-chain via IPFS using a tokenURI. This keeps data decentralized and tamper-proof.

Q: Is this ERC721 standard compliant?

Yes. The contract inherits from OpenZeppelin’s ERC721 implementation, ensuring full compliance with EIP-721 standards.

Q: How do I deploy on Ethereum mainnet?

Replace ropsten with mainnet in hardhat.config.js, connect to a mainnet Alchemy endpoint, and fund your wallet with real ETH.


👉 Start building the future of digital ownership—explore Web3 tools now.