How to create and deploy an ERC-721 (NFT)?

How to create and deploy an ERC-721 (NFT)?

Digital collectibles compatible with the ERC-721 standard have become very popular since the launch of Cryptokitties and have moved forward towards mass adoption in recent months. This guide will create and deploy our ERC-721 (NFT) using the 0xcert/ethereum-erc721 smart contract library.

What is a Non-Fungible Token?

Fungible means to be the same or interchangeable. For example, Ethereum tokens, all the members of a particular token class, have the same value. The same can be said of Cardano tokens. Fungible tokens are interchangeable 1:1.

With this in mind, NFTs are unique; each one is different. Every single token has unique characteristics and values. The types of things that can be NFTs are collectible cards, artworks, airplane tickets, etc. They are all clearly distinguishable from one another and are not interchangeable. Think of Non-Fungible Tokens (NFTs) as rare collectibles; each has unique characteristics, unusual attributes, and most times, its metadata.

What is ERC-721?

ERC stands for Ethereum Request for Comment, and 721 is the proposal identifier number. ERCs are application-level standards in the Ethereum ecosystem, they can be a smart contract standard for tokens such as ERC-20, the author of an ERC is responsible for building consensus with the Ethereum community and once the proposal is reviewed and approved by the community it becomes a standard. You can track the recent ERC proposal here. ERC-721 was created to propose the functionality to track and transfer NFTs within smart contracts.

ERC-721 is an open standard that describes how to build Non-Fungible tokens on EVM (Ethereum Virtual Machine) compatible blockchains; it is a standard interface for Non-Fungible tokens; it has a set of rules which make it easy to work with NFTs. NFTs are not only of ERC-721 type; they can also be ERC-1155 tokens.

The following are the set of functions and events defined in the ERC-721 standard:

ERC-721 defines some functions with compliance to ERC-20. This makes it easier for existing wallets to display simple token information.

ERC20-like Functions:

  • name: Used to define the token’s name, which other contracts and applications can identify.

  • symbol: Used to define token’s shorthand name or symbol.

  • totalSupply: This function is used to define the total number of tokens on the blockchain; the supply doesn’t have to be constant.

  • balanceOf: Returns number of NFTs owned by an address.

Ownership Functions

  • ownerOf: This function returns the address of the owner of a token. As each ERC-721 token is unique and non-fungible, they are represented on the blockchain by an ID. Other users, contracts, apps can use this ID to determine the owner of the token.

  • approve: This function grants or approves another entity the permission to transfer tokens on the owner’s behalf.

  • takeOwnership: This is an optional function that acts like a withdraw function since an outside party can call it to take tokens out of another user’s account. Therefore, takeOwnership can be used when a user has been approved to own a certain amount of tokens and wishes to withdraw said tokens from another user’s balance.

  • transfer: This is another type of transfer function; it allows the owner to transfer the token to another user, just like other digital tokens/coins.

  • tokenOfOwnerByIndex: This is an optional but recommended function. Each owner can own more than one NFT at the same time. Its unique ID identifies every NFT, and eventually, it can become difficult to keep track of IDs. So the contract stores these IDs in an array and the tokenOfOwnerByIndex function lets us retrieve this information from the array.

Metadata Function

  • tokenMetadata: This optional feature is an interface that lets us discover a token’s metadata or a link to its data.

Events

  • Transfer: This event is fired when the ownership of the token changes from one individual to another. It emits the information on which account transferred the token, which account received the token, and which token (by ID) was transferred.

  • Approve: This event is fired when a user approves another user to take ownership of the token, i.e., it is fired whenever approve function is executed. It emits the information on which account currently owns the token, which account is approved to take ownership of the token in the future, and which token (by ID) is approved to have its ownership transferred.

Use cases of Non-Fungible Tokens (NFTs):

  • Digital art (or physical art): Art pieces are the most popular use cases of NFTs. Digital art auctions were the first application of NFTs and continue to grow.

  • Gaming: Providing in-game purchases and collectibles of games.

  • Real estate: Tokenizing properties and smart contracts and carry buying and selling.

  • Finance: Financial instruments like loans, futures, and other responsibilities.

  • Software titles: Software licenses to ensure anti-piracy and privacy.

  • Concert tickets/Sports match tickets: To ensure that no fraud happens in ticket selling and fans can have a single place to view past experiences.

  • KYC compliance: Creating a token for a specific user’s KYC.

Getting test ETH

Now that we know what ERC-721 tokens are and how they work let’s see how we can build and deploy our own tokens.

We’ll deploy our contract on the Ropsten testnet. To get started, you will need the Metamask browser extension to create an ETH wallet and some test ETH, which you can get by going to the Ropsten faucet. You’ll need to select Ropsten Test Network on your Metamask wallet and copy-paste the wallet address into the text field in the faucet, then click Send me test Ether.

Adding Files to IPFS

