ERC-1155D1
The standard is a gas efficient modification of the EVM standard ERC-1155 but mainly aimed to replace ERC-721 both accepted in 2018 and not changed since then. Only supports NFTs. By contrast with ERC-721 it allows batch minting, burning & transferring.
TL;DR2
Parameter | ||
---|---|---|
Minting Gas Price | ||
Transferring Gas Price | ||
Auditing | ||
tokenId enumeration | ||
FT support | ||
SFT support | ||
Max Supply |
Gas Saving Architecture
The updated standard authors followed the blue ocean
strategy dropping all the unnecessary but costly functionality leaving only the bear minimum. Unfortunately, a lot of useful functionality was lost as well, such as FT & SFT support, or the maximum number of tokens is restricted to 5,000 due to the implementation limitations.
Gas saving is achieved by fewer storage modifications.
1. Drop of ownerOf
function (by contrast with ERC-721)
Becasuse the standard is mainly aimed at replacing ERC-721 one of the gas saving features was the removal of the function that returns the number of owned tokens for a user. By contrast with ERC-721, in ERC-1155D 2*32 bytes of the (address + uint256) are not added to the contract (i.e. blockchain) storage.
Here's the removed part of the ERC-721 contract code3:
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
...
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _ownerOf(tokenId);
require(owner != address(0), "ERC721: invalid token ID");
return owner;
}
...
function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
return _owners[tokenId];
}
...
function _mint(address to, uint256 tokenId) internal virtual {
...
_owners[tokenId] = to;
...
}
Removal of the above code was motivated by the presence the function balanceOf
in ERC-1155 contract, but the way it operates has been modified. For details see the next point.
2. Modification of the balanceOf
function
In the original ERC-1155 implementation the function looked like this:
// ORIGINAL ERC-1155
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: address zero is not a valid owner");
return _balances[id][account];
}
In ERC-1155D the function has been modified like so:
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: balance query for the zero address");
require(id < MAX_SUPPLY, "ERC1155D: id exceeds maximum");
return _owners[id] == account ? 1 : 0;
}
This leads us to the next point, the contract storage.
3. Contract Storage
ERC-721
storage consists of the following slots:
# | Slot name | Slot types | Storage Change (bytes )5 |
---|---|---|---|
1 | _name | 0 | |
2 | _symbol | 0 | |
3 | _owners | ||
4 | _balances | ||
5 | _tokenApprovals | 04 | |
6 | _operatorApprovals | 05 |
ERC-1155
storage consists of the following slots:
# | Slot name | Slot types | Storage Change (bytes ) |
---|---|---|---|
1 | _uri | 0 | |
2 | _balances | ||
3 | _operatorApprovals | 05 |
ERC-1155D
storage consists of the following slots:
# | Slot name | Slot types | Storage Change (bytes ) |
---|---|---|---|
1 | _uri | 0 | |
2 | _owners | ||
3 | _operatorApprovals | 05 | |
4 | _currentIndex | 6 |
Key Takeaways:
- The name of the standard is misleading since it replaces ERC721 while it is called ERC-1155D.
- The standard is not as universal as it might seem. It only supports NFTs like ERC-721 and does not support FTs and SFTs like the original ERC-1155 would.
- The maximum number of tokens is limited to 5,000 while regular contracts are free from this limitation.
- The contract has not been audited, so the team planning to use it should invest in going through the decent auditing procedure before using it in production.
- The contract consumes 32-32 bytes of the blockchain storage depending on whether the
tokenId
is handled on- or off-chain. It saves up to 50-75% of the gas fees if compared with ERC-721 and 0-50% if compared with the classical ERC-1155.
Footnotes
- For studying the standard ERC-1155 implementation we referred to the folowing repository: https://github.com/DonkeVerse/ERC1155D↩
- The pros & cons are compared with the industry standard ERC-1155 and ERC-721 implementations by OpenZeppelin.↩
...
dots in the sourse code indicate presense of other code irrelevant for the current topic. ↩_tokenApprovals
is called independently of minting, burning & transferring and is present in all 3 standards.↩- Here, we only mean slot increase/change during every
mint
,burn
,transfer
or related operations. Static variables set during the contract deployment are not taken into account as irrelevant to the topic. Therefore,storage change
of the last is considered to be zero for the purposes of this paper. ↩ - Since the
tokenId
tracking is not natively implemented by the contract on GitHub, we used an arbitrary implementation offered in a medium article: https://medium.com/donkeverse/introducing-erc1155d-the-most-efficient-non-fungible-token-contract-in-existence-c1d0a62e30f1#2c37↩