Non-Fungible Tokens (NFTs) have gained significant popularity in the blockchain space, enabling creators to tokenize and sell unique digital assets. In this tutorial, we will create a simple NFT exchange contract using Solidity, the primary programming language for developing smart contracts on the Ethereum blockchain. We will walk through the process of creating, deploying, and interacting with the contract to enable users to list, buy, and sell NFTs on our exchange.
To begin, we will use the Remix IDE (
Create a new Solidity file named "NFTExchange.sol" in the Remix IDE, and add the following code:
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract NFTExchange is Ownable {
using Counters for Counters.Counter;
Counters.Counter private _listingIds;
struct Listing {
uint256 id;
address nftContract;
uint256 tokenId;
address payable seller;
uint256 price;
bool isSold;
}
mapping(uint256 => Listing) public listings;
event ListingCreated(uint256 indexed id, address indexed nftContract, uint256 indexed tokenId, address seller, uint256 price);
event ListingSold(uint256 indexed id, address indexed buyer);
// Your code will go here
}
Now, let's implement the core functions of our contract:
function createListing(address nftContract, uint256 tokenId, uint256 price) public {
IERC721(nftContract).transferFrom(msg.sender, address(this), tokenId);
_listingIds.increment();
uint256 listingId = _listingIds.current();
listings[listingId] = Listing({
id: listingId,
nftContract: nftContract,
tokenId: tokenId,
seller: payable(msg.sender),
price: price,
isSold: false
});
emit ListingCreated(listingId, nftContract, tokenId, msg.sender, price);
}
function buyNFT(uint256 listingId) public payable {
Listing storage listing = listings[listingId];
require(!listing.isSold, "NFT is already sold");
require(msg.value >= listing.price, "Insufficient funds");
listing.seller.transfer(listing.price);
IERC721(listing.nftContract).transferFrom(address(this), msg.sender, listing.tokenId);
listing.isSold = true;
emit ListingSold(listingId, msg.sender);
}
Now, compile the contract by clicking on the "Solidity Compiler" tab in Remix and then clicking the "Compile" button. Once compiled, switch to the "Deploy & Run Transactions" tab, select the "Injected Web3" environment, and click "Deploy."
After deployment, the NFTExchange contract will appear under the "Deployed Contracts" section. You can now interact with the contract using the provided buttons to call the functions we defined earlier.
To create a listing, you will need the NFT contract address and the token ID of the NFT you want to sell. Make sure you are the owner of the NFT, and the NFT is approved for transfer to the
NFTExchange contract.
Call the createListing
function by providing the NFT contract address, token ID, and desired price. After executing the function, a new listing will be created, and an event will be emitted with the listing details.
To buy an NFT from the exchange, call the buyNFT
function with the listing ID you want to purchase. Ensure you send the required amount of Ether along with the function call. If the purchase is successful, the NFT will be transferred to your address, and the seller will receive the payment.
To fetch the details of a particular listing, you can call the listings
function with the listing ID as an argument. The function will return the listing's details, such as the NFT contract address, token ID, seller address, price, and sold status.
Conclusion:
In this tutorial, we built a simple NFT exchange contract using Solidity. We implemented core functionalities to create listings and buy NFTs. This exchange contract can be further expanded with additional features, such as a bidding system or a native token for transaction fees. With a firm understanding of the basics, you can now continue to explore more complex NFT exchange systems and develop your own decentralized marketplace for unique digital assets.
You can get the whole code here.