sui move 动态字段练习(4)

  • shaflow01
  • 更新于 2024-03-14 23:52
  • 阅读 642

引言学习了suimove中的动态字段,table,bag,作为练习,我准备使用它们模拟solidity中的映射类型,在suimove实现一个类似erc20的同质化代币作为之前学习的实践与巩固。本文分享了练习过程中的重构,事件和错误。

引言

学习了sui move中的动态字段,table,bag,作为练习,我准备使用它们模拟solidity中的映射类型,在sui move实现一个类似erc20的同质化代币作为之前学习的实践与巩固。本文分享了练习过程中的重构,事件和错误。 注:本例实现仅用于学习动态字段,由于访问gas和便捷性不强,无法用于生产。在sui move中使用的同质化代币请使用官方标准库中内置的coin

事件和错误

我们需要定义一些事件,在资产转移的时候触发,以便链下能够快速监控

Transfer事件

    struct Transfer has copy, drop {
        from: address,
        to: address,
        value: u64,
    }

Transfer事件将会在转账,铸造和销毁交易中被触发

  1. 在转账交易中,from,to均不能为0
  2. 在铸币交易中,from为0地址
  3. 在销毁交易中,to为0地址

Approve事件

    struct Approve has copy, drop {
        owner: address,
        spender: address,
        value: u64,
    }

Approve事件将会在授权被变更时被触发

error

我们需要一些错误,使交易抛出异常时,保证交易者快速确定原因。

    const EBadWitnessErr: u64 = 0;
    const AlreadlyInitlizeErr: u64 = 1;
    const BadTypeOrNotInitlizeErr: u64 = 2;
    const OverFlowErr: u64 = 3;
    const NotEnoughBalanceErr: u64 = 4;
    const AddressZeroErr: u64 = 5;
    const NotEnoughAllowanceErr: u64 = 6;

重构函数

transfer函数和transferFrom函数存在部分相同的函数逻辑,所以我们可以进行提取重构

  1. 定义transfer_in内部函数

    fun transfer_in<T>(balance_table:&mut BalanceData<T>, from: address, to:address, value: u64){
        assert!(table::contains(&balance_table.balance,from), NotEnoughBalanceErr);
    
        let balance_from = table::borrow_mut(&mut balance_table.balance, from);
        assert!(*balance_from >= value , NotEnoughBalanceErr);
        if(*balance_from > value){
            *balance_from = *balance_from - value;
        }
        else{
            table::remove(&mut balance_table.balance ,from);
        };
        event::emit(
            Transfer {
                from: from,
                to: to,
                value: value,
            }
        );
        if(table::contains(&balance_table.balance, to)){
            let balance_to = table::borrow_mut(&mut balance_table.balance,to);
            assert!(*balance_to + value >= *balance_to, OverFlowErr);
            *balance_to = *balance_to + value;
        }else{
            table::add(&mut balance_table.balance, to, value);
        };
    
    }
  2. 定义花费授权代币内部函数

    fun spender_allowance<T>(allowance_table:&mut AllowanceData<T>, from:address ,spender: address, value: u64){
        assert!(table::contains(&allowance_table.allowance, from), NotEnoughAllowanceErr);
        let allowance = table::borrow_mut(&mut allowance_table.allowance, from);

        assert!(table::contains(&allowance.allowance_amount, spender),NotEnoughAllowanceErr);
        let amount = table::borrow_mut(&mut allowance.allowance_amount, spender);

        assert!(*amount >= value, 7);
        let new_amount = *amount - value;
        event::emit(
            Approve {
                owner: from,
                spender: spender,
                value: new_amount,
            }
        );
        if(new_amount > 0){
            *amount = new_amount;
        }
        else{
            *amount = new_amount;
            table::remove(&mut allowance.allowance_amount, spender);
        };
    }

重构后的函数

transfer

    public fun transfer<T>(_:& TokenCap<T>, balance_list: &mut BalanceList, to:address, value: u64, ctx:&mut TxContext):bool{
        assert!(to != AddressZero, AddressZeroErr);
        if(value == 0){
            return true
        };
        let type = ascii::into_bytes(type_name::into_string(type_name::get_with_original_ids<T>()));
        assert!(bag::contains(&balance_list.balance_list, type), BadTypeOrNotInitlizeErr);
        transfer_in(bag::borrow_mut<vector<u8>, BalanceData<T>>(&mut balance_list.balance_list, type), tx_context::sender(ctx), to, value);
        return true
    }

transfer

    public fun transferFrom<T>(_:& TokenCap<T>, allowance_list: &mut AllowanceList,balance_list: &mut BalanceList,from: address, to: address, value: u64, ctx:&mut TxContext):bool{
        assert!(from != AddressZero, AddressZeroErr);
        assert!(to != AddressZero, AddressZeroErr);
        if(value == 0){
            return true
        };
        let type = ascii::into_bytes(type_name::into_string(type_name::get_with_original_ids<T>()));
        assert!(bag::contains(&allowance_list.allowance_list, type), BadTypeOrNotInitlizeErr);
        assert!(bag::contains(&balance_list.balance_list, type), BadTypeOrNotInitlizeErr);

        spender_allowance(bag::borrow_mut<vector<u8>, AllowanceData<T>>(&mut allowance_list.allowance_list, type), from, tx_context::sender(ctx), value);

        transfer_in(bag::borrow_mut<vector<u8>, BalanceData<T>>(&mut balance_list.balance_list, type), from ,to,value);
        return true
    }
  • 原创
  • 学分: 1
  • 分类: Sui
  • 标签:
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
shaflow01
shaflow01
0x4937...bA76
江湖只有他的大名,没有他的介绍。