ERC721 is one of the most common representations of NFTs on EVM blockchains so we will be diving deeper into how they work in this post.
Understanding the ERC721 Standard
ERC721 is a notable standard in the Ethereum ecosystem, created to facilitate the representation of non-fungible tokens (NFTs) on the Ethereum blockchain. Introduced in 2017, the ERC721 standard has gained significant popularity due to its ability to represent unique, indivisible assets, providing a foundation for the booming digital art and collectables market.
Unlike ERC20 tokens, which are fungible and interchangeable, each ERC721 token is unique and can represent ownership over an individual, distinct asset, digital or physical.
Primary use cases of ERC721 tokens include:
Digital Collectibles: The most common use case is in the realm of digital collectables. CryptoKitties, a game where you can collect, breed, and sell virtual cats, was the first major project to use ERC721 tokens.
Digital Art: Artists can mint their artworks as ERC721 tokens, proving their authenticity and allowing them to be bought, sold, or traded on various NFT marketplaces like OpenSea
--- [ shameless shilling - check out my very own NFT collection, Teal Panic-A-Cat which I used to test out some of the features I have been building at Zeal ] ---
Virtual Real Estate: Projects like Decentraland use ERC721 tokens to represent ownership over parcels of virtual land.
Fine Wine Trading: Strauss & Cohas partnered withFanfire to create wine collections backed by NFT baskets, a novel concept for creating baskets for ERC721 tokens.
Token Approvals and Ownership Tracking in ERC721
In ERC721, the concept of ownership is well-defined and standardised. Each token has an owner, which can be transferred via the transferFrom function that emits the transfer event.
Token Approvals: Similar to ERC20, ERC721 also includes an approval mechanism. However, in the case of ERC721, approvals are set per token. This means a token owner can approve another user or a smart contract to manage one of their tokens. This is done via the approve function.
Ownership Tracking: ERC721 tokens use a mapping structure to track the owner of each token. Each token has a unique identifier and the contract stores which address owns each identifier.
Operator Approvals: In addition to per-token approvals, ERC721 also introduces the concept of operator approvals. This allows a token owner to approve another address (an "operator") to manage all their tokens.
The specifics of tracking ownership and approvals in ERC721 contracts can be complex due to the unique nature of each token. In the following sections, we will delve deeper into these topics, providing code examples and discussing their implementations.
Ownership Tracking
ERC721 tokens, also known as Non-Fungible Tokens (NFTs), represent unique items or assets on the blockchain. In the ERC721 standard, each token is unique and can be owned by an individual address. The contract keeps track of the owner of each token through a mapping, much like in ERC20, but this time the mapping is from the unique token ID to the owner's address:
mapping (uint256 => address) private _tokenOwner;function ownerOf(uint256 tokenId) public view virtual returns (address) { address owner = _ownerOf(tokenId); if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } return owner;}
Approvals Tracking
ERC721 contracts also keep track of token approvals within their internal state. This allows a token owner to approve another address to transfer a specific token on their behalf. The contract maintains a mapping of token approvals:
mapping (uint256 => address) private _tokenApprovals;function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ownerOf(tokenId), to, tokenId);}
Recommended by LinkedIn
Challenges and Solutions
One challenge with the ERC721 standard is that each token is unique, which can make it more difficult to work with than ERC20 tokens. For example, to transfer multiple ERC721 tokens, you would have to call the transfer function individually for each token, which can be gas-intensive.
An extension to the ERC721 standard, known as ERC721Enumerable, introduces an additional mapping to keep track of all tokens owned by each address, making it easier to work with multiple tokens owned by the same address.
The approval system in ERC721 is more complex compared to ERC20 due to its granular permission settings. Within ERC721, each token requires its own individual approval, or you could use the setApprovalForAll function which authorises a specific address to manage every token the owner presently holds and will acquire in the future. This differentiation contributes to higher gas costs and the added challenge of managing approvals, as tokens are individually approved and entire collections are managed separately.
To illustrate, imagine that you have both individual and 'ForAll' approvals. If one type of approval is revoked, it doesn't impact the other. Thus, should you invoke 'revokeForAll', any individual approvals previously set will remain active. This can be an essential detail when managing ERC721 tokens, as it provides flexibility but can also introduce complexities.
It's worth noting that, like in ERC20, approvals and ownership changes are tracked by listening for Approval, ApprovalForAll, and Transfer events emitted by the contract and updating an off-chain database accordingly.
This poses a challenge for some use cases like building a web3 wallet where users need an accurate representation of all approvals granted for all assets they hold on the blockchain. I've discussed the same issues for ERC20 here:
We have solved this particular problem at Zeal , giving our wallet users a comprehensive view of their ERC20, ERC721 and ERC1155 approvals and balances on the entire blockchain. We currently support Polygon and Binance Smart Chain with many more EVMs to be added in the near future. If you are curious to play with the API, just drop me a message!
In the next post, I'll tackle ERC1155 tokens, and share specifics of how you can use log topics and data to identify approvals.
Some supplemental reading:
If you are a blockchain boffin and spot anything missing or incorrect, feel free to drop a comment.