1

I wrote a mov package in which anyone can mint token (very new to move)

module fungible_tokens::rcoin {
    use sui::coin::{Self, Coin, TreasuryCap};
    use sui::transfer;
    use sui::tx_context::{Self, TxContext};


    struct RCOIN has drop {}

    
    /// Register the RCOIN currency to acquire its `TreasuryCap`. Because
    /// this is a module initializer, it ensures the currency only gets
    /// registered once.
    fun init(witness: RCOIN, ctx: &mut TxContext) {
        // Get a treasury cap for the coin 
        let treasury_cap = coin::create_currency<RCOIN>(witness, 2, ctx);
        // Make it a share object so that anyone can mint
        transfer::share_object(treasury_cap)
    }


    public entry fun mint(
        treasury_cap: &mut TreasuryCap<RCOIN>, amount: u64, recipient: address, ctx: &mut TxContext
    ) {
        coin::mint_and_transfer(treasury_cap, amount, recipient, ctx)
    }
}

Now, I want to send the coins I have minted to a different address. Sui transfer only transfers an object/sui gas.

Can someone help me with this?

Max
  • 2,082
  • 19
  • 25
Alwaysblue
  • 9,948
  • 38
  • 121
  • 210

1 Answers1

2

This is how I was able to resolve it.



// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

/// Example coin with a trusted manager responsible for minting/burning (e.g., a stablecoin)
/// By convention, modules defining custom coin types use upper case names, in contrast to
/// ordinary modules, which use camel case.
module fungible_tokens::r6coin {
    use sui::coin::{Self, Coin, TreasuryCap};
    use sui::transfer;
    use sui::pay;
    use sui::tx_context::{Self, TxContext};
    use std::vector;
    /// Name of the coin. By convention, this type has the same name as its parent module
    /// and has no fields. The full type of the coin defined by this module will be `COIN<R1COIN>`.
    struct R6COIN has drop {}

    /// For when empty vector is supplied into join function.
    const ENoCoins: u64 = 0;
    /// Register the RCOIN currency to acquire its `TreasuryCap`. Because
    /// this is a module initializer, it ensures the currency only gets
    /// registered once.
    fun init(witness: R6COIN, ctx: &mut TxContext) {
        // Get a treasury cap for the coin 
        let coin = coin::create_currency<R6COIN>(witness, 2, ctx);
        // Make it a share object so that anyone can mint
        transfer::share_object(coin)
    } 

    //     public entry fun mint(
    //     treasury_cap: &mut TreasuryCap<R1COIN>, amount: u64, recipient: address, ctx: &mut TxContext
    // ) {
    //     coin::mint_and_transfer(treasury_cap, amount, recipient, ctx)
    // }

    public entry fun join_split_transfer<T>(coins: vector<coin::Coin<T>>, amount: u64, recipient: address, ctx: &mut TxContext) {
          assert!(vector::length(&coins) > 0, ENoCoins);
            let coin = vector::pop_back(&mut coins);
            pay::join_vec(&mut coin, coins);
            pay::split_and_transfer<T>(&mut coin, amount, recipient, ctx);
            transfer::transfer(coin, tx_context::sender(ctx))
    }

    public entry fun mint(
        treasury_cap: &mut TreasuryCap<R6COIN>, amount: u64, recipient: address, ctx: &mut TxContext
    ) {
        coin::mint_and_transfer(treasury_cap, amount, recipient, ctx)
    }
}

In this code, look at this part

    public entry fun join_split_transfer<T>(coins: vector<coin::Coin<T>>, amount: u64, recipient: address, ctx: &mut TxContext) {
          assert!(vector::length(&coins) > 0, ENoCoins);
            let coin = vector::pop_back(&mut coins);
            pay::join_vec(&mut coin, coins);
            pay::split_and_transfer<T>(&mut coin, amount, recipient, ctx);
            transfer::transfer(coin, tx_context::sender(ctx))
    }

Going line by line

  1. assert!(vector::length(&coins) > 0, ENoCoins); Here I am saying that there should be more than one coin object passed.

Here, I am joining the coin objects

  let coin = vector::pop_back(&mut coins);
   pay::join_vec(&mut coin, coins);

After joining the coin objects, I am calling SUI function which splits the amount and returns the remaining, the remaining is send back to the address.

      pay::split_and_transfer<T>(&mut coin, amount, recipient, ctx);
            transfer::transfer(coin, tx_context::sender(ctx))
Alwaysblue
  • 9,948
  • 38
  • 121
  • 210