4. Create your own Move coin
This tutorial covers how to make my own coin and mint them using 0x1::managed_coin module, and how to interact with the Move module.
Step 1: Initialize Coin
Call 0x1::managed_coin::initialize function and start creating a new coin on Initia.
public entry fun initialize(
    account: &signer,
    maximum_supply: Option<u128>,
    name: String,
    symbol: String,
    decimals: u8,
    icon_uri: String,
    project_uri: String,
)TIP: On the entry function, signer is included in msg sender and is omitted on msg args.
> initiad tx move execute 0x1 managed_coin initialize \
  --args "option<u128>:null string:my_coin string:MYCOIN u8:6 string: string:" \
  --from [key-name] \
  --gas auto --gas-adjustment 1.5 --gas-prices 0.15uinit \
  --node [rpc-url]:[rpc-port] --chain-id [chain-id]import {
  bcs,
  LCDClient,
  MnemonicKey,
  MsgExecute,
  Wallet,
} from '@initia/initia.js';
async function createCoin() {
  const lcd = new LCDClient('[rest-url]', {
    gasPrices: '0.15uinit',
    gasAdjustment: '1.5',
  });
  const key = new MnemonicKey({
    mnemonic: 'beauty sniff protect ...',
  });
  const wallet = new Wallet(lcd, key);
  const msgs = [
    new MsgExecute(
      key.accAddress,
      '0x1',
      'managed_coin',
      'initialize',
      [],
      [
        // max supply, if you want to set max supply, insert number instaed of null
        bcs.option(bcs.u128()).serialize(null).toBase64(),
        bcs.string().serialize('my_coin').toBase64(), // name
        bcs.string().serialize('MYCOIN').toBase64(), // symbol
        // decimal point (raw value 1 consider to 10 ** (- decimalPoint))
        bcs.u8().serialize(6).toBase64(),
        bcs.string().serialize('').toBase64(), // icon uri
        bcs.string().serialize('').toBase64(), // project uri
      ]
    ),
  ];
  // sign tx
  const signedTx = await wallet.createAndSignTx({ msgs });
  // send(broadcast) tx
  lcd.tx.broadcastSync(signedTx).then(res => console.log(res));
  // {
  //   height: 0,
  //   txhash: '40E0D5633D37E207B2463D275F5B479FC67D545B666C37DC7B121ED551FA18FC',
  //   raw_log: '[]'
  // }
}
createCoin();Step 2: Mint Coin
Call 0x1::managed_coin::mint function and mint the tokens create on Step 1.
public entry fun mint(
    account: &signer,
    dst_addr: address,
    metadata: Object<Metadata>,
    amount: u64,
)What is metadata?
Metadata is the coins unique identity. To be more specific, it is an object or an address where 0x1::fungible_asset::Metadata is saved. Fungible asset is using named object to generate deterministic address which is the form of sha3_256(creator+symbol+0xFE).
How do I get metadata?
A view function 0x1::coin::metadata can be used to get metadata of a coin. You can also get the metadata by using sha3_256(creator+symbol+0xFE).
> initiad query move view 0x1 coin metadata \
    --args "address:[addr] string:MYCOIN" \
    --node [rpc-url]:[rpc-port]
