ERC721Upgradeable
Inherits: Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721, IERC721Metadata, IERC721Errors
Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC-721] Non-Fungible Token Standard, including the Metadata extension, but not including the Enumerable extension, which is available separately as {ERC721Enumerable}.
State Variables
ERC721StorageLocation
bytes32 private constant ERC721StorageLocation = 0x80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079300;
Functions
_getERC721Storage
function _getERC721Storage() private pure returns (ERC721Storage storage $);
__ERC721_init
Initializes the contract by setting a name
and a symbol
to the token collection.
function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing;
__ERC721_init_unchained
function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing;
supportsInterface
Query if a contract implements an interface
Interface identification is specified in ERC-165. This function uses less than 30,000 gas.
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC165Upgradeable, IERC165)
returns (bool);
Parameters
Name | Type | Description |
---|---|---|
interfaceId | bytes4 |
Returns
Name | Type | Description |
---|---|---|
<none> | bool | true if the contract implements interfaceID and interfaceID is not 0xffffffff, false otherwise |
balanceOf
Count all NFTs assigned to an owner
NFTs assigned to the zero address are considered invalid, and this function throws for queries about the zero address.
function balanceOf(address owner) public view virtual returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
owner | address |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | The number of NFTs owned by _owner , possibly zero |
ownerOf
Find the owner of an NFT
NFTs assigned to zero address are considered invalid, and queries about them do throw.
function ownerOf(uint256 tokenId) public view virtual returns (address);
Parameters
Name | Type | Description |
---|---|---|
tokenId | uint256 |
Returns
Name | Type | Description |
---|---|---|
<none> | address | The address of the owner of the NFT |
name
A descriptive name for a collection of NFTs in this contract
function name() public view virtual returns (string memory);
symbol
An abbreviated name for NFTs in this contract
function symbol() public view virtual returns (string memory);
tokenURI
A distinct Uniform Resource Identifier (URI) for a given asset.
Throws if _tokenId
is not a valid NFT. URIs are defined in RFC
3986. The URI may point to a JSON file that conforms to the "ERC721
Metadata JSON Schema".
function tokenURI(uint256 tokenId) public view virtual returns (string memory);
_baseURI
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.
function _baseURI() internal view virtual returns (string memory);
approve
Change or reaffirm the approved address for an NFT
The zero address indicates there is no approved address.
Throws unless msg.sender
is the current NFT owner, or an authorized
operator of the current owner.
function approve(address to, uint256 tokenId) public virtual;
Parameters
Name | Type | Description |
---|---|---|
to | address | |
tokenId | uint256 |
getApproved
Get the approved address for a single NFT
Throws if _tokenId
is not a valid NFT.
function getApproved(uint256 tokenId) public view virtual returns (address);
Parameters
Name | Type | Description |
---|---|---|
tokenId | uint256 |
Returns
Name | Type | Description |
---|---|---|
<none> | address | The approved address for this NFT, or the zero address if there is none |
setApprovalForAll
Enable or disable approval for a third party ("operator") to manage
all of msg.sender
's assets
Emits the ApprovalForAll event. The contract MUST allow multiple operators per owner.
function setApprovalForAll(address operator, bool approved) public virtual;
Parameters
Name | Type | Description |
---|---|---|
operator | address | |
approved | bool |
isApprovedForAll
Query if an address is an authorized operator for another address
function isApprovedForAll(address owner, address operator) public view virtual returns (bool);
Parameters
Name | Type | Description |
---|---|---|
owner | address | |
operator | address |
Returns
Name | Type | Description |
---|---|---|
<none> | bool | True if _operator is an approved operator for _owner , false otherwise |
transferFrom
Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
TO CONFIRM THAT _to
IS CAPABLE OF RECEIVING NFTS OR ELSE
THEY MAY BE PERMANENTLY LOST
Throws unless msg.sender
is the current owner, an authorized
operator, or the approved address for this NFT. Throws if _from
is
not the current owner. Throws if _to
is the zero address. Throws if
_tokenId
is not a valid NFT.
function transferFrom(address from, address to, uint256 tokenId) public virtual;
Parameters
Name | Type | Description |
---|---|---|
from | address | |
to | address | |
tokenId | uint256 |
safeTransferFrom
Transfers the ownership of an NFT from one address to another address
Throws unless msg.sender
is the current owner, an authorized
operator, or the approved address for this NFT. Throws if _from
is
not the current owner. Throws if _to
is the zero address. Throws if
_tokenId
is not a valid NFT. When transfer is complete, this function
checks if _to
is a smart contract (code size > 0). If so, it calls
onERC721Received
on _to
and throws if the return value is not
bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))
.
function safeTransferFrom(address from, address to, uint256 tokenId) public;
Parameters
Name | Type | Description |
---|---|---|
from | address | |
to | address | |
tokenId | uint256 |
safeTransferFrom
Transfers the ownership of an NFT from one address to another address
Throws unless msg.sender
is the current owner, an authorized
operator, or the approved address for this NFT. Throws if _from
is
not the current owner. Throws if _to
is the zero address. Throws if
_tokenId
is not a valid NFT. When transfer is complete, this function
checks if _to
is a smart contract (code size > 0). If so, it calls
onERC721Received
on _to
and throws if the return value is not
bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))
.
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual;
Parameters
Name | Type | Description |
---|---|---|
from | address | |
to | address | |
tokenId | uint256 | |
data | bytes | Additional data with no specified format, sent in call to _to |
_ownerOf
Returns the owner of the tokenId
. Does NOT revert if token doesn't exist
IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the
core ERC-721 logic MUST be matched with the use of _increaseBalance to keep balances
consistent with ownership. The invariant to preserve is that for any address a
the value returned by
balanceOf(a)
must be equal to the number of tokens such that _ownerOf(tokenId)
is a
.
function _ownerOf(uint256 tokenId) internal view virtual returns (address);
_getApproved
Returns the approved address for tokenId
. Returns 0 if tokenId
is not minted.
function _getApproved(uint256 tokenId) internal view virtual returns (address);
_isAuthorized
Returns whether spender
is allowed to manage owner
's tokens, or tokenId
in
particular (ignoring whether it is owned by owner
).
WARNING: This function assumes that owner
is the actual owner of tokenId
and does not verify this
assumption.
function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool);
_checkAuthorized
*Checks if spender
can operate on tokenId
, assuming the provided owner
is the actual owner.
Reverts if:
spender
does not have approval fromowner
fortokenId
.spender
does not have approval to manage all ofowner
's assets. WARNING: This function assumes thatowner
is the actual owner oftokenId
and does not verify this assumption.*
function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual;
_increaseBalance
Unsafe write access to the balances, used by extensions that "mint" tokens using an ownerOf override. NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that a uint256 would ever overflow from increments when these increments are bounded to uint128 values. WARNING: Increasing an account's balance using this function tends to be paired with an override of the {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership remain consistent with one another.
function _increaseBalance(address account, uint128 value) internal virtual;
_update
Transfers tokenId
from its current owner to to
, or alternatively mints (or burns) if the current owner
(or to
) is the zero address. Returns the owner of the tokenId
before the update.
The auth
argument is optional. If the value passed is non 0, then this function will check that
auth
is either the owner of the token, or approved to operate on the token (by the owner).
Emits a {Transfer} event.
NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}.
function _update(address to, uint256 tokenId, address auth) internal virtual returns (address);
_mint
*Mints tokenId
and transfers it to to
.
WARNING: 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.*
function _mint(address to, uint256 tokenId) internal;
_safeMint
*Mints tokenId
, transfers it to to
and checks for to
acceptance.
Requirements:
tokenId
must not exist.- If
to
refers to a smart contract, it must implement IERC721Receiver-onERC721Received, which is called upon a safe transfer. Emits a {Transfer} event.*
function _safeMint(address to, uint256 tokenId) internal;
_safeMint
Same as _safeMint
, with an additional data
parameter which is
forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual;
_burn
*Destroys tokenId
.
The approval is cleared when the token is burned.
This is an internal function that does not check if the sender is authorized to operate on the token.
Requirements:
tokenId
must exist. Emits a {Transfer} event.*
function _burn(uint256 tokenId) internal;
_transfer
*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.*
function _transfer(address from, address to, uint256 tokenId) internal;
_safeTransfer
*Safely transfers tokenId
token from from
to to
, checking that contract recipients
are aware of the ERC-721 standard 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 like safeTransferFrom in the sense that it invokes
{IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g.
implement alternative mechanisms to perform token transfer, such as signature-based.
Requirements:
tokenId
token must exist and be owned byfrom
.to
cannot be the zero address.from
cannot be the zero address.- If
to
refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.*
function _safeTransfer(address from, address to, uint256 tokenId) internal;
_safeTransfer
Same as _safeTransfer
, with an additional data
parameter which is
forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual;
_approve
Approve to
to operate on tokenId
The auth
argument is optional. If the value passed is non 0, then this function will check that auth
is
either the owner of the token, or approved to operate on all tokens held by this owner.
Emits an {Approval} event.
Overrides to this logic should be done to the variant with an additional bool emitEvent
argument.
function _approve(address to, uint256 tokenId, address auth) internal;
_approve
Variant of _approve
with an optional flag to enable or disable the {Approval} event. The event is not
emitted in the context of transfers.
function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual;
_setApprovalForAll
*Approve operator
to operate on all of owner
tokens
Requirements:
- operator can't be the address zero. Emits an {ApprovalForAll} event.*
function _setApprovalForAll(address owner, address operator, bool approved) internal virtual;
_requireOwned
Reverts if the tokenId
doesn't have a current owner (it hasn't been minted, or it has been burned).
Returns the owner.
Overrides to ownership logic should be done to _ownerOf.
function _requireOwned(uint256 tokenId) internal view returns (address);
Structs
ERC721Storage
Note: storage-location: erc7201:openzeppelin.storage.ERC721
struct ERC721Storage {
string _name;
string _symbol;
mapping(uint256 tokenId => address) _owners;
mapping(address owner => uint256) _balances;
mapping(uint256 tokenId => address) _tokenApprovals;
mapping(address owner => mapping(address operator => bool)) _operatorApprovals;
}