
ERC721-O: The standard protocol and implementation for on-chain NFTs
TechFlow Selected TechFlow Selected

ERC721-O: The standard protocol and implementation for on-chain NFTs
Catddle NFT will be the first cross-chain NFT developed using ERC721-O.
ERC721-O is designed by Catddle Lab, the development team behind Catddle NFT. Catddle NFT will be the first fully on-chain NFT built using ERC721-O.
*ERC721-O is a fully open-source project; contributions are welcome on GitHub!
Overview
ERC721-O is a standard protocol and implementation for omnichain Non-Fungible Tokens (NFTs), based on ERC721. The ERC721-O protocol aims to enable third-party applications (such as wallets or exchanges) to uniformly verify and interact with any NFT implementing this protocol.
ERC721-O introduces various cross-chain capabilities and proposes a series of solutions to address cross-chain security issues.
Background
LayerZero is a new blockchain infrastructure that enables message passing between different blockchains. According to the LayerZero paper, this messaging service ensures valid delivery. When a recipient receives a message m from a valid delivery service, the service guarantees that the associated transaction t is valid and has been committed on the sender's chain.
With this universal messaging protocol, the implementation of omnichain NFTs becomes possible.
Differences Between ERC721-O and Existing Omnichain NFTs*

Improvements in ERC721-O
More Secure
· Cross-Chain Gas Protection Mechanism
Although we have implemented non-blocking and other safety designs, NFTs may still get stuck during cross-chain transfers if the destination gas limit is set too low.
To prevent this, we introduced a cross-chain gas protection mechanism; contract owners can set a reasonable minimum gas limit to ensure all NFTs successfully complete cross-chain transfers without running out of gas, while preserving other cross-chain functionalities.
· Secure Remote Address Configuration
Updating an active omnichain NFT contract may lead to permanent fund loss. Additionally, when deploying an omnichain NFT contract to a new chain without following a specific function call order, NFTs may become blocked or even permanently lost during cross-chain transfers.
To solve these issues, ERC721-O introduces a secure remote address setup mechanism. This allows contract owners to avoid fund losses during contract updates and removes the need to manage function call orders across chains.
· Fixed Third-Party Library Version
Sending and receiving messages relies on the LayerZero library. When LayerZero updates, it’s essential to lock the version of the third-party library to avoid potential bugs from upgrades. This is also the best practice recommended by the official LayerZero team.
· Retaining Last Resort Option
Even with multiple safety mechanisms (e.g., non-blocking, gas protection), there may still be cases where message paths are blocked and cannot be retried successfully.
forceResumeReceive is our last resort option—otherwise, chain errors would remain permanently stuck. We retain it in the implementation as a final fallback.
Additional Features
· Support for Third-Party Transfer (Approval) Mode
Allowing third parties to transfer your tokens is a key feature provided in both ERC20 and ERC721. We added this functionality to help third-party applications better interact with omnichain NFTs.
· Freedom to Choose Target Address for Cross-Chain Transfers
Users can now transfer their NFTs to any address on another chain, rather than being limited to transferring only to the same address on the destination chain.
· Gas Airdrop Capability During NFT Transfer
After users send an NFT to another chain, they typically need to separately send native gas (Ether, BNB, AVAX, etc.) to the target address to use the NFT—a cumbersome extra step.
Now, gas airdrops can be completed simultaneously with the NFT transfer, eliminating additional actions on the destination chain.
· Allow Token Payment for Cross-Chain Fees
When LayerZero launches its token, users will be able to designate specific token holders to pay cross-chain fees. Discounts might be offered :)
More Transparent
· Public Disclosure of Key Deployment Information
In the ERC721-O protocol design, both the endpoint address and remote contract address must be publicly disclosed. This allows any user or third party to verify whether the endpoint address comes from the official LayerZero and whether the remote contract address is correctly configured.
Therefore, third parties such as exchanges and wallets can easily implement verification mechanisms for ERC721-O tokens to protect users from potential fund loss.
· Disclosure of Critical On-Chain Activities
Event emissions help users and third parties immediately understand what has occurred on-chain when critical activities take place.
In the ERC721-O interface design, sending and receiving NFTs across chains are required to emit events, helping users and third parties clearly track on-chain activity.
In the ERC721-O implementation, other critical actions (e.g., pausing, setting remote contract addresses) also emit events to notify users of important changes.
· Enable Nonce Tracking
Nonce indicates the sequence number of transactions sent from a specific address. LayerZero provides nonce tracking capability, which ERC721-O incorporates into its cross-chain events. Using event data, users and third parties can easily match transactions between source and destination chains.
Reduced Gas Consumption
Since LayerZero already performs gas estimation checks for users, pre-transfer gas estimation within the contract is redundant. ERC721-O removes this check to reduce gas consumption during cross-chain operations.
Code Designed for Easy Override and Reuse
All functions and variables are designed to be easily overridden and reused.
As a base class, virtual, override, and internal keywords are widely used throughout the codebase, along with clear comments, providing developers clearer guidance when inheriting and extending the contract.
Principles Behind Security Design
The official LayerZero documentation provides solid foundational implementations,examples. Moreover, NFTs likeGh0stly Gh0sts have demonstrated the immense potential of cross-chain NFTs.
However, for omnichain tokens to go further, serious security issues must be addressed. To tackle these, ERC721-O introduces a series of unique security designs.
Before diving into the details, an important concept must be introduced: cross-chain message blocking. Cross-chain message blocking refers to a state where messages cannot be delivered from the source contract to the destination chain. In this state, the source contract continues sending messages, but they remain stranded—neither on the source nor the destination chain—and cannot be received or executed.
This is not only frustrating for NFT users but also dangerous because:
All blocked messages disappear from the blockchain and wait in a queue maintained by LayerZero, potentially creating risks.
If failed messages cannot be resolved, the blocked message queue remains stuck indefinitely.
If contract owners use forceResumeReceive to handle failed messages instead of retryPayload, the failed messages may be permanently lost. Note: In omnichain NFT implementations, losing a message equals losing an NFT.
Thus, the primary goal of security design is to minimize the likelihood of message blocking.
· Cross-Chain Gas Protection Mechanism
It should be noted that even with non-blocking mechanisms, tokens may still get stuck due to insufficient destination gas limits.
In ERC721-O, adapter parameters are fully exposed to users to enable advanced features—such as airdropping gas tokens (e.g., Ether, BNB, AVAX) alongside NFT transfers—and allow manual setting of cross-chain gas limits. If a user sets the gas limit to 100 and initiates a cross-chain request, this is valid for the LayerZero endpoint but may cause transaction blocking—even under non-blocking mode.
This happens because when the cross-chain gas limit is too low, the transaction on the receiving chain fails before reaching the try-catch block. In other words, the non-blocking mechanism becomes ineffective in this case.
To resolve this, ERC721-O introduces a gas protection mechanism. This mechanism validates user-provided adapter parameters. If the parameters are invalid or allocated gas falls below the minimum threshold set by the contract owner, the transaction cannot proceed. This protection does not restrict enhanced adapter usage—users can still perform gas airdrops and similar functions via enhanced parameters.
Through this mechanism, contract owners can set a reasonable minimum gas limit based on their receiver function's gas consumption, preventing blocking issues.
· Secure Remote Address Setup
Anyone can send messages via LayerZero to anyone else, so remote contracts must be configured to prevent execution of unauthorized messages. In existing implementations, the setTrustedRemote function helps restrict message senders. Contract owners call setTrustRemote to set the remote contract address, ensuring the contract only accepts messages from that address.
This sounds reasonable, but it doesn’t account for the inevitable time gap between operations on different chains.
Consider a scenario: Contract a on Chain A and contract b on Chain B have mutually set each other as remote contracts and are actively used—meaning NFTs exist on both chains. Now suppose we want to upgrade contract a on Chain A to a new contract c on the same chain.
One might simply call setTrustRemote on Chain B to set c as the new remote address for contract b. However, this could lead to disaster: Users on Chain A can still send NFTs to Chain B, but since the remote address on Chain B has changed (no longer pointing to Chain A), all such NFTs will be permanently lost. Note: The non-blocking mechanism won’t help here—it only works after the correct remote address is set.
Conversely, changing contract a’s remote address first leads to the same risk: Users on Chain B might send NFTs to contract a before Chain B is updated. Since contract a’s remote address has already changed and no longer points to contract b, these NFTs will also be lost.
The key point is: We can never guarantee simultaneous operations across different chains. So does this mean we cannot update a contract once it’s in use?
There is a solution—the secure remote address setup mechanism in ERC721-O. We introduce a pauseMove function that takes a chainId parameter, locking the move functionality for that chain. This prevents users on the current chain from sending NFTs to the specified chain. The contract owner can later call unPauseMove(chainId) to unlock transfers after confirming that setRemote operations are finalized on both chains.
With this design, contract owners can safely update active contracts. Returning to our example: The owner calls pauseMove(A) on Chain B, preventing users on Chain B from sending NFTs to Chain A, while users on Chain A can continue sending to Chain B. Note: Contract b can still correctly receive NFTs from contract a, so no NFTs are lost during this window. Then, the owner calls pauseMove(B) on contract a (Chain A) and also on contract c (Chain A).
Now, the owner can call setRemote on contracts b and c in any order to establish mutual trust. Finally, calling unpause on both restores cross-chain transfers—successfully replacing contract a with contract c on Chain A.
This pattern applies to other scenarios too. For instance, when deploying an existing NFT from Chain A to Chain B, the owner must first configure the remote address on Chain B, otherwise NFTs may get stuck. With pauseMove, the owner can safely pause moves, set remote addresses in either order, and avoid risks from incorrect call sequences.
Indeed, this pattern can extend to other token types like ERC20, though we won’t elaborate further here.
Discussion
· Should We Remove On-Chain Gas Estimation?
The official LayerZero documentation recommends on-chain gas estimation to prevent transaction failures on the destination chain.
However, they have already implemented this check in their officially deployed smart contracts. Furthermore, for multiple message types, even on-chain gas estimation cannot guarantee accuracy. Also, if gas estimation fails, the non-blocking design of ERC721-O handles it gracefully without significant loss.
Therefore, enforcing on-chain gas estimation seems unnecessary—we’ve removed it from our current protocol version.
· Should We Remove the forceResumeReceive Function?
The forceResumeReceive function carries a high risk of fund loss. However, if an unexpected erroneous message blocks the message path and cannot be successfully retried, forceResumeReceive is the only way to clear such a blockage. Note: Non-blocking design alone cannot always ensure an open message path. To guard against unforeseen blocking, we retain it in the current implementation. You may override and disable this function only if your contract has IFG (Instant Finality Guarantee) properties—meaning if a transaction is accepted on the source chain, it will also be accepted on the destination chain.
Blocking harms user experience and risks fund loss. Hence, we aim to minimize its occurrence. Given that transaction order isn't critical in NFT cross-chain operations, we leverage the non-blocking mechanism to keep message paths open even after unexpected errors. If your contract can ensure correct execution after remote address validation, you may remove the non-blocking components.
ERC721-O remains an open, community-driven standard. We believe that with community contributions, ERC721-O will become the standard protocol for omnichain NFTs.
All conclusions above are derived from open-source documents and code from the LayerZero Lab, as well as experiments conducted on official LayerZero nodes. If you spot any errors, please feel free to comment or file an issue on GitHub. Thank you for reading!
* Note: In this article, we use the Gh0stly Gh0sts implementation and the officialexample as comparative benchmarks.
Join TechFlow official community to stay tuned
Telegram:https://t.me/TechFlowDaily
X (Twitter):https://x.com/TechFlowPost
X (Twitter) EN:https://x.com/BlockFlow_News















