Resource Behaviors

New resources created with the ResourceBuilder can also be attributed with special characteristics. For example, you can specify behaviors to mark a resource as mintable, burnable, or even restrict its ability to be withdrawn, making them “Soulbound” tokens. AccessRules can also be specified with resource behaviors, which allows you to determine the conditions need to be present before the behavior action can be performed. We can also determine the mutability of these authorization rules to have the ability to change the authorization rules in the future or lock its mutability to prevent its rules from being changed.

List of Resource Behaviors

Method

Description

.mint_roles(mint_roles!)

Specify the AccessRule for MintRoles to provide permission to mint tokens.

.burn_roles(burn_roles!)

Specify the AccessRule for BurnRoles to provide permission to burn tokens.

.withdraw_roles(withdraw_roles!)

Specify the AccessRule for WithdrawRoles to provide permission to withdraw tokens from a Vault.

.deposit_roles(deposit_roles!)

Specify the AccessRule for DepositRoles to provide permission to deposit tokens to a Vault.

.recall_roles(recall_roles!)

Specify the AccessRule for RecallRoles to provide permission to freeze tokens.

.freezer_roles(freezer_roles!)

Specify the AccessRule for FreezeRoles to provide permission to freeze tokens.

Mintable

To make a resource mintable means that we allow the creation of additional supply of that resource. We can do this by simply adding .mint_roles() when we create our resource and map the AccessRule to each BurnRoles.

let my_token = ResourceBuilder::new_fungible()
    .metadata(metadata!(
        init {
            "name" => "My Token", locked;
            "symbol" => "TKN", locked;
        }
    ))
  .mint_roles(mint_roles!( (1)
      minter => rule!(allow_all);
      minter_updater => rule!(deny_all);
  .create_with_no_initial_supply();
1 To make a resource mintable, you simply have to make a call to the mint_roles(mint_roles!) method during the resource creation which requires that we map the AccessRule for two roles:
  • minter role provides minting authority.

  • minter_updater role provides updating authority to the minter role. Mapping its AccessRule to DenyAll will result in locking this role permanently.

Burnable

Having a resource burnable indicates that an specified supply of this resource can essentially be destroyed. If all the supply of that resource is burnt, the ResourceManager will still exist. Additionally, if that resource is mintable then more of that resource can be created. Similar to our previous example, to make our resource burnable, we call the .burn_roles() method when we create our resource and map the AccessRule to each BurnRoles.

let my_token = ResourceBuilder::new_fungible()
    .metadata(metadata!(
        init {
            "name" => "My Token", locked;
            "symbol" => "TKN", locked;
        }
    ))
  .burn_roles(burn_roles!(
      burner => rule!(allow_all);
      burner_updater => rule!(deny_all); (1)
  .create_with_no_initial_supply();

Restrict Withdraw

Resources restricted from being withdrawn are effectively locked in the Vault that contains it. This makes the resource soulbound and its most common use-case is to attach some form of identification or reputation to the account that owns that resource.

let my_token = ResourceBuilder::new_fungible()
    .metadata(metadata!(
        init {
            "name" => "My Token", locked;
            "symbol" => "TKN", locked;
        }
    ))
  .withdraw_roles(withdraw_roles!(
      withdrawer => rule!(allow_all);
      withdrawer_updater => rule!(deny_all);
  .create_with_no_initial_supply();

Restrict Deposit

Resources restricted from being deposited are commonly called transient resources. This forces a dangling resource to exist. If the resource can’t be deposited into a Vault, the resource must be burnt, else we will encounter a dangling resource error. Transient resources are most commonly used as a means to force a specified condition to happen within a transaction. If that condition is met, we can permit the resource to be burned. Alternatively, if we specify an authorization requirement, we can allow this resource to be deposited if a specified condition is met.

let my_token = ResourceBuilder::new_fungible()
    .metadata(metadata!(
        init {
            "name" => "My Token", locked;
            "symbol" => "TKN", locked;
        }
    ))
  .deposit_roles(deposit_roles!(
      depositor => rule!(allow_all);
      depositor_updater => rule!(deny_all);
  .create_with_no_initial_supply();

Recallable Token

Having a resource to be recallable allows us to send our tokens to anybody, but have the ability for us to retrieve it if we desire. The most common use case for this is to allow for “Rental NFTs”. We can create conditions in how long this resource can essentially be borrowed for.

let my_token = ResourceBuilder::new_fungible()
    .metadata(metadata!(
        init {
            "name" => "My Token", locked;
            "symbol" => "TKN", locked;
        }
    ))
  .recall_roles(recall_roles!(
      recaller => rule!(allow_all);
      recaller_updater => rule!(deny_all);
  .create_with_no_initial_supply();