ERC721 Non Fungible Standard
Simple-explanantion
ERC20 is fungible token = tradeable ERC721 is non fungible token = collectible For physical coins, a gold coin is not fungible with a copper coin, because their differing characteristics give them different values to collectors. This standard can't scale
**ERC721 tokens can be used in any exchange, but their value is a result of the uniqueness and rareness associated with each token. The standard defines the functions name
, symbol
, totalSupply
, balanceOf
, ownerOf
, approve
, takeOwnership
, transfer
, tokenOfOwnerByIndex
, and tokenMetadata
. It also defines two events: Transfer
and Approval
.
Source for this part: https://medium.com/crypto-currently/the-anatomy-of-erc721-e9db77abfc24
Functions-simplified
ERC721 standard allows each unit to be unique collectible item with its own serial number ID ERC20 Functions Functions of token standard makes it easier for existing wallets to display simple information about the token. These functions let the smart contract that fits this standard act like a common cryptocurrency such as Bitcoin or Ethereum by defining functions that let users perform actions such as sending tokens to others and checking balances of accounts.
name - tell outside contracts and apps the name of the token
symbol - helps in providing compatibility with the ERC720 token standard. Provides outside programs with the token's shorter name or symbol
totalSupply - returns the total number of coins available on blockchain
balanceOf - find the numbers of tokens that a given address owns
Ownership Functions Define how contract will handle token ownership and how it can be transferred. The most notable are takeOwnership = withdraw and Transfer = send functions. Both are essential for letting users transfer tokens.
ownerOf - returns the address of the owner of a token. We can determine the owner of a token using its ID which this function gives
approve - approves and gives another entity permission to transfer a token on the owners behalf
takeOwnership - acts like withdraw function, can be used when a user has been approved to own certain amount of tokens and wish to withdraw X amount of tokens from someone else balanace
Transfer - transferring tokens, lets the owner send to another user, can be initiated after the receiving account has been approved to own the token by sending account
tokenOfOwnerByIndex (optional but recommended) - this contract keep a record of every unique ID of the token as the user may own more tokens, user can be retrieved by its index in the list of tokens owned
Metadata Functions Storing data on blockchain that tells the defining characteristic of each token is expensive and not recommended. We can store references like IPFS hash or HTTPS link (URL) to each token attribute on the chain in order for the dapp outside of the chain to execute logic and find the information about the token. These data are metadata [[tokenMetadata]] (optional but recommended) - discover the tokens metadata or link to them
Events Fired whenevenr a contract calls them, are broadcasted to any listening programs - dapps once they ve been fired. Dapps are listening those events so they can execute the logic once the event is fired.
Transfer- functions and broadcasted when the token ownership changes, details which account sent the token and received by token ID
approval - when user approves another user to take the ownership of a token, shows which account owns the token by ID, which is approoved to have its ownership transferred
Find snippets of code here: https://medium.com/crypto-currently/the-anatomy-of-erc721-e9db77abfc24
History of the standard
ERC721 = non fungible token that can hold metadata
ERC-721 Non Fungible Token Standard
Token standard that is used to identify something or someone in a unique way. Perfect for being used as collectible item, access keys, lottery standards...
This standard has [[uinit26]] = tokenId. The [[contract-address]], uint26 tokenId must be unique. dApp usually have "converter" that uses the tokenId as input and outputs image - the NFT itself.
Token Standards are summarised and compared in the following ways:
Ownership - How is the token ownership handled?
Creation - How are tokens created?
Transfer & Allowance - How tokens are transferred, how do we allow other addresses (contracts or extrnally owned accounts) transfer capability?
Burn - How do we burn or destroy a token?
Token Ownership
token-ownership mapping(address => uint256) balances
uint256 = record of how many tokens each address of the ERC721 Contract holds
If you want to transfer ERC721 then the balance is verified through balance mapping so you don’t send more than you have
Functionalities
balanceOf(address _owner)= external view returns (uint256) **ownerOf(uint256_tokenId) ** = external view returns (address)safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payablesafeTransferFrom(address _from, address _to, uint256 _tokenId) external payabletransferFrom(address _from, address _to, uint256 _tokenId) external payableapprove(address _approved, uint256 _tokenId) external payable function setApprovalForAll(address _operator, bool _approved) external function getApproved(uint256 _tokenId) external view returns (address; function isApprovedForAll(address _owner, address _operator) external view returns (bool)
Fuctions
Events simplified
transfer token between accounts
get (display) current balance of an account
get specific token
total supply of the token available on the network
approve amount of token from an account can be moved by 3rd party account
Events of this standard
Transfer(address indexed_from, address indexed _to, uint256 indexed _tokenId); event
Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); event
ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved)
Source for this part: https://ethereum.org/en/developers/docs/standards/tokens/erc-721/
ERC-721 Security
TL:DR just misleading name of the function
Intro
The ERC-721 was supposed to have a transfer security function to ensure tokens wouldn’t be stuck in recipient contracts that weren't designed to handle them.
Safe functions prevent tokens from getting stuck that's why we call them safeTransfer
. This function may cause reentrancy vulnerabilities which means the safeTransfer
function in code is not making the contract safe - preventing it from other vulnerabilities it's actually unsafeTransfer
. This function was initially named as transfer
Full disclosure
"When the ERC-721 standard was being drafted, back in the beginning of 2018, a suggestion was made to implement transfer security to ensure that tokens wouldn't be stuck in recipient contracts that weren't designed to handle them. To do this, the proposal authors modified the behavior of the transfer function to check the recipient for whether they were capable of supporting the token transfer. They also introduced the unsafeTransfer function which would bypass this check, should the sender so desire.
However, due to concerns about backward compatibility, the functions were renamed in a subsequent commit. This made the transfer function behave the same for both an ERC-20 and an ERC-721 token. However, now the recipient checking needed to be moved elsewhere. As such, the safe class of functions was introduced: safeTransfer and safeTransferFrom.
This was a solution for a legitimate problem, as there have been numerous examples of ERC-20 tokens being accidentally transferred to contracts that never expected to receive tokens (one particularly common mistake was to transfer tokens to the token contract itself, locking it forever). It's no surprise then that when the ERC-1155 standard was being drafted, it took inspiration from the ERC-721 standard by including recipient checks not only on transfer but on mint as well.
These standards mostly sat dormant for the next few years while ERC-20 maintained its popularity, but recently a spike in gas costs, as well as interest in NFTs, means that the ERC-721 and ERC-1155 standards have seen a spike in developer usage. With all this renewed interest, it sure is fortunate that these standards were designed with safety in mind, right?" -Samczsun
Source: https://www.paradigm.xyz/2021/08/the-dangers-of-surprising-code Code: https://github.com/ethereum/EIPs/commit/74dadccc858545aa89edaf6ec1cb5857cd261083
ERC721 Benchmark
"The standard enforces to emit Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId)
every time a token is transferred. Events can be used to get the list of tokens owned by a user. This approach queries the Transfer
events emitted by the smart contract that holds the tokens. As we will see later, querying for events is a slow operation that might fail.
Further reading
Walking Through the ERC721 Full Implementation - A Deep Dive into Managing ERC721 Assets https://medium.com/blockchannel/walking-through-the-erc721-full-implementation-72ad72735f3c
OpenZeppelin implementation https://docs.openzeppelin.com/contracts/3.x/api/token/erc721#IERC721Metadata
OpenZeppelin Contract https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol
Full implementation https://eips.ethereum.org/EIPS/eip-721
Exploring Non-Fungible Token with Zeppelin Library (ERC721) https://medium.com/coinmonks/exploring-non-fungible-token-with-zeppelin-library-erc721-399cb180cfaf
A Simple ERC-721 Example https://medium.com/coinmonks/a-simple-erc-721-example-c3f72b5aa19
ERC-721 Token - Reference Implementation by 0xCert https://github.com/0xcert/ethereum-erc721
ERC-721 Solmate https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol
Optimising ERC-721 Solmate walkthrough https://mirror.xyz/0x3fcAf7DDf64E6e109B1e2A5CC17875D4a5993F39/B3PKWKWZTk_lgLRS9oLY2sYCcYLHKdFQPyVrzDg0hZo
Last updated