Deciphering ERC721 Token Standard & Fungibility of assets from a Developer’s perspective.
Table of Contents
To begin with, What exactly are tokens?
In simpler terms, a token can be seen as a representative of value within a particular platform that has the capability to be traded for services, currency, time, or even shares in a company, etc.
The entire concept of tokens in the Blockchain space has mostly inspired the use of tokens in our real lives.
Imagine a MOVIE HALL
The best way to understand a token is to take a real-world example like a Movie Hall.
Before you enter a movie hall you need to exchange your to receive tickets.
Those tickets can actually be seen as tokens.
Inside the Movie Hall, the real money doesn’t really hold any value(unless the manager inside is corrupt) but the ticket does.
These tickets now have enough value to be exchanged for a seat inside the hall. In fact, almost everything or services you might want inside this hall, completely depends on the kind of tickets you have.
The more tickets you have, more the quantity of seats you have access to. Also the costlier your ticket is, the better the quality of your seats.
Tickets are TOKENS... HALL is the DAPP...
Now simply swap the entire idea of the Movie Hall with a Decentralized Application(DAPP) and the movie tickets with the crypto tokens allowed in that DAPP.
That’s it. You just got the gist of what Tokens actually are.
Hence, it can undoubtedly be said that Tokens play an imperative role as they let you access certain features or services provided by the DAPP and act as medium of exchange within that particular platform.
The Concept of FUNGIBILITY
Before understanding even the basic idea of ERC721 its literally imperative for us to understand the 2 most crucial kinds of TOKENS.
Fungible tokens
This represents the simple type of tokens that we are quite familiar in our everyday life.
A Fungible token may be defined as those that are equivalent as well as easily interchangeable. For example, A 100 Rupee note can be exchanged for any other 100 Rupee note since all of those are the same and hold the same amount of value.
There is no uniqueness in Fungible assets as they are already available in large quantities. A 100 Rupee that you have is quite similar to the note I have in every aspect, i.e., size, shape, color as well as value. Therefore there isn’t any uniqueness in Fungible assets.
Moreover, these fungible assets are divisible into smaller units and it doesn’t really matter since the value of all the smaller units together still remains the same.
For example, a 100 Rupee note can be divided into two 50 Rupee notes or even into ten 10 Rupee notes. It doesn’t really matter since all these smaller notes together bring the same value as the 100 Rupee note.
However, the same is not true for Non Fungible Tokens.
Non-Fungible Tokens
Unlike Fungible assets, Non-Fungible Tokens(NFTs) are not at all interchangeable and equivalent.
NFTs can simply be understood as all those assets whose value exists because of their uniqueness, usefulness as well as rarity.
NFTs can simply be understood as all those assets whose value exists because of their uniqueness, usefulness as well as rarity.
The best example of Non Fungible assets are paintings or unique artworks. Each Painting is one of a kind and is unique in its own way.
Now, this painting comes under the category of Non Fungible assets because all are different, rare, and most importantly unique. This means unlike Fungible tokens, NFTs can’t be exchanged simply.
Moreover, they aren’t divisible like Fungible assets because once divided they lose their real value.
Therefore, while Fungible assets deals with the quantity(how many)of the tokens you own, Non Fungible assets is more about the quality(which ones) of tokens you possess.
Enters ERC721
In late 2017, Dieter Shirley introduced an Ethereum Improvement Proposal called ERC721.
Why ERC721 and not ERC20?
The Ethereum community already had an effective standard called ERC20 tokens, to represent and track fungible tokens on the blockchain.
However, it was beyond the capability of ERC20 to track NFTs because, unlike fungible tokens, each NFT is distinct.
ERC721, although inspired by the ERC20 protocol, provides a modified and effective standard interface for non-fungible tokens.
While ERC721 tokens can be used in any exchange, their value however is quite not similar and largely depends upon their uniqueness and rareness.
Moreover, unlike ERC20 tokens, the value of non-fungible tokens in the ERC721 token standard largely depends upon their uniqueness as well as rareness.
Diving Deep into ERC721 Contract
The fact that makes ERC721 different from ERC20 can actually be found within its smart contract.
Although ERC721 follows the basic procedure of ERC20 but certain functions within ERC721 allows us to track non fungible assets as well.
Let’s dive in and understand more about the ERC721 contract and those functions that makes it one of a kind.
Imperative Functions in ERC721
balanceOf(owner)
ownerOf(tokenId)
safeTransferFrom(from, to, tokenId)
transferFrom(from, to, tokenId)
approve(to, tokenId)
getApproved(tokenId)
setApprovalForAll(operator, _approved)
isApprovedForAll(owner, operator)
safeTransferFrom(from, to, tokenId, data)
Important Events in ERC721:
- Transfer
- Approval
- ApproveForAll
In-Depth Analysis of ERC721 Functions and Events
a. ownerOf
Syntax:function ownerOf(uint256 _tokenId) external view returns (address);
Function Parameter:
_tokenId -the unique ID assigned for each NFT.
What it does: Simply looks for the owner of a particular NFT.
What it returns: Returns the address of the owner who owns the NFT.
Throws an Error: If the tokenId passed as parameter doesn’t have any owner, then such NFTs are invalid.
b. safeTransferFrom
Syntax:function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
Function Parameter:
_from -the current owner of the NFT
_to -address of the new owner
_tokenId -unique ID of the NFT to be transferred.
_data -Additional Data.
What it does: Its main task is to transfer the ownership from one address to another.
Throws an Error: This function can throw errors in 5 crucial conditions. Its really imperative to understand each of them.
a. It throws an error if the msg.sender is not the current owner, an authorized operator or an approved address for the NFT to be transferred.
b. If the _from parameter doesn’t contain the address of the current owner, then error will be thrown.
c. If the _to parameter is a zero address(invalid address).
d. If the _tokenId is not a valid NFT.
Note: This function can throw an error even after the transfer is complete.
e. One of the most imperative part that must be understood is that as soon as the transfer is complete, this function checks if the _to address passed in the parameter is an Externally Owned Account(owned by a person) or a Contract Address(owned by a contract).
If the _to address is a contract address(code size>0), then it calls an `onERC721Received` function on `_to` address.
It then checks if the return value is equal to:
`bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
If the return value is not the same, then it throws an error.
c. transferFrom
Syntax:function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
Function Parameter:
from -the current owner of the NFT
to -address of the new owner
tokenId -unique ID of the NFT to be transferred.
What it does: It also transfers the ownership of a NFT from one address to another. However, there is a crucial difference between this function and the safeTransferFrom function.
In this function, the Caller is the one responsible to confirm that the receiver of the NFT is capable of receiving NFTs.
Otherwise the NFTs may be lost as soon as the execution of this function is completed.
Throws an Error:
a. It throws an error if the msg.sender is not the current owner, an authorized operator or an approved address for the NFT to be transferred.
b. If the _from parameter doesn’t contain the address of the current owner, then error will be thrown.
c. If the _to parameter is a zero address(invalid address).
d. If the _tokenId is not a valid NFT.
d. approve
Syntax:function approve(address _approved, uint256 _tokenId) external payable;
Function Parameter:
_approved -the New Approved address for a particular NFT
tokenId -unique ID of the NFT to approve.
What it does: This function is used to change or reaffirm the approved address for an NFT.
Throws an Error:
a. It throws an error if the msg.sender is not the current owner, an authorized operator or an approved address for the NFT to be transferred.
b. If the _tokenId is not a valid NFT.
e. setApprovalForAll
Syntax:function setApprovalForAll(address _operator, bool _approved) external;
Function Parameter:
_operator -the address of the operator who will be approved for control over the NFTs
_approved -True if the provided operator is to be approved or False if the approval is to be revoked.
What it does: This is one of the most imperative functions as it allows the owner of the NFT to allow or prevent certain third parties, i.e., operators to manage all of his/her NFTs.
Throws an Error:
a. It throws an error if the msg.sender is not the current owner, an authorized operator, or an approved address for the NFT to be transferred.
f. getApproved
Syntax:function getApproved(uint256 _tokenId) external view returns (address);
Function Parameter:
tokenId -unique ID of the NFT to approve.
What it does: This is a simple function that provides us with the approved address for a single NFT.
What it returns: Returns the approved address for a particular NFT. It returns a zero address if there is no approved address for a NFT.
Throws an Error: If the _tokenId is not a valid NFT.
g. isApprovedForAll
Syntax: function isApprovedForAll(address _owner, address _operator) external view returns (bool);
Function Parameter:
_owner -the Owner of the NFT
_operator -The address of the third party that acts on behalf of the owner.
What it does: This function provides us with information that whether or not an operator is authorized for another address.
What it returns: Returns True if _operator is an approved address for the owner, else returns False.
Important Events in ERC721:
- Transfer Event
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
This event is emitted whenever the ownership of any NFT is changed from on address to another.
2. Approval Event
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
Whenever an approved address for a particular NFT is converted or reaffirmed, the Approval Event is emitted.
3. ApprovalForAllEvent
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
This event is fired only when a third party or an operator is allowed or prevented to use the NFTs of a particular user on behalf of the user.
Once allowed, the operator can manage all the NFTs of the owner.
Best Use Cases of Non-Fungible Tokens
NFTs have a completely distinct set of properties that makes them quite different from traditional fungible tokens.
Therefore, before using NFTs or starting to develop your own NFTs, there is a very strong need for you to understand the best ways a non fungible tokens can and should be used.
Some of the most renowned applications of NFTs are as follows:
Gaming
Collectibles
Licensing
NFTs in Gaming
One of the most renowned use cases of NFTs in Gaming can undoubtedly be seen as Cryptokitties.
In fact, this was one of the first best use cases of the NFTs that drew enormous attention towards NFTs and the ERC721 token standard.
With the use of NFTs, this game expanded its boundaries enormously and people have spent more than $6.5 million on these unique cryptokitties.
NFTs in Licensing
Software Licensing is yet another best-use case of NFTs.
It is widely believed that using NFTs in licensing can reduce not only reduce piracy but also allows people to earn profit by selling their license in the open market.
Guess you are all set to get started with ERC721 token.
Good LUCK!