ERC 721

This set of interfaces, contracts, and utilities are all related to the ERC721 Non-Fungible Token Standard.

For a walk through on how to create an ERC721 token read our ERC721 guide.

The EIP specifies four interfaces:

  • IERC721: Core functionality required in all compliant implementation.

  • IERC721Metadata: Optional extension that adds name, symbol, and token URI, almost always included.

  • IERC721Enumerable: Optional extension that allows enumerating the tokens on chain, often not included since it requires large gas overhead.

  • IERC721Receiver: An interface that must be implemented by contracts if they want to accept tokens through safeTransferFrom.

OpenZeppelin Contracts provides implementations of all four interfaces:

  • ERC721: The core and metadata extensions, with a base URI mechanism.

  • ERC721Enumerable: The enumerable extension.

  • ERC721Holder: A bare bones implementation of the receiver interface.

Additionally there are a few of other extensions:

This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC721 (such as _mint) and expose them as external functions in the way they prefer. On the other hand, ERC721 Presets (such as ERC721PresetMinterPauserAutoId) are designed using opinionated patterns to provide developers with ready to use, deployable contracts.

Core

IERC721

import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

Required interface of an ERC721 compliant contract.

balanceOf(address owner) → uint256 balance external

Returns the number of tokens in owner's account.

ownerOf(uint256 tokenId) → address owner external

Returns the owner of the tokenId token.

Requirements:

  • tokenId must exist.

safeTransferFrom(address from, address to, uint256 tokenId, bytes data) external

Safely transfers tokenId token from from to to.

Requirements:

  • from cannot be the zero address.

  • to cannot be the zero address.

  • tokenId token must exist and be owned by from.

  • If the caller is not from, it must be approved to move this token by either approve or setApprovalForAll.

  • If to refers to a smart contract, it must implement IERC721Receiver.onERC721Received, which is called upon a safe transfer.

Emits a Transfer event.

safeTransferFrom(address from, address to, uint256 tokenId) external

Safely transfers tokenId token from from to to, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked.

Requirements:

  • from cannot be the zero address.

  • to cannot be the zero address.

  • tokenId token must exist and be owned by from.

  • If the caller is not from, it must have been allowed to move this token by either approve or setApprovalForAll.

  • If to refers to a smart contract, it must implement IERC721Receiver.onERC721Received, which is called upon a safe transfer.

Emits a Transfer event.

transferFrom(address from, address to, uint256 tokenId) external

Transfers tokenId token from from to to.

Usage of this method is discouraged, use safeTransferFrom whenever possible.

Requirements:

  • from cannot be the zero address.

  • to cannot be the zero address.

  • tokenId token must be owned by from.

  • If the caller is not from, it must be approved to move this token by either approve or setApprovalForAll.

Emits a Transfer event.

approve(address to, uint256 tokenId) external

Gives permission to to to transfer tokenId token to another account. The approval is cleared when the token is transferred.

Only a single account can be approved at a time, so approving the zero address clears previous approvals.

Requirements:

  • The caller must own the token or be an approved operator.

  • tokenId must exist.

Emits an Approval event.

setApprovalForAll(address operator, bool _approved) external

Approve or remove operator as an operator for the caller. Operators can call transferFrom or safeTransferFrom for any token owned by the caller.

Requirements:

  • The operator cannot be the caller.

Emits an ApprovalForAll event.

getApproved(uint256 tokenId) → address operator external

Returns the account approved for tokenId token.

Requirements:

  • tokenId must exist.

isApprovedForAll(address owner, address operator) → bool external

Returns if the operator is allowed to manage all of the assets of owner.

Transfer(address from, address to, uint256 tokenId) event

Emitted when tokenId token is transferred from from to to.

Approval(address owner, address approved, uint256 tokenId) event

Emitted when owner enables approved to manage the tokenId token.

ApprovalForAll(address owner, address operator, bool approved) event

