ERC721 on StarkNet
As part of Immutable X’s StarkNet strategy, there is a need for an ERC721-compatible NFT implementation on StarkNet. Implementations in Solidity are not directly portable due to StarkNet’s usage of Cairo. The ‘Warp’ transpiler aims to bridge this gap, but a native Cairo implementation is more readable and maintainable. Fortunately, OpenZeppelin progressed in implementing many of their popular smart contracts in Cairo, including their ERC721 standard. The opinionated choices made by OpenZeppelin introduced limitations that we at Immutable X set out to solve. We also present a recommended preset that introduces extra functionality to support the health of the NFT ecosystem.
The ERC721 standard is used to represent non-fungible tokens. The most popular use case has been PFP (Profile Picture) NFTs, commonly used to create digital online identities. Other use cases include tokenization of digital assets, memorabilia for experiences, and digital art. The Immutable X ERC721 Cairo implementation supports any use case that can be done with the Solidity implementation.
Our recommended preset
ERC721_Full allows contract owners to use role-based permissions for minting and burning. It also allows the contract owner to set token metadata, contract metadata, and royalty information. Royalties can only be decreased after initializing, giving greater assurances to token holders. This preset is great for any project with plans to be presentable on marketplaces and requiring recurring revenue through royalties.
Immutable X’s Cairo ERC721 implementation provides all the functionality one expects from the Solidity implementation. Furthermore, our recommended preset
ERC721_Full integrates the following additional functionality beyond the ERC721 specification:
- EIP2981 royalty standard: Project owners can set token royalties independent of any particular marketplace. This preset uses unidirectional royalties, meaning they can only be decreased after being initialized
- Token Metadata: Project owners can set a retrievable
- Contract metadata: Project owners can decide what their storefront looks like on marketplaces.
- Access Control: Project owners can use role-based authorization
- Bridgeable: Project owners can grant minting and burning permission to contracts such as an NFT bridge (👀 coming soon)
We decided to recommend unidirectional royalties as the default because there are very few reasons for a team to legitimately increase their royalties. Conversely, a team could rug pull their community by increasing the royalty amount without prior warning. At Immutable X, we care deeply about buyer protection, and this is one step forward in making the NFT buying experience much safer. Project owners can still opt out of this preset and set their royalties flexibly if required.
OpenZeppelin’s ERC721 implementation introduces limitations with token metadata, where the
tokenURI can only be a maximum of 31 characters which is too small for an IPFS URI. The Immutable X implementation works around this by using a different type to represent the
tokenURI. With this change, we obtain feature parity with the ERC721 specification.
Immutable X believes that the fine-grained permissions of role-based authorization are better than simply relying on the owner, which is why our default preset uses Access Control instead of Ownable. This unlocks benefits such as simpler NFT bridging between L1 and L2.
NFTs rely on a
tokenURI to store off-chain data known as metadata. This metadata may include information such as a link to an image or information about NFT attributes. The
tokenURI is stored on-chain. We follow the ERC721 Metadata JSON Schema for token metadata, as this is the most widely adopted.
We will also be supporting any standard URI format for token metadata, e.g. CAIP-19 and EIP-681, whereby a reference to a token on Ethereum Layer 1 can be used as the
tokenURI. For example, if the
tokenURI returns a CAIP-19 URI of the form
eip155:1/erc721:0x06012c8cf97BEaD5deAe237070F9587f8E7A266d/771769, then marketplaces will be expected to resolve the URI by calling
tokenURI on address
0x06012c8cf97BEaD5deAe237070F9587f8E7A266d with token id argument
771769 on Ethereum Mainnet.
Our preset includes contract metadata, allowing for a whole NFT collection to have a representative image, which is useful for marketplaces. This was initially pioneered by OpenSea and is expected to resolve to a JSON object of the form:
2 "name": "My Collection Name",
3 "description": "A Cool Collection",
4 "image": "https://miro.medium.com/fit/c/112/112/1*ALBgIir8j4TOcKqnU_2BLQ.jpeg",
5 "external_link": "https://www.immutable.com/"
A notable difference is a lack of
fee_recipient. This is because these are captured in the contract itself with the EIP2981 implementation.
Inspired by the role-based Access Control in OpenZeppelin’s Solidity implementation, Immutable X implemented the same functionality in Cairo and adopted it for our default ERC721 Preset. Contract owners can allow one or more other addresses to mint on their behalf, providing greater flexibility. This is also beneficial for NFT bridging, whereby the minter role can be given to a bridging contract on L2, which can mint an NFT whenever someone deposits the NFT on L1. For simple use cases, contract owners may want to give themselves the minter role.
This ERC721 implementation is subject to change as new features of the Cairo language are released. Therefore, we recommend that projects use a proxy contract to make their ERC721 contract upgradeable.
As the StarkNet ecosystem is in its infancy, it is essential to scrutinize any libraries and both written and imported contracts, as everything is quite experimental and not yet battle-tested. We welcome the community to deploy and play around with our contracts — try them out, break things, build on top of them, etc. Any suggestions, improvements, or feedback would be greatly appreciated, and feel free to open PRs or issues on Github!
We will also be exploring new presets if required. If your project requires a specific preset, let us know as we’re interested in what people are building on StarkNet!
- Twitter: Immutable
- Discord: Join the Immutable X Discord Server!
- Telegram: Immutable X — Official Announcements
- Reddit: r/ImmutableX
We’re hiring! Apply now — bit.ly/1MTBLll