API Reference

ERC721

This module provides interfaces, presets, and utilities related to ERC721 contracts.

For an overview of ERC721, read our ERC721 guide.

Interfaces

Starting from version 3.x.x, the interfaces are no longer part of the openzeppelin_access package. The references documented here are contained in the openzeppelin_interfaces package version 2.1.0-alpha.0.

use openzeppelin_interfaces::erc721::IERC721;

Interface of the IERC721 standard as defined in EIP721.

SRC5 ID

0x33eb2f84c309543403fd69f0d0f363781ef06ef6faeb0131ff16ea3175bd943

Functions

Events

Functions

balance_of(account: ContractAddress) → u256

external

#

Returns the number of NFTs owned by account.

owner_of(token_id: u256) → ContractAddress

external

#

Returns the owner address of token_id.

safe_transfer_from(from: ContractAddress, to: ContractAddress, token_id: u256, data: Span<felt252>)

external

#

Transfer ownership of token_id from from to to, checking first that to is aware of the ERC721 protocol to prevent tokens being locked forever. For information regarding how contracts communicate their awareness of the ERC721 protocol, see Receiving Tokens.

Emits a Transfer event.

transfer_from(from: ContractAddress, to: ContractAddress, token_id: u256)

external

#

Transfer ownership of token_id from from to to.

Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 transfers or else they may be permanently lost. Usage of IERC721::safe_transfer_from prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability.

Emits a Transfer event.

approve(to: ContractAddress, token_id: u256)

external

#

Change or reaffirm the approved address for an NFT.

Emits an Approval event.

set_approval_for_all(operator: ContractAddress, approved: bool)

external

#

Enable or disable approval for operator to manage all of the caller's assets.

Emits an ApprovalForAll event.

get_approved(token_id: u256) -> u256

external

#

Returns the address approved for token_id.

is_approved_for_all(owner: ContractAddress, operator: ContractAddress) -> bool

external

#

Query if operator is an authorized operator for owner.

Events

Approval(owner: ContractAddress, approved: ContractAddress, token_id: u256)

event

#

Emitted when owner enables approved to manage the token_id token.

ApprovalForAll(owner: ContractAddress, operator: ContractAddress, approved: bool)

event

#

Emitted when owner enables or disables operator to manage the token_id token.

Transfer(from: ContractAddress, to: ContractAddress, token_id: u256)

event

#

Emitted when token_id token is transferred from from to to.

use openzeppelin_interfaces::erc721::IERC721Metadata;

Interface for the optional metadata functions in EIP721.

SRC5 ID

0xabbcd595a567dce909050a1038e055daccb3c42af06f0add544fa90ee91f25

Functions

Functions

name() -> ByteArray

external

#

Returns the NFT name.

symbol() -> ByteArray

external

#

Returns the NFT ticker symbol.

token_uri(token_id: u256) -> ByteArray

external

#

Returns the Uniform Resource Identifier (URI) for the token_id token. If the URI is not set for token_id, the return value will be an empty ByteArray.

use openzeppelin_interfaces::erc721::IERC721Receiver;

Interface for contracts that support receiving safe_transfer_from transfers.

SRC5 ID

0x3a0dff5f70d80458ad14ae37bb182a728e3c8cdda0402a5daa86620bdf910bc

Functions

Functions

on_erc721_received(operator: ContractAddress, from: ContractAddress, token_id: u256, data: Span<felt252>) -> felt252

external

#

Whenever an IERC721 token_id token is transferred to this non-account contract via IERC721::safe_transfer_from by operator from from, this function is called.

Interface for the optional enumerable functions in EIP721.

SRC5 ID

0x16bc0f502eeaf65ce0b3acb5eea656e2f26979ce6750e8502a82f377e538c87

Functions

Functions

total_supply() -> u256

external

#

Returns the total amount of tokens stored by the contract.

token_by_index(index: u256) -> u256

external

#