Emitted when owner enables or disables (approved) operator to manage all of its assets.

IERC721Metadata

import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";

name() → string external

Returns the token collection name.

symbol() → string external

Returns the token collection symbol.

tokenURI(uint256 tokenId) → string external

Returns the Uniform Resource Identifier (URI) for tokenId token.

IERC721Enumerable

import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";

totalSupply() → uint256 external

Returns the total amount of tokens stored by the contract.

tokenOfOwnerByIndex(address owner, uint256 index) → uint256 external

Returns a token ID owned by owner at a given index of its token list. Use along with balanceOf to enumerate all of owner's tokens.

tokenByIndex(uint256 index) → uint256 external

Returns a token ID at a given index of all the tokens stored by the contract. Use along with totalSupply to enumerate all tokens.

ERC721

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

Implementation of ERC721 Non-Fungible Token Standard, including the Metadata extension, but not including the Enumerable extension, which is available separately as ERC721Enumerable.

constructor(string name_, string symbol_) public

Initializes the contract by setting a name and a symbol to the token collection.

supportsInterface(bytes4 interfaceId) → bool public

balanceOf(address owner) → uint256 public

ownerOf(uint256 tokenId) → address public

name() → string public

symbol() → string public

tokenURI(uint256 tokenId) → string public

_baseURI() → string internal

Base URI for computing tokenURI. If set, the resulting URI for each token will be the concatenation of the baseURI and the tokenId. Empty by default, can be overridden in child contracts.

approve(address to, uint256 tokenId) public

getApproved(uint256 tokenId) → address public

setApprovalForAll(address operator, bool approved) public

isApprovedForAll(address owner, address operator) → bool public

transferFrom(address from, address to, uint256 tokenId) public

safeTransferFrom(address from, address to, uint256 tokenId) public

safeTransferFrom(address from, address to, uint256 tokenId, bytes data) public

_safeTransfer(address from, address to, uint256 tokenId, bytes data) internal

Safely transfers tokenId token from from to to, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked.

data is additional data, it has no specified format and it is sent in call to to.

This internal function is equivalent to safeTransferFrom, and can be used to e.g. implement alternative mechanisms to perform token transfer, such as signature-based.

Requirements:

  • from cannot be the zero address.

  • to cannot be the zero address.

  • tokenId token must exist and be owned by from.

  • If to refers to a smart contract, it must implement IERC721Receiver.onERC721Received, which is called upon a safe transfer.

Emits a Transfer event.

_exists(uint256 tokenId) → bool internal

Returns whether tokenId exists.

Tokens can be managed by their owner or approved accounts via approve or setApprovalForAll.

Tokens start existing when they are minted (_mint), and stop existing when they are burned (_burn).

_isApprovedOrOwner(address spender, uint256 tokenId) → bool internal

Returns whether spender is allowed to manage tokenId.

Requirements:

  • tokenId must exist.

_safeMint(address to, uint256 tokenId) internal

Safely mints tokenId and transfers it to to.

Requirements:

Emits a Transfer event.

_safeMint(address to, uint256 tokenId, bytes data) internal

Same as _safeMint, with an additional data parameter which is forwarded in IERC721Receiver.onERC721Received to contract recipients.

_mint(address to, uint256 tokenId) internal

Mints tokenId and transfers it to to.

Usage of this method is discouraged, use _safeMint whenever possible

Requirements:

  • tokenId must not exist.

  • to cannot be the zero address.

Emits a Transfer event.

_burn(uint256 tokenId) internal

Destroys tokenId. The approval is cleared when the token is burned.

Requirements:

  • tokenId must exist.

Emits a Transfer event.

_transfer(address from, address to, uint256 tokenId) internal

Transfers tokenId from from to to. As opposed to transferFrom, this imposes no restrictions on msg.sender.

Requirements:

  • to cannot be the zero address.

  • tokenId token must be owned by from.

