NonFungibleToken API
This module provides the full NonFungibleToken module API.
For an overview of the module, read the NonFungibleToken guide.
import "./node_modules/@openzeppelin/compact-contracts/token/NonFungibleToken";Ledger
_name: Opaque<"string">
sealed ledger
#The token's human-readable name, set once at construction.
_symbol: Opaque<"string">
sealed ledger
#The token's ticker symbol, set once at construction.
_isInitialized: Boolean
ledger
#Initialization flag, tracked per-module to avoid the compiler's shared transitive-dependency state bug (LFDT-Minokawa/compact#270). See the Initializable module for rationale.
_owners: Map<Uint<128>, Either<Bytes<32>, ContractAddress>>
ledger
#Mapping from token IDs to their owner addresses.
_balances: Map<Either<Bytes<32>, ContractAddress>, Uint<128>>
ledger
#Mapping from account addresses to their token balances.
_tokenApprovals: Map<Uint<128>, Either<Bytes<32>, ContractAddress>>
ledger
#Mapping from token IDs to approved addresses.
_operatorApprovals: Map<Either<Bytes<32>, ContractAddress>, Map<Either<Bytes<32>, ContractAddress>, Boolean>>
ledger
#Mapping from owner addresses to operator approvals.
_tokenURIs: Map<Uint<128>, Opaque<"string">>
ledger
#Mapping from token IDs to their metadata URIs.
Witnesses
wit_NonFungibleTokenSK() → Bytes<32>
witness
#Returns the caller's secret key used in deriving the account identifier.
The same key produces the same account identifier across all contracts. Users who desire cross-contract unlinkability should use different keys per contract.
Circuits
initialize(name_: Opaque<"string">, symbol_: Opaque<"string">) → []
circuit
#Initializes the contract by setting the name and symbol.
This MUST be called in the implementing contract's constructor. Failure to do so can lead to an irreparable contract.
Requirements:
- Contract is not initialized.
balanceOf(owner: Either<Bytes<32>, ContractAddress>) → Uint<128>
circuit
#Returns the number of tokens in owner's account.
Requirements:
- The contract is initialized.
ownerOf(tokenId: Uint<128>) → Either<Bytes<32>, ContractAddress>
circuit
#Returns the owner of the tokenId token.
Requirements:
- The contract is initialized.
- The
tokenIdmust exist.
name() → Opaque<"string">
circuit
#Returns the token name.
Requirements:
- The contract is initialized.
symbol() → Opaque<"string">
circuit
#Returns the symbol of the token.
Requirements:
- The contract is initialized.
tokenURI(tokenId: Uint<128>) → Opaque<"string">
circuit
#Returns the token URI for the given tokenId. Returns the empty
string if a tokenURI does not exist.
Requirements:
- The contract is initialized.
- The
tokenIdmust exist.
Native strings and string operations aren't supported within the Compact language, e.g. concatenating a base URI + token ID is not possible like in other NFT implementations. Therefore, we propose the URI storage approach; whereby, NFTs may or may not have unique "base" URIs. It's up to the implementation to decide on how to handle this.
approve(to: Either<Bytes<32>, ContractAddress>, tokenId: Uint<128>) → []
circuit
#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 value clears previous approvals.
In the case of an external (non-contract) caller, the caller's identity is derived from the wit_NonFungibleTokenSK
witness as persistentHash(secretKey).
Requirements:
- The contract is initialized.
- The caller must either own the token or be an approved operator.
tokenIdmust exist.
getApproved(tokenId: Uint<128>) → Either<Bytes<32>, ContractAddress>
circuit
#Returns the account approved for tokenId token.
Requirements:
- The contract is initialized.
tokenIdmust exist.
setApprovalForAll(
operator: Either<Bytes<32>, ContractAddress>,
approved: Boolean
) → []circuit
#Approve or remove operator as an operator for the caller.
Operators can call transferFrom for any token owned by the caller.
In the case of an external (non-contract) caller, the caller's identity is derived from the wit_NonFungibleTokenSK
witness as persistentHash(secretKey).
Requirements:
- The contract is initialized.
- The
operatorcannot be zero.
isApprovedForAll(
owner: Either<Bytes<32>, ContractAddress>,
operator: Either<Bytes<32>, ContractAddress>
) → Booleancircuit
#Returns if the operator is allowed to manage all of the assets of owner.
Requirements:
- The contract is initialized.
transferFrom(
fromAddress: Either<Bytes<32>, ContractAddress>,
to: Either<Bytes<32>, ContractAddress>,
tokenId: Uint<128>
) → []circuit
#Transfers tokenId token from fromAddress to to.
Transfers to contract addresses are currently disallowed until contract-to-contract interactions are supported in Compact. This restriction prevents assets from being inadvertently locked in contracts that cannot currently handle token receipt.
In the case of an external (non-contract) caller, the caller's identity is derived from the wit_NonFungibleTokenSK
witness as persistentHash(secretKey).
Requirements:
- The contract is initialized.
fromAddressis not zero.tois not zero.tois not a ContractAddress.tokenIdtoken must be owned byfromAddress.- If the caller is not
fromAddress, it must be approved to move this token by either approve or setApprovalForAll.
_unsafeTransferFrom(
fromAddress: Either<Bytes<32>, ContractAddress>,
to: Either<Bytes<32>, ContractAddress>,
tokenId: Uint<128>
) → []circuit
#Transfers tokenId token from fromAddress to to. It does NOT check if the recipient is a ContractAddress.
In the case of an external (non-contract) caller, the caller's identity is derived from the wit_NonFungibleTokenSK
witness as persistentHash(secretKey).
Transfers to contract addresses are considered unsafe because contract-to-contract calls are not currently supported. Tokens sent to a contract address may become irretrievable. Once contract-to-contract calls are supported, this circuit may be deprecated.
Requirements:
- The contract is initialized.
fromAddressis not zero.tois not zero.tokenIdtoken must be owned byfromAddress.- If the caller is not
fromAddress, it must be approved to move this token by either approve or setApprovalForAll.
_ownerOf(tokenId: Uint<128>) → Either<Bytes<32>, ContractAddress>
circuit
#Returns the owner of the tokenId. Does NOT revert if token doesn't exist.
Requirements:
- The contract is initialized.
_getApproved(tokenId: Uint<128>) → Either<Bytes<32>, ContractAddress>
circuit
#Returns the approved address for tokenId. Returns the zero value if tokenId is not minted.
Requirements:
- The contract is initialized.
_isAuthorized(
owner: Either<Bytes<32>, ContractAddress>,
spender: Either<Bytes<32>, ContractAddress>,
tokenId: Uint<128>
) → Booleancircuit
#Returns whether spender is allowed to manage owner's tokens, or tokenId in
particular (ignoring whether it is owned by owner).
Requirements:
- The contract is initialized.
This function assumes that owner is the actual owner of tokenId and does not verify this
assumption.
_checkAuthorized(
owner: Either<Bytes<32>, ContractAddress>,
spender: Either<Bytes<32>, ContractAddress>,
tokenId: Uint<128>
) → []circuit
#Checks if spender can operate on tokenId, assuming the provided owner is the actual owner.
Requirements:
- The contract is initialized.
spenderhas approval fromownerfortokenIdORspenderhas approval to manage all ofowner's assets.
This function assumes that owner is the actual owner of tokenId and does not verify this
assumption.
_mint(to: Either<Bytes<32>, ContractAddress>, tokenId: Uint<128>) → []
circuit
#Mints tokenId and transfers it to to.
Requirements:
- The contract is initialized.
tokenIdmust not exist.tois not zero.tois not a ContractAddress.
_unsafeMint(to: Either<Bytes<32>, ContractAddress>, tokenId: Uint<128>) → []
circuit
#Mints tokenId and transfers it to to. It does NOT check if the recipient is a ContractAddress.
Requirements:
- The contract is initialized.
tokenIdmust not exist.tois not zero.
Transfers to contract addresses are considered unsafe because contract-to-contract calls are not currently supported. Tokens sent to a contract address may become irretrievable. Once contract-to-contract calls are supported, this circuit may be deprecated.
_burn(tokenId: Uint<128>) → []
circuit
#Destroys tokenId.
The approval is cleared when the token is burned.
This circuit does not check if the sender is authorized to operate on the token.
Requirements:
- The contract is initialized.
tokenIdmust exist.
_transfer(
fromAddress: Either<Bytes<32>, ContractAddress>,
to: Either<Bytes<32>, ContractAddress>,
tokenId: Uint<128>
) → []circuit
#Transfers tokenId from fromAddress to to.
As opposed to transferFrom, this imposes no restrictions on the caller's identity.
Transfers to contract addresses are currently disallowed until contract-to-contract interactions are supported in Compact. This restriction prevents assets from being inadvertently locked in contracts that cannot currently handle token receipt.
Requirements:
- The contract is initialized.
tois not zero.tois not a ContractAddress.tokenIdtoken must be owned byfromAddress.
_unsafeTransfer(
fromAddress: Either<Bytes<32>, ContractAddress>,
to: Either<Bytes<32>, ContractAddress>,
tokenId: Uint<128>
) → []circuit
#Transfers tokenId from fromAddress to to.
As opposed to _unsafeTransferFrom, this imposes no restrictions on the caller's identity.
It does NOT check if the recipient is a ContractAddress.
Requirements:
- The contract is initialized.
tois not zero.tokenIdtoken must be owned byfromAddress.
Transfers to contract addresses are considered unsafe because contract-to-contract calls are not currently supported. Tokens sent to a contract address may become irretrievable. Once contract-to-contract calls are supported, this circuit may be deprecated.
_approve(
to: Either<Bytes<32>, ContractAddress>,
tokenId: Uint<128>,
auth: Either<Bytes<32>, ContractAddress>
) → []circuit
#Approve to to operate on tokenId.
Requirements:
- The contract is initialized.
tokenIdmust exist.- If
authis non 0, then this function will check thatauthis either the owner of the token, or approved to operate on the token (by the owner).
_unsafeApprove(
to: Either<Bytes<32>, ContractAddress>,
tokenId: Uint<128>,
auth: Either<Bytes<32>, ContractAddress>,
isExistenceRequired: Boolean
) → []circuit
#Approve to to operate on tokenId, requiring the token to exist
only when isExistenceRequired is true.
Passing false skips the check that tokenId was minted. Both
_unsafeTransferFrom and _update read that invariant back, so a planted approval
can mint a token nobody authorized or outlive a later mint. Pass false only where
the owner has already been read, as _update does.
Counterpart to Solidity's _approve(to, tokenId, auth, bool emitEvent), where
the flag also suppresses the Approval event. Compact has no events, so it carries
the existence check alone.
Requirements:
- The contract is initialized.
tokenIdmust exist, unlessisExistenceRequiredis false andauthis zero.- If
authis non 0, then this function will check thatauthis either the owner of the token, or approved to operate on the token (by the owner).
_setApprovalForAll(
owner: Either<Bytes<32>, ContractAddress>,
operator: Either<Bytes<32>, ContractAddress>,
approved: Boolean
) → []circuit
#Approve operator to operate on all of owner tokens.
Requirements:
- The contract is initialized.
owneris not zero.operatoris not zero.
_requireOwned(tokenId: Uint<128>) → Either<Bytes<32>, ContractAddress>
circuit
#Reverts if the tokenId doesn't have a current owner (it hasn't been minted, or it has been burned).
Returns the owner.
Requirements:
- The contract is initialized.
tokenIdmust exist.