transfer entrypoint is used to move 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 sender of the transfer
txs: a list of records, each with the fields:
to_: receiver of the transaction
token_id: the token id
amount: amount to be transferred
c1.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) ] ) ]).run(sender = charlie)
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"))]
transfer entrypoint can raise:
Operators are accounts authorized to transfer tokens on the owner's behalf.
update_operators entrypoint modifies the list of operators. It takes a list of actions, each of which is either
"add_operator" associated with an operator permission.
Each operator permission is a record of:
owner: The account on which the operator can perform the transfer.
operator: The account given permission to transfer.
token_id: The token id for which permission is granted.
c1.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)) ]).run(sender = alice)
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"))))]
update_operators can raise:
balance_of entrypoint is used to query the balance of multiple account/token pairs. It sends the balances to a callback address.
sp.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")))]]
sp.list[sp.record(owner=sp.address, token_id=sp.nat).layout(("owner", "token_id"))]
The layout of this entrypoint is
c1.balance_of( callback=sp.contract( sp.list(fa2.t.balance_of_response), c2.address, entry_point="receive_balances", ).open_some(), requests=[sp.record(owner=alice.address, token_id=0)], ).run(sender=alice)
balance_of transfers 0 mutez to
callback with corresponding response.
balance_of can raise:
You can either override the provided entrypoints or add your own, just as you would in any other SmartPy contract.
class ExampleFA2(main.Fungible): @sp.entrypoint def my_entrypoint(self, params): # ...
The FA2 library provides non-standard entrypoints and views, which can be added using the mixins mechanism.
Mint and burn
FA2 does not specify an interface for mint and burn operations due to the varying ways these can be handled.
You can use the mixins to implement these functionalities.
If you want to create your own, they should follow the same logic as the
transfer entrypoint (core transfer behaviour and transfer permission logic).
Mint and burn can be considered special cases of the transfer. Although, it is possible that they have more or less restrictive rules than the regular transfer. For instance, mint and burn operations may be invoked by a special privileged administrative address only. In this case, regular operator restrictions may not be applicable.