Asset operations and 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.
Initializing the dapp
Let’s implement the initialization operation that creates our pool account:
operation initialize_dapp() {
admin.require_admin();
create_pool_account();
}
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());
Key points:
- Creates a pool account with admin privileges
- Generates a unique account ID
Minting assets
Minting creates new assets and adds them to the pool account:
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:
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 reside in the pool account
- Burning reduces the total supply of assets
Faucet implementation
Creating a faucet for testing purposes:
@extend(auth.auth_handler)
function () = auth.add_auth_handler(
flags = ["T"]
);
We require users to have the "T" flag, ensuring that only transfer-capable accounts can access the faucet. This guarantees they can effectively use the assets they receive.
operation faucet() {
val receiver = auth.authenticate();
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:
operation transfer(receiver: byte_array, amount: big_integer) {
val sender = auth.authenticate();
Unsafe.transfer(sender, accounts.Account(receiver), 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:
operation lock_asset(type: text, account_id: byte_array, amount: big_integer) {
admin.require_admin();
locking.lock_asset(type, accounts.Account(account_id), 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), Asset(get_asset_id()), amount);
}
Key points:
- Only admins can lock or unlock assets
- Assets remain in the account but cannot be transferred
- Different lock types can be specified
Queries
Implementing queries to check balances and account statuses:
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
);
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();