Emits a Transfer event.

_approve(address to, uint256 tokenId) internal

Approve to to operate on tokenId

Emits an Approval event.

_setApprovalForAll(address owner, address operator, bool approved) internal

Approve operator to operate on all of owner tokens

Emits an ApprovalForAll event.

_requireMinted(uint256 tokenId) internal

Reverts if the tokenId has not been minted yet.

_beforeTokenTransfer(address from, address to, uint256 tokenId) internal

Hook that is called before any token transfer. This includes minting and burning.

Calling conditions:

  • When from and to are both non-zero, from's tokenId will be transferred to to.

  • When from is zero, tokenId will be minted for to.

  • When to is zero, from's tokenId will be burned.

  • from and to are never both zero.

To learn more about hooks, head to Using Hooks.

_afterTokenTransfer(address from, address to, uint256 tokenId) internal

Hook that is called after any transfer of tokens. This includes minting and burning.

Calling conditions:

  • when from and to are both non-zero.

  • from and to are never both zero.

To learn more about hooks, head to Using Hooks.

ERC721Enumerable

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";

This implements an optional extension of ERC721 defined in the EIP that adds enumerability of all the token ids in the contract as well as all token ids owned by each account.

supportsInterface(bytes4 interfaceId) → bool public

tokenOfOwnerByIndex(address owner, uint256 index) → uint256 public

totalSupply() → uint256 public

tokenByIndex(uint256 index) → uint256 public

_beforeTokenTransfer(address from, address to, uint256 tokenId) internal

Hook that is called before any token transfer. This includes minting and burning.

Calling conditions:

  • When from and to are both non-zero, from's tokenId will be transferred to to.

  • When from is zero, tokenId will be minted for to.

  • When to is zero, from's tokenId will be burned.

  • from cannot be the zero address.

  • to cannot be the zero address.

To learn more about hooks, head to Using Hooks.

IERC721Receiver

import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";

Interface for any contract that wants to support safeTransfers from ERC721 asset contracts.

onERC721Received(address operator, address from, uint256 tokenId, bytes data) → bytes4 external

Whenever an IERC721 tokenId token is transferred to this contract via IERC721.safeTransferFrom by operator from from, this function is called.

It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.

The selector can be obtained in Solidity with IERC721Receiver.onERC721Received.selector.

Extensions

ERC721Votes

import "@openzeppelin/contracts/token/ERC721/extensions/draft-ERC721Votes.sol";

Extension of ERC721 to support voting and delegation as implemented by Votes, where each individual NFT counts as 1 vote unit.

Tokens do not count as votes until they are delegated, because votes must be tracked which incurs an additional cost on every transfer. Token holders can either delegate to a trusted representative who will decide how to make use of the votes in governance decisions, or they can delegate to themselves to be their own representative.

Available since v4.5.

_afterTokenTransfer(address from, address to, uint256 tokenId) internal

Adjusts votes when tokens are transferred.

Emits a {Votes-DelegateVotesChanged} event.

_getVotingUnits(address account) → uint256 internal

Returns the balance of account.

ERC721Royalty

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Royalty.sol";

Extension of ERC721 with the ERC2981 NFT Royalty Standard, a standardized way to retrieve royalty payment information.

Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.

ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See Rationale in the EIP. Marketplaces are expected to voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.

Available since v4.5.

supportsInterface(bytes4 interfaceId) → bool public

_burn(uint256 tokenId) internal

See ERC721._burn. This override additionally clears the royalty information for the token.

Presets

These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code.

Utilities

ERC721Holder

import "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";

Implementation of the IERC721Receiver interface.

Accepts all token transfers. Make sure the contract is able to use its token with IERC721.safeTransferFrom, IERC721.approve or IERC721.setApprovalForAll.

onERC721Received(address, address, uint256, bytes) → bytes4 public

Always returns IERC721Receiver.onERC721Received.selector.