Entrypoints
When you import the base classes as described in Base classes, the FA2 library automatically adds the standard entrypoints that the FA2 standard requires. You can override these entrypoints or add other custom entrypoints.
Off-chain views
In addition to entrypoints, the FA2 library creates off-chain views as described by the FA2 standard. For these views to work, you must upload their code in contract metadata as described in Creating and publishing metadata.
Standard entrypoints
The FA2 library provides the three standard entrypoints transfer
, balance_of
, and update_operators
. These entrypoints work the same way for each type of token. You can modify them with transfer policies or replace them with custom entrypoints as long as the custom entrypoint meets the FA2 standard.
transfer
The transfer
entrypoint moves tokens from one account to another. It requires a list of batches as an argument. Each batch is a record that contains the following fields:
from_
: The account that sends the tokenstxs
: A list of records, each with these fields:to_
: The account that receives the tokenstoken_id
: The token IDamount
: The amount of tokens to transfer
By default, the owner of a token and their designated operators can transfer a token. You can change permissions for transferring tokens by setting a transfer policy.
The following example makes three token transfers in a single call to the transfer
entrypoint:
contract.transfer(
[
sp.record(
from_ = alice.address,
txs = [
sp.record(to_=bob.address, amount=10, token_id=0),
sp.record(to_=bob.address, amount=10, token_id=1)
]
),
sp.record(
from_ = bob.address,
txs = [
sp.record(to_=alice.address, amount=11, token_id=0)
]
)
],
_sender=charlie)
The type of the transfer
entrypoint's parameter is available in the library as the t.transfer_batch
type, which is equivalent to:
sp.list[sp.record(from_=sp.address, txs=sp.list[sp.record(to_=sp.address, token_id=sp.nat, amount=sp.nat).layout(("to_", ("token_id", "amount")))]).layout(("from_", "txs"))]
The transfer
entrypoint can raise these exceptions: FA2_TOKEN_UNDEFINED
, FA2_NOT_OPERATOR
, FA2_INSUFFICIENT_BALANCE
, and FA2_TX_DENIED
.
update_operators
The update_operators
entrypoint modifies the list of operators, which are accounts that are authorized to transfer tokens that another account owns. Only the owner of a token can set the operators for their tokens.
This entrypoint takes a list of actions, each of which is either "remove_operator"
or "add_operator"
associated with an operator permission. Each operator permission is a record of:
owner
: The account on which the operator can perform the transferoperator
: The account given permission to transfertoken_id
: The token ID for which permission is granted
This example removes the account op1
as the operator for Alice's tokens with the ID 0 and adds the account op2
as an operator for the same tokens:
contract.update_operators([
sp.variant("remove_operator", sp.record(
owner = alice.address,
operator = op1.address,
token_id = 0)),
sp.variant("add_operator", sp.record(
owner = alice.address,
operator = op2.address,
token_id = 0))
],
_sender=alice
)
The type of the update_operators
entrypoint's parameter is available in the library as the t.update_operators_params
type, which is equivalent to:
sp.list[
sp.variant(
add_operator=sp.record(
owner=sp.address,
operator=sp.address,
token_id=sp.nat
).layout(("owner", ("operator", "token_id"))),
remove_operator=sp.record(
owner=sp.address,
operator=sp.address,
token_id=sp.nat
).layout(("owner", ("operator", "token_id")))
)
]
The update_operators
can raise these exceptions: FA2_NOT_OWNER
and FA2_OPERATORS_UNSUPPORTED
.
balance_of
The balance_of
entrypoint is used to query the balance of multiple account/token pairs. It sends the balances to a callback address.
It takes two parameters:
callback
: Information about the contract to send the balance information to, in this format:pythonsp.contract[ sp.list[ sp.record( request=sp.record( owner=sp.address, token_id=sp.nat ).layout(("owner", "token_id")), balance=sp.nat ).layout(("request", "balance")) ] ]
requests
: Information about the owners and token IDs to provide information about, in this format:pythonsp.list[ sp.record( owner=sp.address, token_id=sp.nat ).layout(("owner", "token_id")) ]
The layout of this entrypoint is
("requests", "callback")
.
Together, these parameters are available in the library as the t.balance_of_params
type.
This example sends a user's balance of the token ID 0 to the receive_balances
entrypoint of another contract:
contract.balance_of(
callback=sp.contract(
sp.list(fa2.t.balance_of_response),
contract2.address,
entry_point="receive_balances",
).open_some(),
requests=[sp.record(owner=alice.address, token_id=0)],
_sender=alice)
The balance_of
transfers 0 mutez to callback
with corresponding response. This response is in the type t.balance_of_response
, which is equivalent to:
sp.record(
request=sp.record(owner=sp.address, token_id=sp.nat),
balance: sp.nat
).layout(("request", "balance"))
The balance_of
entrypoint can raise these exceptions: FA2_NOT_OWNER
and FA2_OPERATORS_UNSUPPORTED
.
Custom entrypoints
You can either override the provided entrypoints or add your own, just as you would in any other SmartPy contract.
For example, this contract has an entrypoint named my_entrypoint
in addition to the entrypoints provided by the main.Fungible
base class:
class ExampleFA2(main.Fungible):
@sp.entrypoint
def my_entrypoint(self, params):
# ...
You can override the standard entrypoints in this way, but to maintain compliance with the FA2 standard, they should have the same interface as the standard entrypoints.
Non-standard entrypoints
The FA2 library provides entrypoints and views that are not required by the standard. You can add them to your contracts with the mixins mechanism.
For example, the FA2 standard does not require contracts to have mint and burn entrypoints to create and destroy tokens, but the FA2 library provides them.