第4节:实现Module

上节我们完成了接口定义,本节将实现这些接口。

Code

本节将实现Token的各个接口:public、mint、deposit、withdraw、balance_of

/// This module defines a minimal Coin and Balance.
module NamedAddr::BasicCoin {
    use std::signer;

    /// Address of the owner of this module
    const MODULE_OWNER: address = @NamedAddr;

    /// Error codes
    const ENOT_MODULE_OWNER: u64 = 0;
    const EINSUFFICIENT_BALANCE: u64 = 1;
    const EALREADY_HAS_BALANCE: u64 = 2;

    struct Coin has store {
        value: u64
    }

    /// Struct representing the balance of each address.
    struct Balance has key {
        coin: Coin
    }

    /// Publish an empty balance resource under `account`'s address. This function must be called before
    /// minting or transferring to the account.
    public fun publish_balance(account: &signer) {
        let empty_coin = Coin { value: 0 };
        // assert!(signer::balance_of(account) == 0, EALREADY_HAS_BALANCE);
        assert!(!exists<Balance>(signer::address_of(account)), EALREADY_HAS_BALANCE);

          // 这句代码完成了publish ✅,没有发币!
        move_to(account, Balance { coin: empty_coin });
    }

    /// Initialize this module.
    public fun mint(module_owner: &signer, mint_addr: address, amount: u64) acquires Balance {
        // Only the owner of the module can initialize this module
        assert!(signer::address_of(module_owner) == MODULE_OWNER, ENOT_MODULE_OWNER);

        // Deposit `amount` of tokens to `mint_addr`'s balance
          // 发币了 ✅
        deposit(mint_addr, Coin { value: amount });
    }

    /// Returns the balance of `owner`.
    public fun balance_of(owner: address): u64 acquires Balance {
        borrow_global<Balance>(owner).coin.value
    }

    /// Transfers `amount` of tokens from `from` to `to`.
    public fun transfer(from: &signer, to: address, amount: u64) acquires Balance {
        let check = withdraw(signer::address_of(from), amount);
        deposit(to, check);
    }

    /// Withdraw `amount` number of tokens from the balance under `addr`.
    fun withdraw(addr: address, amount: u64) : Coin acquires Balance {
        let balance = balance_of(addr);

        // balance must be greater than the withdraw amount
        assert!(balance >= amount, EINSUFFICIENT_BALANCE);

        let balance_ref = &mut borrow_global_mut<Balance>(addr).coin.value;
        *balance_ref = balance - amount;

          // 返回withdraw的数量
        Coin { value: amount }
    }

    /// Deposit `amount` number of tokens to the balance under `addr`.
    fun deposit(addr: address, check: Coin) acquires Balance {
        let balance = balance_of(addr);

        // Get a mutable reference of addr's balance's coin value
        let balance_ref = &mut borrow_global_mut<Balance>(addr).coin.value;

        // TODO: follow the implementation of `withdraw` and implement me!
        let Coin { value } = check; // unpacks the check

        // Increment the value by `amount`
        *balance_ref = balance + value;
    }
}

Note

  • 需要了解对象的存储:borrow_global_mut

  • 需要了解函数的原型,返回值:acquires Balance {

  • 对象的解析:Coin { value: amount }

  • 断言

    # predicate为false时,抛异常
    assert!(<predicate>, <abort_code>);
    
  • balance_of

    borrow_global<Balance>(owner).coin.value
                     |       |       \    /
           # resource type  address  field names
    

results matching ""

    No results matching ""