Returns a token id at a given index of all the tokens stored by the contract. Use along with IERC721Enumerable::total_supply to enumerate all tokens.

token_of_owner_by_index(owner: ContractAddress, index: u256) -> u256

external

#

Returns the token id owned by owner at a given index of its token list. Use along with IERC721::balance_of to enumerate all of owner's tokens.

Core

use openzeppelin_token::erc721::ERC721Component;

ERC721 component implementing IERC721 and IERC721Metadata.

Implementing SRC5Component is a requirement for this component to be implemented.

See Hooks to understand how are hooks used.

Hooks

ERC721HooksTrait

Embeddable Mixin Implementations

ERC721MixinImpl

Embeddable Implementations

ERC721Impl

ERC721MetadataImpl

ERC721CamelOnlyImpl

ERC721MetadataCamelOnlyImpl

SRC5Impl

Internal functions

InternalImpl

Events

IERC721

Hooks

Hooks are functions which implementations can extend the functionality of the component source code. Every contract using ERC721Component is expected to provide an implementation of the ERC721HooksTrait. For basic token contracts, an empty implementation with no logic must be provided.

You can use openzeppelin_token::erc721::ERC721HooksEmptyImpl which is already available as part of the library for this purpose.

before_update(ref self: ContractState, to: ContractAddress, token_id: u256, auth: ContractAddress)

hook

#

Function executed at the beginning of the update function prior to any other logic.

after_update(ref self: ContractState, to: ContractAddress, token_id: u256, auth: ContractAddress)

hook

#

Function executed at the end of the update function.

Embeddable functions

balance_of(self: @ContractState, account: ContractAddress) → u256

external

#

owner_of(self: @ContractState, token_id: u256) → ContractAddress

external

#

See IERC721::owner_of.

Requirements:

  • token_id exists.

safe_transfer_from(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256, data: Span<felt252>)

external

#

See IERC721::safe_transfer_from.

Requirements:

  • Caller is either approved or the token_id owner.
  • to is not the zero address.
  • from is not the zero address.
  • token_id exists.
  • to is either an account contract or supports the IERC721Receiver interface.

transfer_from(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256)

external

#

See IERC721::transfer_from.

Requirements:

  • Caller either approved or the token_id owner.
  • to is not the zero address.
  • from is not the zero address.
  • token_id exists.

approve(ref self: ContractState, to: ContractAddress, token_id: u256)

external

#

See IERC721::approve.

Requirements:

  • The caller is either an approved operator or the token_id owner.
  • to cannot be the token owner or the zero address.
  • token_id exists.

set_approval_for_all(ref self: ContractState, operator: ContractAddress, approved: bool)

external

#

See IERC721::set_approval_for_all.

Requirements:

  • operator is not the zero address.

get_approved(self: @ContractState, token_id: u256) -> u256

external

#

See IERC721::get_approved.

Requirements:

  • token_id exists.

is_approved_for_all(self: @ContractState, owner: ContractAddress, operator: ContractAddress) -> bool

external

#

name(self: @ContractState) -> ByteArray

external

#

symbol(self: @ContractState) -> ByteArray

external

#

token_uri(self: @ContractState, token_id: u256) -> ByteArray

external

#

Returns the Uniform Resource Identifier (URI) for the token_id token. If a base URI is set, the resulting URI for each token will be the concatenation of the base URI and the token ID. For example, the base URI https://token-cdn-domain/ would be returned as https://token-cdn-domain/123 for token ID 123.

If the URI is not set for token_id, the return value will be an empty ByteArray.

balanceOf(self: @ContractState, account: ContractAddress) -> u256

external

#

ownerOf(self: @ContractState, tokenId: u256) -> ContractAddress

external

#

safeTransferFrom(ref self: ContractState, from: ContractAddress, to: ContractAddress, tokenId: u256, data: Span<felt252>)

external

#

transferFrom(ref self: ContractState, from: ContractAddress, to: ContractAddress, tokenId: u256)

