ERC-4400 ERC-721 Consumer Role Extension (EIP-721 Consumable Extension)

Final · NFTs & multi-token · created 2021-10-30

Adds a standard interface to ERC-721 NFTs for assigning and querying a consumer address, which uses the token without being its owner. It is the basis for services that separate ownership from use, such as NFT rental and staking.

Why it is needed

ERC-721 NFTs define only three roles: owner, operator, and approved address. But an NFT has a use beyond ownership, which is utilization. For example, the owner of a land NFT in a metaverse must be able to delegate scene deployment to another address, and a person who deposits an NFT in a staking contract wants to keep enjoying the token's utility benefits even after ownership moves to the contract. Without a standard, each contract creates its own usage-right role with different names and methods, and wallets or other contracts cannot read or handle that role consistently. As a result, it becomes hard to build services such as a general-purpose NFT rental marketplace that spans many projects.

What to implement

In depth

The IEIP721Consumable interface and the ERC-165 identifier

A contract that follows this extension MUST implement the IEIP721Consumable interface. The extension itself is OPTIONAL for an ERC-721 contract. The ERC-165 identifier of the interface is 0x953c8dfa, and calling supportsInterface with this value MUST return true. This lets external code such as wallets or marketplaces check on-chain in advance whether an NFT contract supports the consumer extension. The interface consists of just one event and two functions.

consumerOf: querying the consumer

consumerOf(uint256 _tokenId) returns the current consumer address of the NFT. The zero address means no consumer is assigned, and execution is aborted (throw) if _tokenId is not a valid NFT. This function MAY be implemented as pure or view. Because it is a read-only function that does not change state, it serves as the standard entry point for external services to check who holds the usage right to a given token.

changeConsumer and the ConsumerChanged event

changeConsumer(address _consumer, uint256 _tokenId) changes or reaffirms the consumer address of the NFT. Execution is aborted if msg.sender is not the current owner, an operator approved by the owner, or an approved address, and it is also aborted if _tokenId is not a valid NFT. Passing the zero address means there is no consumer. The function MAY be implemented as public or external. When the consumer changes, the ConsumerChanged(owner, consumer, tokenId) event MUST be emitted.

The limit on consumer permissions

What a consumer can do within the system is left to each implementing contract. There is one exception. A consumer MUST NOT be treated as an owner, operator, or approved address under the ERC-721 specification, and therefore must not be able to execute transfers or approvals. The original Rationale states the reason for this restriction plainly. Many use cases need a separate role without owner permissions, and an implementation that gives a consumer owner permissions defeats the purpose of this standard.

Consumer reset on transfer

Every time an NFT is transferred, the consumer MUST be changed to the default address, and using the zero address address(0) as the default is RECOMMENDED. The comment on the ConsumerChanged event says the same. When a Transfer event is emitted, the consumer is reset to none even if the NFT had one. In other words, usage rights do not follow ownership, and a new owner who wants a consumer must assign one again with changeConsumer.

Design principles and name choice

The original text lists four factors that influenced the design of the standard: keeping the number of functions to a minimum to avoid bloating contracts, simplicity, gas efficiency, and not reusing or overlaying existing roles such as owner, operator, and approved address. The name operator was also considered for the role, but consumer was chosen because operator is already defined and used in ERC-721. Consumer matches the meaning of an entity that uses a token instance without owning it. This standard has been finalized with Final status, is compatible with existing ERC-721, and no other standard defines a similar role.

Things to watch out for

Original ERC · ← ERCs