04 / 06Advanced
Asset functions, operations and queries
This lesson covers the core operations for the pool account and for handling FT4 assets: minting, burning, transferring, and locking.
Functions
Start with a few helper functions that identify the asset and the pool account. The rest of the module relies on them.
Put this code in 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"]);The "T" flag is required so that operations such as the faucet are available only to users who can transfer assets. This guarantees they can actually use whatever assets they receive.
Operations
Next, write the operation that initializes the dapp by creating the pool account.
Put this code in src/main/operations.rell:
import lib.ft4.core.admin;operation initialize_dapp() { admin.require_admin(); create_pool_account();}What this does:
- Sets up a pool account with admin privileges
- Produces a unique account ID based on the blockchain RID and the account type
Minting assets
Minting issues new assets and credits them to the pool account.
Place this import at the top of the file:
import lib.ft4.assets.{ Unsafe }; // For minting and burningThen add the minting operation:
operation mint() { admin.require_admin(); Unsafe.mint(get_pool_account(), dapp_meta.asset, asset_amount_to_mint);}What this does:
- Restricts minting to admins
- Credits the minted assets to the pool account
- Expects the amount in the smallest unit, taking decimals into account
Burning assets
Burning takes assets out of circulation for good.
Place this import at the top of the file:
import lib.ft4.core.assets.{ Asset };Then add the burning operation:
operation burn() { admin.require_admin(); val pool_account = get_pool_account(); Unsafe.burn(pool_account, Asset(get_asset_id()), asset_amount_to_burn);}What this does:
- Restricts burning to admins
- Requires the assets to exist in the pool account
- Lowers the asset's total supply
Faucet implementation
For testing, add a faucet:
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);}What this does:
- Requires the user to be authenticated
- Hands out the same fixed amount on every request
- Sends the funds from the pool account
Transferring assets
To move assets from one account to another, add this operation:
operation transfer(receiver: byte_array, amount: big_integer) { val sender = auth.authenticate(); Unsafe.transfer(sender, accounts.Account(receiver.hash()), Asset(get_asset_id()), amount);}What this does:
- Requires the sender to be authenticated
- Rejects amounts that are not positive
Asset locking
Locking places a temporary restriction on assets.
Place this import at the top of the file:
import lib.ft4.core.assets.locking;Then add the lock and unlock operations:
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);}What this does:
- Restricts locking and unlocking to admins
- Keeps locked assets in the account while blocking their transfer
- Lets you use the lock type to label different restriction categories, such as vesting or escrow
Queries
Finally, add queries for reading balances and account status:
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 );