Building a Simple NFT Marketplace: A Journey into Blockchain Development
Sadikur Rahman
Experienced .NET Developer, Team Lead, and Blockchain Enthusiast with Proficiency in SQL Server, Frontend Development, and Node.js. Building Innovative Solutions( mobile and web application) for Finance, Education.
Welcome back to our ongoing series on blockchain development! In our last tutorial, we successfully built a Multi-Chain Bridge DApp. Now, we're diving into the fascinating world of Non-Fungible Tokens (NFTs) with the creation of a Simple NFT Marketplace. This project will allow users to mint, buy, and sell unique digital assets using Solidity, Hardhat, Axios, and Next.js.
Prerequisites
Before we start this project, ensure you have the necessary tools and knowledge:
Project 2: Simple NFT Marketplace
Overview
In this project, we'll create a Simple NFT Marketplace where users can mint their NFTs, buy NFTs from others, and sell their own NFTs. We'll use Solidity to define the smart contracts, Hardhat for deployment, Axios for API interactions, and Next.js for the frontend.
Smart Contracts (Solidity)
We begin by defining the smart contract that represents our NFT. It includes functions for minting, buying, and selling NFTs.
// contracts/NFT.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract NFT is ERC721Enumerable, Ownable {
using Strings for uint256;
// Base URI for metadata
string private _baseTokenURI;
// Mapping from token ID to price
mapping(uint256 => uint256) private _tokenPrices;
constructor(string memory name, string memory symbol, string memory baseTokenURI) ERC721(name, symbol) {
_baseTokenURI = baseTokenURI;
}
function _baseURI() internal view override returns (string memory) {
return _baseTokenURI;
}
// Mint new NFT
function mint(address to) external onlyOwner {
uint256 tokenId = totalSupply() + 1;
_safeMint(to, tokenId);
// Set an initial price for the minted NFT
_tokenPrices[tokenId] = 1 ether; // 1 ether as an example, adjust as needed
}
// Get the price of a token
function getTokenPrice(uint256 tokenId) external view returns (uint256) {
return _tokenPrices[tokenId];
}
// Sell a token
function sellToken(uint256 tokenId, uint256 price) external {
require(ownerOf(tokenId) == msg.sender, "Not the owner of the token");
_tokenPrices[tokenId] = price;
}
// Buy a token
function buyToken(uint256 tokenId) external payable {
uint256 price = _tokenPrices[tokenId];
require(price > 0, "Token not for sale");
require(msg.value >= price, "Insufficient funds");
address seller = ownerOf(tokenId);
// Transfer ownership
_transfer(seller, msg.sender, tokenId);
// Clear the token price
_tokenPrices[tokenId] = 0;
// Transfer funds to the seller
payable(seller).transfer(msg.value);
}
}
领英推荐
Hardhat Deployment Script
Next, we create a deployment script for Hardhat to deploy our NFT smart contract.
// scripts/deploy.js
const { ethers } = require("hardhat");
async function main() {
const NFT = await ethers.getContractFactory("NFT");
const nft = await NFT.deploy("MyNFT", "MNFT", "https://your-metadata-api.com/api/token/");
await nft.deployed();
console.log("NFT deployed to:", nft.address);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Next.js Frontend (pages/index.js)
Now, let's build the frontend using Next.js. This includes features for minting, buying, and selling NFTs.
// pages/index.js
import { useEffect, useState } from 'react';
import axios from 'axios';
const Home = () => {
const [tokenId, setTokenId] = useState('');
const [mintedTokenId, setMintedTokenId] = useState('');
const [buyTokenId, setBuyTokenId] = useState('');
const [buyPrice, setBuyPrice] = useState('');
const [sellTokenId, setSellTokenId] = useState('');
const [sellPrice, setSellPrice] = useState('');
const [message, setMessage] = useState('');
useEffect(() => {
// Fetch metadata for the minted token
const fetchMetadata = async () => {
try {
const response = await axios.get(`https://your-metadata-api.com/api/token/${mintedTokenId}`);
console.log('Token Metadata:', response.data);
} catch (error) {
console.error('Error fetching token metadata:', error);
}
};
if (mintedTokenId) {
fetchMetadata();
}
}, [mintedTokenId]);
const handleMint = async () => {
try {
const response = await axios.post('https://your-nft-contract-api.com/api/mint', { to: 'recipient-address' });
setMintedTokenId(response.data.tokenId);
setMessage('NFT minted successfully!');
} catch (error) {
console.error('Error minting NFT:', error);
setMessage('Error minting NFT.');
}
};
const handleBuy = async () => {
try {
await axios.post('https://your-nft-contract-api.com/api/buy', { tokenId: buyTokenId }, { value: buyPrice });
setMessage('NFT purchased successfully!');
} catch (error) {
console.error('Error buying NFT:', error);
setMessage('Error buying NFT.');
}
};
const handleSell = async () => {
try {
await axios.post('https://your-nft-contract-api.com/api/sell', { tokenId: sellTokenId, price: sellPrice });
setMessage('NFT listed for sale successfully!');
} catch (error) {
console.error('Error listing NFT for sale:', error);
setMessage('Error listing NFT for sale.');
}
};
return (
<div>
<h1>Simple NFT Marketplace</h1>
<div>
<label>
Mint NFT to Address:
<input type="text" value={tokenId} onChange={(e) => setTokenId(e.target.value)} />
<button onClick={handleMint}>Mint NFT</button>
</label>
</div>
<div>
<label>
Buy NFT (Token ID):
<input type="text" value={buyTokenId} onChange={(e) => setBuyTokenId(e.target.value)} />
<label>
Price (ETH):
<input type="text" value={buyPrice} onChange={(e) => setBuyPrice(e.target.value)} />
</label>
<button onClick={handleBuy}>Buy NFT</button>
</label>
</div>
<div>
<label>
Sell NFT (Token ID):
<input type="text" value={sellTokenId} onChange={(e) => setSellTokenId(e.target.value)} />
<label>
Price (ETH):
<input type="text" value={sellPrice} onChange={(e) => setSellPrice(e.target.value)} />
</label>
<button onClick={handleSell}>Sell NFT</button>
</label>
</div>
<div>
<p>{message}</p>
</div>
</div>
);
};
export default Home;
This completes the code for our Simple NFT Marketplace. Remember to replace placeholder URLs and addresses with your actual API endpoints, contract addresses, and other relevant information.
Next Project: Twitter Clone
For our next project, get ready to dive into the world of social media on the blockchain! We'll be building a Twitter Clone that leverages blockchain technology for decentralized, censorship-resistant communication. Stay tuned for our next tutorial, where we'll guide you through the process of creating this exciting project.
Happy coding, and welcome to the frontier of blockchain development!