Managed Coin Example

Now we have peeked under the hood of the sui::coin module, we can look at a simple but complete example of creating a type of custom fungible token where there is a trusted manager that has the capability to mint and burn, similar to many ERC-20 implementations.

Smart Contract

You can find the complete Managed Coin example contract under the example project folder.

Given what we have covered so far, this contract should be fairly easy to understand. It follows the One Time Witness pattern exactly, where the witness resource is named MANAGED, and automatically created by the module init function.

The init function then calls coin::create_currency to get the TreasuryCap and CoinMetadata resources. The parameters passed into this function are the fields of the CoinMetadata object, so include the token name, symbol, icon URL, etc.

The CoinMetadata is immediately frozen after creation via the transfer::freeze_object method, so that it becomes a shared immutable object that can be read by any address.

The TreasuryCap Capability object is used as a way to control access to the mint and burn methods that create or destroy Coin<MANAGED> objects respectively.

Publishing and CLI Testing

Publish the Module

Under the fungible_tokens project folder, run:

    sui client publish --gas-budget 10000000

You should see console output similar to:

Publish Output

The two immutable objects created are respectively the package itself and the CoinMetadata object of Managed Coin. And the owned object passed to the transaction sender is the TreasuryCap object of Managed Coin.

Treasury Object

Export the object IDs of the package object and the TreasuryCap object to environmental variables:

export PACKAGE_ID=<package object ID from previous output>
export TREASURYCAP_ID=<treasury cap object ID from previous output>

Minting Tokens

To mint some MNG tokens, we can use the following CLI command:

    sui client call --function mint --module managed --package $PACKAGE_ID --args $TREASURYCAP_ID <amount to mint> <recipient address> --gas-budget 10000000

💡Note: as of Sui binary version 0.21.0, u64 inputs must be escaped as strings, thus the above CLI command format. This might change in a future version.

Minting

Export the object ID of the newly minted COIN<MANAGED> object to a bash variable:

export COIN_ID=<coin object ID from previous output>

Verify that the Supply field under the TreasuryCap<MANAGED> object should be increased by the amount minted.

Burning Tokens

To burn an existing COIN<MANAGED> object, we use the following CLI command:

    sui client call --function burn --module managed --package $PACKAGE_ID --args $TREASURYCAP_ID $COIN_ID --gas-budget 10000000

Burning

Verify that the Supply field under the TreasuryCap<MANAGED> object should be back to 0.

Exercise: What other commonly used functions do fungible tokens need? You should know enough about programming in Move now to try to implement some of these functions.