sui move动态字段练习(5)- 总结与思考

引言

之前几篇文章,我们用sui move动态字段模拟solidity映射,实现了一个类似erc20的代币,这使我更加深刻地理解了sui move和solidity编程特性和编程思想的区别。下面是我的总结与思考。

总结

首先,sui与solidity的编程特性有很大差异。

solidity

solidity是面向以太坊虚拟机(EVM)的合约编程语言,以太坊状态树储存了各个账号下的状态,而合约账户是由智能合约定义转变状态的规则。
例如在同质化代币的实现中,solidity需要使用映射这一类型储存各个账户的余额,代币被用储存在合约账户的数字替代,实际上持有代币的余额就是合约账户下储存的数字。
比如,小蓝要查询自己拥有多少代币,就需要查询代币合约下以小蓝地址为键的映射的值。小蓝要向小红转账10个代币,合约会先检查小蓝的余额是否大于转账数额,如果大于,就会将小蓝余额的对应值减去10,将小红余额对应值加10.

sui

sui是面向资源编程。资源是具有key能力的对象,这意味它可以在全局存储中用做键,资源都具有所有者属性来声明其所有权。所有权分为:被地址拥有,被另一个资源拥有,可变的共享,不可变的共享。而sui move中module可以称为合约,它规定了相应资源的生成,销毁,查询等规则,多个module可以部署在一个package下。只有module才能创建资源,只有资源的拥有者才能在交易中使用资源(共享资源除外),只有创建资源的module才能对资源内的属性进行改变。

与solidity不同的是,sui中可以将余额封装后创建Token资源,这样Token资源的所有者就是Token的持有者,对Token具有使用权。相比于单纯数字的增减,持有者真正拥有了数字资产。

虽然Sui是纯静态的语言,但是泛型为其提供了很大的灵活性。在solidity中,我们如果想要发行多种Token,就需要部署多个合约,分别储存不同代币的余额状态。而在sui中,我们只需要使用泛型,就可以使用一个module发行相同规则的不同代币。

在分析下solidity映射与sui动态字段的区别
要深入理解solidity的映射,我们需要对以太坊合约的储存布局有所了解。以太坊中每个特定地址的智能合约都有自己的"储存",储存是一个 2256 ✖ 2256大小的键值映射
这是一个很大的数字,但我们不需要担心它会占用太多空间,因为大部分的储存都未被使用,只有在非零值被写入时,才会被写入数据库。
我们将每一个储存的值是32字节,我们叫它插槽。每一个储存的键也是32字节大小,键的范围为0 ~ 2*256-1。那第一个插槽就成为slot(0),第二个插槽为slot(1),… ,第n个插槽就是slot(n-1)。
而在solidity中,映射在储存中的布局遵循特定的规则。
首先solidity的映射类型本身顺序占据一个插槽slot(i),映射的键为k, 则此映射的值会被储存在keccak256(k,p),我们可以根据此规则很轻松的找到相应值的位置
例如:

    contract ERC20{
        mapping (address => uint256) balanceOf;
    }

balanceOf储存映射储存对应地址的代币余额
我们知道小蓝的地址为0x312bEeF78F3efa18cc4B94D489fCD43fEb5BbA9E,那么小蓝代币余额储存的计算:

  1. balanceOf映射自身顺序占据slot(0), p = 0 ;
  2. 键为小蓝的地址, k = 0x312bEeF78F3efa18cc4B94D489fCD43fEb5BbA9E
  3. 余额储存在 slot( keccak256(abi.encode(address(0x312bEeF78F3efa18cc4B94D489fCD43fEb5BbA9E), 0)) )
    这样来看,当一个映射的储存记录无限多时,取出一个键对应的值事件复杂度为O(1).

在sui move中,我们使用的table,bag等类型的底层实现都为动态字段
添加一个动态字段,实质上是为对象添加了一个子对象

        let field = Field {
            id: object::new_uid_from_hash(hash),
            name,
            value,
        };
        add_child_object(object_addr, field)

结语

综上,sui的编程特性确定了sui的编程风格,sui官方实现的同质化代币coin很好的体现了sui的编程特性,泛型的灵活运用,无需使用数字来表示所有者对资产的持有,而是通过将余额封装为coin资源使所有者持有,比起在sui中模拟映射,不仅便利,而且安全(减少了出现合约编写的逻辑漏洞的可能)。因此,我才说’本例实现仅用于学习动态字段,由于访问gas和便捷性不强,无法用于生产。在sui move中使用的同质化代币请使用官方标准库中内置的coin’.

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>