Before writing our NFT contract, we need to host our art for NFT and create a metadata file; for this, we’ll use IPFS — a peer-to-peer file storing and sharing distributed system. Download and install IPFS CLI based on your Operating system by following the installation guide in IPFS docs.

Following are the steps for hosting the image and metadata file.

Step 1: Creating IPFS repo.

Start the IPFS repo by typing the following in a terminal/cmd window. Add files to ipfs.

$ ipfs init

Step 2: Starting the IPFS daemon.

Start the IPFS daemon, open a separate terminal/cmd window, and type the following.

$ ipfs daemon

Step 3: Adding an image to IPFS

Go to the first terminal window and add the image to IPFS (art.png here).

$ ipfs add art.png

Copy the hash starting from Qm and add the “https://ipfs.io/ipfs/” prefix to it; it must look something like this https://ipfs.io/ipfs/QmQEVVLJUR1WLN15S49rzDJsSP7za9DxeqpUzWuG4aondg

Step 4: Adding JSON file to IPFS

Create a JSON file nft.json and save it in the same directory as the image.

JSON file format:

{
    "name": "NFT Art",
    "description": "This image shows the true nature of NFT.",
    "image": "https://ipfs.io/ipfs/QmZzBdKF7sQX1Q49CQGmreuZHxt9sVB3hTc3TTXYcVZ7jC",
}

Now add the JSON file.

$ ipfs add nft.json

Copy the hash starting from Qm and add the “https://ipfs.io/ipfs/” prefix to it; it must look something like this https://ipfs.io/ipfs/QmUFbUjAifv9GwJo7ufTB5sccnrNqELhDMafoEmZdPPng
Save
this URL. We’ll need this to mint our NFT.

Creating our own token.

For ease and security, we’ll use the 0xcert/ethereum-erc721 contract to create our NFT. With 0xcert/ethereum-erc721, we don’t need to write the whole ERC-721 interface. Instead, we can import the library contract and use its functions.

Head over to the Ethereum Remix IDE and make a new Solidity file, for example — nft.sol

Paste the following code into your new Solidity script:

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

import "https://github.com/0xcert/ethereum-erc721/src/contracts/tokens/nf-token-metadata.sol";
import "https://github.com/0xcert/ethereum-erc721/src/contracts/ownership/ownable.sol";

contract newNFT is NFTokenMetadata, Ownable {

  constructor() {
    nftName = "Synth NFT";
    nftSymbol = "SYN";
  }

  function mint(address _to, uint256 _tokenId, string calldata _uri) external onlyOwner {
    super._mint(_to, _tokenId);
    super._setTokenUri(_tokenId, _uri);
  }

}

Explanation of the code above:

Line 1: Specifying SPDX license type, which is an addition after Solidity ^0.6.8. Whenever the source code of a smart contract is made available to the public, these licenses can help resolve/avoid copyright issues. If you do not wish to specify any license type, you can use a special value UNLICENSED or simply skip the whole comment (it won’t result in an error, just a warning).

Line 2: Declaring the solidity version.

Line 4–5: Importing 0xcert/ethereum-erc721 contracts.

Line 7: Starting our Contract named newNFT and mentioning it’s extending NFTokenMetadata and Ownable contracts.

Line 9–12: Initializing the constructor and setting name, a symbol of our token.

Line 14: Declaring function mint with three arguments, variable to of type address which will store the address of the receiver of NFT token, variable tokenId of uint256 type which will hold the token id, variable _uri of type string which will store the URI of the JSON file. Declaring mint as external means, it can be accessed from other smart contracts and outside the self scope.

Line 15: Minting token using the address of the receiver and token id.

Line 16: Setting token URI using token id and URI of JSON file.

Compile the smart-contract and deploy it using injected Web3 (make sure to select Ropsten testnet on Metamask before compiling the contract). Approve the transaction from metamask.

If you receive an error message before deployment, “This contract may be abstract,” make sure to select the appropriate contract under the Contract tab.

Confirm the transaction in Metamask

Now go to the “Deployed Contracts” section in Remix and expand the deployed contract. You’ll see a bunch of functions/methods. Expand the mint function and add the following details:

  1. Add your Ropsten address in the _to the field.

  2. Enter any Big number value in the _tokenid field (we suggest 1 since it’s the first).

  3. Add URI of JSON file in the _uri field, which we obtained in the previous section.

Click on transact and confirm the transaction from metamask. Now you have the token on the Ropsten chain.

You can check other details like name, symbol, owner, or tokenuri by entering the token id we mentioned earlier.

Conclusion

Congratulations on creating your very own NFT, help your artist friends put their artistic work on the Ethereum blockchain, or become an artist yourself. Checkout 0xcert/ethereum-erc721’s GitHub for more examples.

Subscribe to our newsletter for more articles and guides on Ethereum. If you have any feedback, feel free to reach out to us via Twitter. You can always chat with us on our Discord community server, featuring some of the coolest developers you’ll ever meet :)