ERC-7743 Multi-owner NFT (MO-NFT) (Multi-Owner Non-Fungible Tokens (MO-NFT))

Final · NFTs & multi-token · created 2024-07-13

A standard that lets multiple people own a single NFT at the same time. Transferring it keeps the existing owners in place, and a set fee is paid to the provider on every transfer.

Why it is needed

The existing NFT standard (ERC-721) uses a sole-ownership model in which a token has exactly one owner. Digital assets such as files, however, do not lose quality when copied and can be held by many people, and the sole-ownership model cannot capture this. Passing ownership strips the original owner of their rights, so a structure in which several people jointly own the same asset cannot be built in a standard way. The standard also has no mechanism for the party who first provided an asset to keep earning rewards as it circulates afterward. This standard supports joint ownership by adding the new owner to a list on transfer instead of removing the existing owner, and it sends a set fee to the provider on every transfer so that creators and providers are rewarded. It also defines an archive mechanism through which an owner voluntarily gives up the right to transfer.

What to implement

In depth

Additive ownership model

MO-NFT keeps each token's owner list as an enumerable set, which prevents duplicates and makes lookups efficient. transferFrom does not remove the existing owner. It adds the to address to the set and increases balanceOf of to by 1. The reference implementation uses require to check that the caller is an owner (isOwner), that to is not the zero address, and that to is not already an owner, and a transfer to an address that is already an owner reverts with the error "MO-NFT: Recipient is already an owner". When the transfer completes, a TokenTransferred event is emitted.

Provider role and fee handling

The account that called mintToken() is recorded as the first owner and the provider. Only the provider can set or change the transfer fee with setTransferValue, and a TransferValueUpdated event is emitted when it changes. When a transfer occurs, ether equal to transferValue is paid from the contract to the provider. The reference implementation checks address(this).balance >= transferValue, sends the payment with call, and reverts if it fails. In other words, the contract must hold enough balance to pay the fee for a transfer to succeed.

Archive: irreversibly giving up transfers

An owner can mark themselves as archived for a specific token with archive(tokenId). An archived owner can no longer transfer that token, and once set it cannot be undone. On a digital asset platform, this state means the actual digital asset can be downloaded directly, and an owner who is not archived must first switch to the archived state to download the asset. The Rationale explains that this mechanism replaces the existing notion of burning ownership. An ArchivedStatusUpdated event is emitted when the status changes.

ERC-721 compatibility and intentional differences

MO-NFT implements balanceOf, ownerOf, and transferFrom from ERC-721 and declares the IERC721 and IERC165 interfaces in supportsInterface so that it works with existing tools and platforms. However, approve, getApproved, setApprovalForAll, and isApprovedForAll are intentionally disabled or redefined. Without a joint-ownership consensus mechanism, allowing approvals could let a single co-owner's approval trigger an unwanted transfer, and the reference implementation reverts approval-related calls. safeTransferFrom is also restricted, and the source text describes an implementation approach that, as in ERC-721, adds the new owner and then checks onERC721Received on the receiving contract. Because of these differences, compatibility with existing marketplaces that depend on approve may be limited.

Interpreting ownerOf

For compatibility, ownerOf returns the first owner in the owner list. However, the notion of a single owner does not fully apply to MO-NFT, so the address returned by ownerOf must not be interpreted as the sole owner. Actual ownership is checked with isOwner(tokenId, account), and the number of owners with getOwnersCount(tokenId). The source text states that developers must be aware of these differences when integrating MO-NFT into systems designed for standard ERC-721.

The digital asset registration function provide

Besides mintToken(), the minting function provide(string memory assetName, uint256 size, bytes32 fileHash, address provider, uint256 transferValue) is defined. It takes the asset name, size, file hash, provider address, and transfer fee, and returns a token identifier. The reference implementation includes the base implementation MONFT.sol, DigitalAsset.sol, an extended implementation for digital assets with provider fees, and the IDigitalAsset.sol interface that defines asset management functions.

Things to watch out for

Original ERC · ← ERCs