Skip to content
On this page

Entrypoints

Standard entrypoints

FA2 library provides the three standard entrypoints transfer, balance_of, and update_operators. These entrypoints can be modified using policies or replaced with custom entrypoints.

transfer

The 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

Example:

smartpy
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)
            ]
        )
    ],
    _sender=charlie)

Types:

  • batch: 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: FA2_TOKEN_UNDEFINED, FA2_NOT_OPERATOR, FA2_INSUFFICIENT_BALANCE or FA2_TX_DENIED.

update_operators

update_operators(<batch>)

Operators are accounts authorized to transfer tokens on the owner's behalf.

The update_operators entrypoint modifies the list of operators. It 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 transfer.
  • operator: The account given permission to transfer.
  • token_id: The token id for which permission is granted.

Example:

smartpy
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))
  ],
  _sender=alice)

Types:

  • batch: 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: FA2_NOT_OWNER or FA2_OPERATORS_UNSUPPORTED.

balance_of

balance_of(<callback>, <requests>)

The balance_of entrypoint is used to query the balance of multiple account/token pairs. It sends the balances to a callback address.

Types:

  • callback: 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")))]]

  • requests: sp.list[sp.record(owner=sp.address, token_id=sp.nat).layout(("owner", "token_id"))]

    The layout of this entrypoint is ("requests", "callback").

Example:

smartpy
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)],
    _sender=alice)

The balance_of transfers 0 mutez to callback with corresponding response.

The balance_of can raise: FA2_NOT_OWNER or 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.

Example:

smartpy
class ExampleFA2(main.Fungible):
    @sp.entrypoint
    def my_entrypoint(self, params):
        # ...

Non-standard entrypoints

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.