external

#

setApprovalForAll(ref self: ContractState, operator: ContractAddress, approved: bool)

external

#

getApproved(self: @ContractState, tokenId: u256) -> ContractAddress

external

#

isApprovedForAll(self: @ContractState, owner: ContractAddress, operator: ContractAddress) -> bool

external

#

tokenURI(self: @ContractState, tokenId: u256) -> ByteArray

external

#

Internal functions

initializer(ref self: ContractState, name: ByteArray, symbol: ByteArray, base_uri: ByteArray)

internal

#

Initializes the contract by setting the token name and symbol. This should be used inside the contract's constructor.

Most ERC721 contracts expose the IERC721Metadata interface which is what this initializer is meant to support. If the contract DOES NOT expose the IERC721Metadata interface, meaning the token does not have a name, symbol, or URI, the contract must instead use initializer_no_metadata in the constructor. Failure to abide by these instructions can lead to unexpected issues especially with UIs.

initializer_no_metadata(ref self: ContractState)

internal

#

Initializes the contract with no metadata by registering only the IERC721 interface.

This initializer should ONLY be used during construction in the very specific instance when the contract does NOT expose the IERC721Metadata interface. Initializing a contract with this initializer means that tokens will not have a name, symbol, or URI.

exists(self: @ContractState, token_id: u256) -> bool

internal

#

Internal function that returns whether token_id exists.

Tokens start existing when they are minted (mint), and stop existing when they are burned (burn).

transfer(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256)

internal

#

Transfers token_id from from to to.

Internal function without access restriction.

This method may lead to the loss of tokens if to is not aware of the ERC721 protocol.

Requirements:

  • to is not the zero address.
  • from is the token owner.
  • token_id exists.

Emits a Transfer event.

mint(ref self: ContractState, to: ContractAddress, token_id: u256)

internal

#

Mints token_id and transfers it to to. Internal function without access restriction.

This method may lead to the loss of tokens if to is not aware of the ERC721 protocol.

Requirements:

  • to is not the zero address.
  • token_id does not exist.

Emits a Transfer event.

safe_transfer(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256, data: Span<felt252>)

internal

#

Transfers ownership of token_id from from if to is either an account or IERC721Receiver.

data is additional data, it has no specified format and is forwarded in IERC721Receiver::on_erc721_received to to.

This method makes an external call to the recipient contract, which can lead to reentrancy vulnerabilities.

Requirements:

  • to cannot be the zero address.
  • from must be the token owner.
  • token_id exists.
  • to is either an account contract or supports the IERC721Receiver interface.

Emits a Transfer event.

safe_mint(ref self: ContractState, to: ContractAddress, token_id: u256, data: Span<felt252>)

internal

#

Mints token_id if to is either an account or IERC721Receiver.

data is additional data, it has no specified format and is forwarded in IERC721Receiver::on_erc721_received to to.

This method makes an external call to the recipient contract, which can lead to reentrancy vulnerabilities.

Requirements:

  • token_id does not exist.
  • to is either an account contract or supports the IERC721Receiver interface.

Emits a Transfer event.

burn(ref self: ContractState, token_id: u256)

internal

#

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

This internal function does not check if the caller is authorized to operate on the token.

Requirements:

  • token_id exists.

Emits a Transfer event.

update(ref self: ContractState, to: ContractAddress, token_id: u256, auth: ContractAddress)

internal

#

Transfers token_id 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 token_id before the update.

The auth argument is optional. If the value passed is non-zero, 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.

This function can be extended using the ERC721HooksTrait, to add functionality before and/or after the transfer, mint, or burn.

_owner_of(self: @ContractState, token_id: felt252) -> ContractAddress

internal

#

Internal function that returns the owner address of token_id.

_require_owned(self: @ContractState, token_id: felt252) -> ContractAddress

internal

#

Version of _owner_of that panics if owner is the zero address.

_approve(ref self: ContractState, to: ContractAddress, token_id: u256, auth: ContractAddress)

