Skip to main content

Asset functions, operations & queries

In this lesson, we will implement the core operations for the pool account and manage FT4 assets, including minting, burning, transferring, and locking assets.


Functions

Let’s define a few functions we’ll use to identify the asset and the pool account. These will be used throughout the module.

Add the following to src/main/functions.rell:

src/main/functions.rell
import lib.ft4.accounts;
import lib.ft4.auth;

function create_pool_account() =
accounts.create_account_without_auth(get_pool_account_id(), account_type);

function get_pool_account_id() =
(account_type + chain_context.blockchain_rid).hash();

function get_pool_account() =
accounts.account_by_id(get_pool_account_id());

function get_asset_id() =
(asset_name, chain_context.blockchain_rid).hash();

@extend(auth.auth_handler)
function () = auth.add_auth_handler(flags = ["T"]);

We require the "T" flag so only users who can transfer assets can use operations like the faucet — ensuring they can use the assets they receive.


Operations

Now we can define the operation to initialize the dapp by creating the pool account.

Add the following to src/main/operations.rell:

src/main/operations.rell
import lib.ft4.core.admin;

operation initialize_dapp() {
admin.require_admin();
create_pool_account();
}

Key points:

  • Creates a pool account with admin privileges
  • Generates a unique account ID, derived from blockchain RID and account type

Minting assets

Minting creates new assets and adds them to the pool account.

Add the following import the top of the file:

src/main/operations.rell
import lib.ft4.assets.{ Unsafe }; // For minting and burning

Now define the minting operation:

src/main/operations.rell
operation mint() {
admin.require_admin();
Unsafe.mint(get_pool_account(), dapp_meta.asset, asset_amount_to_mint);
}

Key points:

  • Only admins can mint new assets
  • Assets are minted to the pool account
  • The amount is specified in the smallest unit (considering decimals)

Burning assets

Burning permanently removes assets from circulation.

Add the following import the top of the file:

src/main/operations.rell
import lib.ft4.core.assets.{ Asset };

Now define the burning operation:

src/main/operations.rell
operation burn() {
admin.require_admin();
val pool_account = get_pool_account();
Unsafe.burn(pool_account, Asset(get_asset_id()), asset_amount_to_burn);
}

Key points:

  • Only admins can burn assets
  • Assets must be present in the pool account
  • Burning reduces the total supply of the asset

Faucet implementation

Creating a faucet for testing purposes:

src/main/operations.rell
operation faucet() {
val receiver = auth.authenticate(); // extended to require the "T" flag, ensuring assets can be used
val pool_account = get_pool_account();
Unsafe.transfer(pool_account, receiver, Asset(get_asset_id()), asset_amount_to_faucet);
}

Key points:

  • Users must authenticate
  • There is a fixed amount per request
  • Transfers are conducted from the pool account

Transferring assets

Implementing asset transfers between accounts:

src/main/operations.rell
operation transfer(receiver: byte_array, amount: big_integer) {
val sender = auth.authenticate();
Unsafe.transfer(sender, accounts.Account(receiver.hash()), Asset(get_asset_id()), amount);
}

Key points:

  • The sender must be authenticated
  • The amount must be positive

Asset locking

Implementing asset locking for temporary restrictions.

Add the following import the top of the file:

src/main/operations.rell
import lib.ft4.core.assets.locking;

Now define the locking operations:

src/main/operations.rell
operation lock_asset(type: text, account_id: byte_array, amount: big_integer) {
admin.require_admin();
locking.lock_asset(type, accounts.Account(account_id.hash()), Asset(get_asset_id()), amount);
}

operation unlock_asset(type: text, account_id: byte_array, amount: big_integer) {
admin.require_admin();
locking.unlock_asset(type, accounts.Account(account_id.hash()), Asset(get_asset_id()), amount);
}

Key points:

  • Only admins can lock or unlock assets
  • Assets remain in the account but cannot be transferred
  • The lock type can be used to categorize different kinds of restrictions (e.g. vesting, escrow)

Queries

Implementing queries to check balances and account statuses:

src/queries.rell
import lib.ft4.core.assets.{ get_asset_balance };

query get_pool_account_balance() = get_asset_balance(get_pool_account(), Asset(get_asset_id()));

query get_user_account_balance(
pubkey
) = get_asset_balance(accounts.account_by_id(pubkey.hash()), Asset(get_asset_id()));

query get_user_lock_account_balance(
pubkey
) = locking.get_locked_asset_balance(
accounts.account_by_id(pubkey.hash()),
Asset(get_asset_id()),
["FT4_LOCK"],
5,
null
);