ERC-721 Token

Create Your Own NFT on Ethereum Blockchain

Gaurav Agrawal
QuickNode
Published in
8 min readJun 7, 2019

--

Goal — We will explore the ERC-721 token standard, non-fungibility, and build a SIMPLE ERC-721 token.

What is an ERC 721 Token?

The ERC-721 Token standard is the Ethereum token standard which enables Non-Fungible Tokens (NFTs) on the Ethereum blockchain. Just like the ERC-20 Token standard helps in creating fungible tokens, the ERC-721 focuses on non-fungible asset design. Do you remember CryptoKitties? That is a non-fungible token (i.e. each Kitty asset is unique).

Fungibility

Before understanding non-fungibility, we need to understand what is fungibility. There are two main properties of fungibility:

Interchangeability — You can interchange or replace units of a fungible asset. Your $20 bill and my $20 bill represents the same thing and can be interchanged. Another example that 1kg gold bar is equal to another 1k gold bar. They represent the same value and can be interchanged.

Quantity — You can merge units of a fungible asset to get a higher value in quantity. The example you can add up multiple KGs of grains and now you have the same thing but in a higher quantity.

Nonfungibility

Let’s understand what is non-fungibility.

A non-fungible token represents a unique token which can’t be interchanged with another token.

You can’t divide or add up to get a higher quantity because every unit is unique and you cannot replace or interchange it with other assets. For example, two pieces of land. They are both non-fungible regarding their location.

Image result for cryptokitties
Image source- Every Kitty is unique and represents a different token. Aren’t they cute? See the leftmost one, isn’t he shy? 😋

Example of Non-Fungible Tokens

There are many Non-Fungible Tokens. Some famous NFTs are CryptoKitties, Etheremons, Crypto Bots, and Blockchain Cuties. You can check a full list of ERC-721 tokens here.

The ERC-721 Standard

Now’s let deep dive into the ERC-721 standard. The ERC-721 standard defines a set of methods which help in identifying and interacting with a Non-Fungible Token.

Events- events which get emitted on Transfer, Approvals.

ERC-721 Functions

balanceOf — Will return the balance of an address.

ownerOf — Will return owner address of a token.

safeTransferFrom —Transfer token from one address to another with checks performed to make sure the recipient can accept the token, so it doesn’t get burned/lost.

transferFrom — Transfer token from one address to another address (note: the use of this function is discouraged). The Caller of the method is responsible to put the correct recipient address.

approve — Approve any other address to send a transaction from token owner account to any other account.

setApprovalForAll — Allow or disallow an operator (any address, mostly wallets and exchanges) to send all tokens from owner address to any other address.

getApproved — Return an address which is allowed to transfer token for owners. Return 0 if no address is set.

isApprovedForAll — Return true if given operator (any address) is approved by a given owner.

Building an ERC-721 Token using OpenZeppelin and Truffle

Now let’s build an ERC-721 token using the OpenZeppelin library and Truffle.

First, let’s setup Truffle:

Let’s create a new Contract for our SIMPLE Token:

Let’s see what we are doing here. We are inheriting two contracts; ERC721FULL and Ownable.

Ownable — Using this contract, we can manage ownership of our contract and are able to mint tokens from the contract owner’s account only.

ERC721FULL — This is a standard implementation of ERC-721 interface we have mentioned above. Let’s see what happens inside this contract:

ERC721FULL internally inherits 3 contracts. We will look mainly into ERC721 to understand the implementation.

Let’s go through the main function one by one. Before that, we will understand, how tokens are getting stored:

_tokenOwner — This mapping is needed to store a token against its owner. By using this we can know who is the owner for given tokenId.

_tokenApprovals — This mapping is needed to store tokenId, against an address which is approved by the token owner, to transfer a token on behalf of the owner.

_ownedTokenCount — This mapping is needed to know how many tokens an address owns. If we don’t create this mapping, we have to loop to get this information and looping takes lots of gas on EVM.

_operatorApprovals — Mapping of an owner and an operator (any address, mostly wallets, and exchanges) to check if the owner had given approval or not.

Now let’s see functions in this standard:

balanceOf — This will return the balance of an address. First, it checks for a valid address and then using _ownedTokensCount returns the count of the token.

OwnerOf — This will return the owner address for a given token using _tokenOwner mapping.

approve — This will approve an address to transfer a token on behalf of the owner. The function first checks if the owner called the function or if the call is approved by the owner to send all tokens. Then it updates the _tokenApprovals mapping if everything is correct.

safeTransferFrom — There are two functions with similar names, but with different arguments. These functions internally call transferFrom function. Though they also perform one more important duty. They check if the recipient address is valid for receiving the token or not. This helps in the security of the token.

transferFrom — This is the main function to transfer a token from one address to another address. Let’s see what is it doing:

1- Check if the token is either owned by called or approved to the caller. Also, checks of a valid address.

2- Clear approval, remove current ownership and reduce the token count of the current owner.

3- Add token to recipient account and increase the token count for the recipient.

setApprovalForAll — This function approves the address to transfer all tokens on behalf of the owner. It first checks if the called and to address are not the same, and then updates the _operatorApprovals mapping.

isApprovedForAll — This function checks if the owner approved the operator to transfer tokens or not.

getApproved — Returns the approved address for given tokenId.

You can check the other helper functions and inherited contracts.

If you don’t understand something, please ask in comments! We’re here to help!

Testing ERC-721 Token

Now we will test our SIMPLE token and play around it. We will use a local built-in blockchain to deploy and test the contract.

This will give us the Truffle console.

Now let’s deploy our contract. Remember! You need to add a migration file. You can check the attached GitHub repo at the end of the article.

Now, let’s mint some tokens, and perform a test transfer & approval.

You can go ahead and test all methods (OpenZeppelin is a well-tested library so you don’t need to worry about the functionality provided by the library). You should instead be focusing on testing any functionality added by you 😎

Conclusion

Today we have created a Non-Fungible Token using Solidity on Ethereum. NFT tokens are mostly used as collectibles and have a variety of other use-cases, such as representing real-estate, artwork, certificates, loans, etc… There is a big use-case in gaming where one can use NFTs to represent items and collectibles across games and platforms. This is really exciting!

What’s Next?

In the next article, we will convert this into an upgradable contract using ZeppelinOS… So subscribe & stay tuned!

Let us know what you want to learn about in the comment section.👇

About QuikNode

QuikNode is building infrastructure to support the future of Web3. Since 2017, we’ve worked with hundreds of developers & companies, helping scale dApps and providing high-performance Ethereum nodes. We’re working on something interesting from the past few months and will be launching soon, so subscribe our newsletter for more updates!! 😃

--

--