internal

#

Approve to to operate on token_id

The auth argument is optional. If the value passed is non-zero, 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.

_approve_with_optional_event(ref self: ContractState, to: ContractAddress, token_id: u256, auth: ContractAddress, emit_event: bool)

internal

#

Variant of _approve with an optional flag to enable or disable the Approval event. The event is not emitted in the context of transfers.

If auth is zero and emit_event is false, this function will not check that the token exists.

Requirements:

  • if auth is non-zero, it must be either the owner of the token or approved to operate on all of its tokens.

May emit an Approval event.

_set_approval_for_all(ref self: ContractState, owner: ContractAddress, operator: ContractAddress, approved: bool)

internal

#

Enables or disables approval for operator to manage all of the owner assets.

Requirements:

  • operator is not the zero address.

Emits an Approval event.

_set_base_uri(ref self: ContractState, base_uri: ByteArray)

internal

#

Internal function that sets the base_uri.

_base_uri(self: @ContractState) -> ByteArray

internal

#

Base URI for computing token_uri.

If set, the resulting URI for each token will be the concatenation of the base URI and the token ID. Returns an empty ByteArray if not set.

_is_authorized(self: @ContractState, owner: ContractAddress, spender: ContractAddress, token_id: u256) -> bool

internal

#

Returns whether spender is allowed to manage owner's tokens, or token_id in particular (ignoring whether it is owned by owner).

This function assumes that owner is the actual owner of token_id and does not verify this assumption.

_check_authorized(self: @ContractState, owner: ContractAddress, spender: ContractAddress, token_id: u256) -> bool

internal

#

Checks if spender can operate on token_id, assuming the provided owner is the actual owner.

Requirements:

  • owner cannot be the zero address.
  • spender cannot be the zero address.
  • spender must be the owner of token_id or be approved to operate on it.

This function assumes that owner is the actual owner of token_id and does not verify this assumption.

Events

Approval(owner: ContractAddress, approved: ContractAddress, token_id: u256)

event

#

ApprovalForAll(owner: ContractAddress, operator: ContractAddress, approved: bool)

event

#

Transfer(from: ContractAddress, to: ContractAddress, token_id: u256)

event

#
use openzeppelin_token::erc721::ERC721ReceiverComponent;

ERC721Receiver component implementing IERC721Receiver.

Implementing SRC5Component is a requirement for this component to be implemented.

Embeddable Mixin Implementations

ERCReceiverMixinImpl

Embeddable Implementations

ERC721ReceiverImpl

ERC721ReceiverCamelImpl

Internal Functions

InternalImpl

Embeddable functions

on_erc721_received(self: @ContractState, operator: ContractAddress, from: ContractAddress, token_id: u256, data Span<felt252>) -> felt252

external

#

Returns the IERC721Receiver interface ID.

onERC721Received(self: @ContractState, operator: ContractAddress, from: ContractAddress, token_id: u256, data Span<felt252>) -> felt252

external

#

Internal functions

initializer(ref self: ContractState)

internal

#

Registers the IERC721Receiver interface ID as supported through introspection.

Extensions

use openzeppelin_token::erc721::extensions::ERC721EnumerableComponent;

Extension of ERC721 as 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. This extension allows contracts to publish their entire list of NFTs and make them discoverable.

Implementing ERC721Component is a requirement for this component to be implemented.

To properly track token ids, this extension requires that the ERC721EnumerableComponent::before_update function is called before every transfer, mint, or burn operation. For this, the ERC721HooksTrait::before_update hook must be used. Here's how the hook should be implemented in a contract:

#[starknet::contract]
mod ERC721EnumerableContract {
    (...)

    component!(path: ERC721Component, storage: erc721, event: ERC721Event);
    component!(path: ERC721EnumerableComponent, storage: erc721_enumerable, event: ERC721EnumerableEvent);
    component!(path: SRC5Component, storage: src5, event: SRC5Event);

