Basic Tokens

基础代币 #

合约逻辑

基本代币提供以下功能

  • 应该由签名者调用 create_balance 函数。
  • 用户在调用存款、取款、划转资金功能前。

这是基本令牌的界面。

module coin_addrx::BasicCoins{

    use std::signer;

    struct Coins has store{ val : u64 }

    struct Balance has key{
        coins:Coins
    }

    /// Error codes
    const ERR_BALANCE_NOT_EXISTS: u64 = 101;
    const ERR_BALANCE_EXISTS: u64 = 102;
    const EINSUFFICIENT_BALANCE: u64 = 1;
    const EALREADY_HAS_BALANCE: u64 = 2;
    const EEQUAL_ADDR: u64 = 4;

    /// Mint `amount` called val tokens on `contract`. 
    public fun mint(val: u64):Coins{
        let new_coin = Coins{val};
        new_coin
    }

     /// Burn `amount` tokens from `contract`.
    public fun burn(coin : Coins){
        let Coins{val: _ } = coin;
    }

    public fun create_balancce(acc: &signer){
        let acc_addr = signer::address_of(acc);

        assert!(!balance_exists(acc_addr),ERR_BALANCE_EXISTS);

        let zero_coins = Coins{val:0};
        move_to(acc,Balance{coins : zero_coins});
    }

    public fun balance_exists(acc_addr: address):bool{
        exists<Balance>(acc_addr)
    }

     public fun balance(owner: address): u64 acquires Balance {
        borrow_global<Balance>(owner).coins.val
    }

    public fun deposit(acc_addr: address,coins:Coins) acquires Balance{
        let balance = balance(acc_addr);
        assert!(balance_exists(acc_addr),ERR_BALANCE_NOT_EXISTS);
        let balance_ref = &mut borrow_global_mut<Balance>(acc_addr).coins.val;
        let Coins{val} = coins;
        *balance_ref = balance + val;
    }


    public fun withdraw(acc: address,value : u64) : Coins acquires Balance{
        assert!(balance_exists(acc),ERR_BALANCE_NOT_EXISTS);
        let balance = balance(acc);
        assert!(balance >= value, EINSUFFICIENT_BALANCE);
        let balance_ref = &mut borrow_global_mut<Balance>(acc).coins.val;
        *balance_ref = balance - value;
         Coins{ val: value }
    }
   /// Transfers `amount` of tokens from `from` to `to`.
    public fun transfer(from: &signer, to: address, amount: u64) acquires Balance {
        let from_addr = signer::address_of(from);
        assert!(from_addr != to, EEQUAL_ADDR);
        let check = withdraw(from_addr, amount);
        deposit(to, check);
    }
    

    #[test(acc=@0x123)]
    fun test_use_some_coins(acc: signer) acquires Balance{
        let acc_addr = signer::address_of(&acc);
        let coins_10 = mint(10);
        create_balancce(&acc);
        deposit(acc_addr,coins_10);
        assert!(balance(acc_addr)==10,EINSUFFICIENT_BALANCE);

        let coins_5 = withdraw(acc_addr, 5);
        assert!(balance(acc_addr)==5,EALREADY_HAS_BALANCE);

        burn(coins_5);
    }

}