data: '"0x2d81ce0b6708fccc77a537d3d1abac8c9f1f674f4f76390e3e78a89a52d4aacb"'import { bcs, LCDClient, MnemonicKey } from '@initia/initia.js';
import * as crypto from 'crypto';
async function getCoinMetadata() {
  const lcd = new LCDClient('https://lcd.mahalo-1.initia.xyz', {
    gasPrices: '0.15uinit',
    gasAdjustment: '1.5',
  });
  const key = new MnemonicKey({
    mnemonic: 'beauty sniff protect ...',
  });
  // Method 1: use view function
  lcd.move
    .viewFunction(
      '0x1',
      'coin',
      'metadata',
      [],
      [
        bcs.address().serialize(key.accAddress).toBase64(),
        bcs.string().serialize('MYCOIN').toBase64(),
      ]
    )
    .then(console.log);
  // 0xcf921815f2b4827930ac01b3116ed3caad08ccd443f9df6eb22cd5344a548660
  // Method 2: use sha3-256
  console.log(coinMetadata(key.accAddress, 'MYCOIN'));
  // cf921815f2b4827930ac01b3116ed3caad08ccd443f9df6eb22cd5344a548660
}
getCoinMetadata();
function coinMetadata(creator: string, symbol: string): string {
  const OBJECT_FROM_SEED_ADDRESS_SCHEME = 0xfe;
  const addrBytes = bcs.address().serialize(creator).toBytes();
  const seed = Buffer.from(symbol, 'ascii');
  const bytes = [...addrBytes, ...seed, OBJECT_FROM_SEED_ADDRESS_SCHEME];
  const hash = crypto.createHash('SHA3-256');
  const digest = hash.update(Buffer.from(bytes)).digest();
  return digest.toString('hex');
}Now that we know the metadata address, let's mint coins.
> initiad tx move execute 0x1 managed_coin mint \
  --args "address:[addr] object:0x2d81ce0b6708fccc77a537d3d1abac8c9f1f674f4f76390e3e78a89a52d4aacb u64:100000000" \
  --from [key-name] \
  --gas auto --gas-adjustment 1.5 --gas-prices 0.15uinit \
  --node [rpc-url]:[rpc-port] --chain-id [chain-id]import {
  bcs,
  LCDClient,
  MnemonicKey,
  MsgExecute,
  Wallet,
} from '@initia/initia.js';
import * as crypto from 'crypto';
async function mintCoin() {
  const lcd = new LCDClient('[rest-url]', {
    gasPrices: '0.15uinit',
    gasAdjustment: '1.5',
  });
  const key = new MnemonicKey({
    mnemonic: 'beauty sniff protect ...',
  });
  const wallet = new Wallet(lcd, key);
  const msgs = [
    new MsgExecute(
      key.accAddress,
      '0x1',
      'managed_coin',
      'mint',
      [],
      [
        bcs.address().serialize(key.accAddress).toBase64(),
        bcs
          .object()
          .serialize(coinMetadata(key.accAddress, 'MYCOIN'))
          .toBase64(),
        bcs.u64().serialize(100000000).toBase64(),
      ]
    ),
  ];
  // sign tx
  const signedTx = await wallet.createAndSignTx({ msgs });
  // send(broadcast) tx
  lcd.tx.broadcastSync(signedTx).then(res => console.log(res));
  // {
  //   height: 0,
  //   txhash: '593827F58F3E811686EC6FFDAD2E27E91DA707965F0FF33093DC071D47A46786',
  //   raw_log: '[]'
  // }
}
mintCoin();
function coinMetadata(creator: string, symbol: string): string {
  const OBJECT_FROM_SEED_ADDRESS_SCHEME = 0xfe;
  const addrBytes = bcs.address().serialize(creator).toBytes();
  const seed = Buffer.from(symbol, 'ascii');
  const bytes = [...addrBytes, ...seed, OBJECT_FROM_SEED_ADDRESS_SCHEME];
  const hash = crypto.createHash('SHA3-256');
  const digest = hash.update(Buffer.from(bytes)).digest();
  return digest.toString('hex');
}
Check the minted coins by querying the balances.
initiad query bank balances [addr] \
    --node [rpc-url]:[rpc-port]
balances:
- amount: "100000000"
  denom: move/2d81ce0b6708fccc77a537d3d1abac8c9f1f674f4f76390e3e78a89a52d4aacb
- amount: "99482105"
  denom: uinit
pagination:
  next_key: null
  total: "0"import { LCDClient, MnemonicKey } from '@initia/initia.js';
async function checkBalances() {
  const lcd = new LCDClient('[rest-url]', {
    gasPrices: '0.15uinit',
    gasAdjustment: '1.5',
  });
  const key = new MnemonicKey({
    mnemonic:
      'beauty sniff protect ...',
  });
  const balances = await lcd.bank.balance(key.accAddress);
  console.log('balances:', balances[0]);
  // Coins {
  //   _coins: {
  //     uinit: Coin { denom: 'uinit', amount: '99531690', isDecimal: false },
  //     'move/cf921815f2b4827930ac01b3116ed3caad08ccd443f9df6eb22cd5344a548660': Coin {
  //       denom: 'move/cf921815f2b4827930ac01b3116ed3caad08ccd443f9df6eb22cd5344a548660',
  //       amount: '100000000',
  //       isDecimal: false
  //     }
  //   }
  // }
}
checkBalances();TIP: If creator is 0x1, cosmos denom is equal to the symbol. If not, cosmos denom is equal to move/{metadata_address}
Last updated