    impl ERC721HooksImpl of ERC721Component::ERC721HooksTrait<ContractState> {
        fn before_update(
            ref self: ERC721Component::ComponentState<ContractState>,
            to: ContractAddress,
            token_id: u256,
            auth: ContractAddress
        ) {
            let mut contract_state = self.get_contract_mut();
            contract_state.erc721_enumerable.before_update(to, token_id);
        }
    }
}

Embeddable Implementations

ERC721EnumerableImpl

Internal functions

InternalImpl

Embeddable functions

total_supply(self: @ContractState) → u256

external

#

Returns the current amount of votes that account has.

token_by_index(self: @ContractState, index: u256) → u256

external

#

See IERC721Enumerable::token_by_index.

Requirements:

  • index is less than the total token supply.

token_of_owner_by_index(self: @ContractState, owner: ContractAddress, index: u256) → u256

external

#

See IERC721Enumerable::token_of_owner_by_index.

Requirements:

  • index is less than owner's token balance.
  • owner is not the zero address.

Internal functions

initializer(ref self: ContractState)

internal

#

Registers the IERC721Enumerable interface ID as supported through introspection.

before_update(ref self: ContractState, to: ContractAddress, token_id: u256)

internal

#

Updates the ownership and token-tracking data structures.

When a token is minted (or burned), token_id is added to (or removed from) the token-tracking structures.

When a token is transferred, minted, or burned, the ownership-tracking data structures reflect the change in ownership of token_id.

This must be added to the implementing contract's ERC721HooksTrait::before_update hook.

all_tokens_of_owner(self: @ContractState, owner: ContractAddress) → Span<u256>

internal

#

Returns a list of all token ids owned by the specified owner. This function provides a more efficient alternative to calling ERC721::balance_of and iterating through tokens with ERC721Enumerable::token_of_owner_by_index.

Requirements:

  • owner is not the zero address.

_add_token_to_owner_enumeration(ref self: ContractState, to: ContractAddress, token_id: u256)

internal

#

Adds token to this extension's ownership-tracking data structures.

_add_token_to_all_tokens_enumeration(ref self: ContractState, token_id: u256)

internal

#

Adds token to this extension's token-tracking data structures.

_remove_token_from_owner_enumeration(ref self: ContractState, from: ContractAddress, token_id: u256)

internal

#

Removes a token from this extension's ownership-tracking data structures.

This has 0(1) time complexity but alters the indexed order of owned tokens by swapping token_id and the index thereof with the last token id and the index thereof e.g. removing 1 from [1, 2, 3, 4] results in [4, 2, 3].

_remove_token_from_all_tokens_enumeration(ref self: ContractState, token_id: u256)

internal

#

Removes token_id from this extension's token-tracking data structures.

This has 0(1) time complexity but alters the indexed order by swapping token_id and the index thereof with the last token id and the index thereof e.g. removing 1 from [1, 2, 3, 4] results in [4, 2, 3].

Presets

use openzeppelin_presets::ERC721Upgradeable;

Upgradeable ERC721 contract leveraging ERC721Component.

Sierra class hash

0x04080084ac1ba5a26b4638ac7ca2ff009a9a9b86bf6db5df05e96c90aa143df5

Constructor

Embedded Implementations

ERC721MixinImpl

OwnableMixinImpl

External Functions

Constructor

constructor(ref self: ContractState, name: ByteArray, symbol: ByteArray, recipient: ContractAddress, token_ids: Span<u256>, base_uri: ByteArray, owner: ContractAddress)

constructor

#

Sets the name and symbol. Mints token_ids tokens to recipient and sets the base_uri. Assigns owner as the contract owner with permissions to upgrade.

External functions

upgrade(ref self: ContractState, new_class_hash: ClassHash)

external

#

Upgrades the contract to a new implementation given by new_class_hash.

Requirements:

  • The caller is the contract owner.
  • new_class_hash cannot be zero.