Skip to main content

Create Coins and Tokens

Coins and tokens on IOTA are similar. In practice, the terms are used interchangeably, but there are some differences in their implementation. You can learn about these differences in the respective standard documentation, Closed-Loop Token and Coin.

Publishing a coin on IOTA is nearly as straightforward as publishing a new type. The main difference is the requirement of a one-time witness when creating a coin.

module examples::mycoin {
use iota::coin::{Self, TreasuryCap};

/// The type identifier of coin. The coin will have a type
/// tag of kind: `Coin<package_object::mycoin::MYCOIN>`
/// Make sure that the name of the type matches the module's name.
public struct MYCOIN has drop {}

/// Module initializer is called once on module publish. A treasury
/// cap is sent to the publisher, who then controls minting and burning
fun init(witness: MYCOIN, ctx: &mut TxContext) {
let (treasury, metadata) = coin::create_currency(witness, 6, b"MYCOIN", b"", b"", option::none(), ctx);
transfer::public_freeze_object(metadata);
transfer::public_transfer(treasury, tx_context::sender(ctx))
}
}

The Coin<T> is a generic implementation of a coin on IOTA. Access to the TreasuryCap provides control over the minting and burning of coins. Further transactions can be sent directly to the iota::coin::Coin with TreasuryCap object as authorization.

Extending the example further, add a mint function to the module. Use the mint function of the Coin module to create (mint) a coin and then transfer it to an address.

public fun mint(
treasury_cap: &mut TreasuryCap<MYCOIN>,
amount: u64,
recipient: address,
ctx: &mut TxContext,
) {
let coin = coin::mint(treasury_cap, amount, ctx);
transfer::public_transfer(coin, recipient)
}

IOTA CLI

If you published the previous example to a IOTA network, you can use the iota client call command to mint coins and deliver them to the address you provide. See IOTA CLI for more information on the command line interface.

iota client call --function mint --module mycoin --package <PACKAGE-ID> --args <TREASURY-CAP-ID> <COIN-AMOUNT> <RECIPIENT-ADDRESS> --gas-budget <GAS-AMOUNT>

If the call is successful your console displays the result, which includes a Balance Changes section with the following information included:

...

Owner: Account Address ( <RECIPIENT-ADDRESS> )
CoinType: <PACKAGE-ID>::mycoin::MYCOIN
Amount: <COIN-AMOUNT>

...

DenyList

See DenyList.

Create regulated coin

If you need the ability to deny specific addresses from having access to your coin, you can use the create_regulated_currency function (instead of create_currency) to create it.

Behind the scenes, create_regulated_currency uses the create_currency function to create the coin, but also produces a DenyCap object that allows its bearer to control access to the coin's deny list in a DenyList object. Consequently, the way to create a coin using create_regulated_currency is similar to the previous example, with the addition of a transfer of the DenyCap object to the module publisher.

Create tokens

Tokens reuse the TreasuryCap defined in the iota::coin module and therefore have the same initialization process. The coin::create_currency function guarantees the uniqueness of the TreasuryCap and forces the creation of a CoinMetadata object.

Coin-like functions perform the minting and burning of tokens. Both require the TreasuryCap:

  • token::mint - mint a token
  • token::burn - burn a token

See Closed-Loop Token standard for complete details of working with tokens.

Examples

See the following topics for examples of some common use cases for coin and token creation.