ERC 721
This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc721 |
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 throughsafeTransferFrom
.
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:
-
ERC721URIStorage
: A more flexible but more expensive way of storing metadata. -
ERC721Votes
: Support for voting and vote delegation. -
ERC721Royalty
: A way to signal royalty information following ERC2981. -
ERC721Pausable
: A primitive to pause contract operation. -
ERC721Burnable
: A way for token holders to burn their own tokens.
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 byfrom
. -
If the caller is not
from
, it must be approved to move this token by eitherapprove
orsetApprovalForAll
. -
If
to
refers to a smart contract, it must implementIERC721Receiver.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 byfrom
. -
If the caller is not
from
, it must be have been allowed to move this token by eitherapprove
orsetApprovalForAll
. -
If
to
refers to a smart contract, it must implementIERC721Receiver.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 byfrom
. -
If the caller is not
from
, it must be approved to move this token by eitherapprove
orsetApprovalForAll
.
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
.
IERC721Metadata
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
IERC721Enumerable
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
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.
balanceOf(address owner) → uint256
public
See IERC721.balanceOf
.
ownerOf(uint256 tokenId) → address
public
See IERC721.ownerOf
.
name() → string
public
See IERC721Metadata.name
.
_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
See IERC721.approve
.
getApproved(uint256 tokenId) → address
public
See IERC721.getApproved
.
transferFrom(address from, address to, uint256 tokenId)
public
See IERC721.transferFrom
.
_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 byfrom
. -
If
to
refers to a smart contract, it must implementIERC721Receiver.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:
-
tokenId
must not exist. -
If
to
refers to a smart contract, it must implementIERC721Receiver.onERC721Received
, which is called upon a safe transfer.
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 byfrom
.
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.
_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
andto
are both non-zero,from
'stokenId
will be transferred toto
. -
When
from
is zero,tokenId
will be minted forto
. -
When
to
is zero,from
'stokenId
will be burned. -
from
andto
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
andto
are both non-zero. -
from
andto
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.
_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
andto
are both non-zero,from
'stokenId
will be transferred toto
. -
When
from
is zero,tokenId
will be minted forto
. -
When
to
is zero,from
'stokenId
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
ERC721Pausable
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Pausable.sol";
ERC721 token with pausable token transfers, minting and burning.
Useful for scenarios such as preventing trades until the end of an evaluation period, or having an emergency switch for freezing all token transfers in the event of a large bug.
ERC721Burnable
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
ERC721 Token that can be irreversibly burned (destroyed).
burn(uint256 tokenId)
public
Burns tokenId
. See ERC721._burn
.
Requirements:
-
The caller must own
tokenId
or be an approved operator.
ERC721URIStorage
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
ERC721 token with storage based token URI management.
_setTokenURI(uint256 tokenId, string _tokenURI)
internal
Sets _tokenURI
as the tokenURI of tokenId
.
Requirements:
-
tokenId
must exist.
_burn(uint256 tokenId)
internal
Destroys tokenId
.
The approval is cleared when the token is burned.
Requirements:
-
tokenId
must exist.
Emits a Transfer
event.
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.
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.
_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
.