The gaining popularity of NFTs has create some interesting use cases for NFTs in not just the art space but in the digital media space, the gaming industry, retail, automobile, real estate and more such innumerable categories.
In this article, I will shed some light on understanding NFTs from a developer perspective as to how can we codify them.
I have picked a simple example contract which can be found on the OpenZeppelin website( here ) and modified it a little bit for the audience to understand better.
ERC721 is the standard used for representing the ownership of Non-Fungible Tokens, where each of these is unique in nature. There are a number of functionalities offered by this standard and hence, it is split into multiple tokens.
Here is more information about the ERC721 related contracts and their associated functions.
In order to simplify all the complexities mentioned in the above functions, let me simplify the process of creating and deploying NFTs for sale. The following steps give you a brief yet clear idea of how NFTs are created and put up for sale:
- Step 1: The NFT creator/owner needs to deploy an ERC721 or any other NFT standard contract on the blockchain of their choice(Ethereum/Harmony etc.) by providing a "name" and "symbol" for their NFT. This contract is not the piece of art/collectible in itself. It is more of a first step to ensure that the ownership of the art/collectibles can be recorded and verified on the blockchain.
- Step 2: The next step is to "mint" the piece of art/collectible. They are minted in the form of tokens using the mint() function present in the ERC721 contract. These minted tokens now become associated with the NFT contract that you deployed in step1.
- Step 3: Once the art/collectibles have been minted, they can be put up for sale by writing your own sale contract or using platforms that have already built the underlying infrastructure.
The nature and usage of the NFT items depends on how you have coded the contracts. From the ERC721 solidity contract, many functions can be overridden and changed according to your logic/preference in your smart contract.
Here is a simple contract where we mint some tokens in a game and give it to a player in the form of an award:
Step 1: Import the required contracts in your code. Here, we import the parent ERC721 contract.
// contracts/GameItem.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol';
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol';
Steep 2: You can see the Solidity smart contract in this section, which has 3 functions: tokenURI() , _baseURI() and awardItem(). We will explore the functions in-depth here:
contract GameItem is ERC721 {
uint counter;
mapping(uint => string) _tokenURIs;
constructor() ERC721("GameItem", "ITM") { counter = 0; }
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
return _tokenURIs[tokenId];
}
/**
* @dev Base URI for computing {tokenURI}. Empty by default, can be overriden
* in child contracts.
*/
function _baseURI() internal view virtual override returns (string memory) {
return "https://somekindofs3link";
}
function awardItem(address player, string memory _tokenURI)
public
returns (uint256)
{
counter = counter+1;
uint256 newItemId = counter;
_mint(player, newItemId);
_tokenURIs[newItemId] = string(abi.encodePacked(_baseURI(), _tokenURI));
return newItemId;
}
}
The name of the contract: GameItem
function _baseURI(): This is a function that has been overridden from the ERC721 contract to set the baseURI of the location of your token.
function tokenURI(): This function(again overridden from the ERC721) is used to return the URI of your token. We will be setting the URI in our awardItem function.
function awardItem(): This function takes in the address of the player to be rewarded with the collectible as well as details about the collectible. This functions returns the tokenId once created. The _mint function is used to create a new token(newItemId) and award it to the address mentioned(player).
You can copy paste the above code and run it on the Remixeditor, just to see it for yourself :). If you want to follow my NFT code experiments, you can check out this repo.
Did you think creating NFTs would be this easy? ;) What are some of the cool NFT use cases that you can think of?