9.轻松入门Sui Move: Ability

在前面几章我们一直在说对象的ability,那什么是ability呢? ability直译过来就是数据类型的能力。

Ability有四种,分别是key,store,copy,drop。基础数据类型和内建的数据类型的ability是默认的,不可修改的。他们默认有copy,drop,store这三种能力。结构体默认没有任何能力,但是我们可以自行设置结构体的能力。下面我主要讲解每种能力的含义和如何设置结构体的能力。

无论哪种ability,都是使用has关键字申明,具体如下:

rust 复制代码
//多个ability使用逗号隔开
public struct Person has key,store {
    id:UID,
    name: String,
}

Key Ability

有些资料说拥有key ability代表能在全局存储中作为key使用,这个并不适用于Sui Move。关于key ability的作用官网如下描述:

On Sui, the key ability indicates that a struct is an object type and comes with an additional requirement that the first field of the struct has signature id: UID, to contain the object's unique address on-chain.

翻译过来:**如果一个类型,带有key ability就代表他是一个对象,并且要求这个结构体的第一个字段必须是id:UID。**这个id字段包含了这个对象在区块链上的地址。

如果我们定义了一个结构体有key ability,但是没有id字段或者id字段没在第一位置,编译都会报错:有key ability第一字段就必须是类型为UID的id。如下:

rust 复制代码
 public struct Test3 has key {
     name: String     
}
bash 复制代码
public struct Test3 has key {
--- The 'key' ability is used to declare objects in Sui
name: String     
^^^^ Invalid object 'Test3'. Structs with the 'key' ability must have 'id: sui::object::UID' as their first field

所以key ability就是用来标识结构体是否是对象的

Store Ability

key是对象必有的能力,而store则是对象可选的能力。有以下两种情况需要指定store abiity:

  • 1.当一个对象需要在定义他的模块之外被转交
  • 2.当 一个结构体需要被嵌套的时候

如果你想限定某一个独有对象只能在定义它的模块内transfer,就无需予对象store ability。比如以下代码中的company对象,如果在定义他的模块外调用transfer方法,或者在命令行使用sui client transfer都会报错。

rust 复制代码
//没有store ability
public struct Company  has key {
    id: UID,     
    person: Person,
    can_be_transfered: bool,
}
public struct Person has key,store {
    id:UID,
    name: String,
}

如果你想限定某个对象只有满足特定条件的时候才能转交,就可以自定义transfer方法,并且限定只能在模块内transfer,这样。实现如下:

rust 复制代码
const ECanNotTransfer = 1;
//对象company没有store ability,只允许在定义对象的模块内transfer
public struct Company  has key {
    id: UID,     
    person: Person,
    can_be_transfered: bool,
}
public struct Person has key,store {
    id:UID,
    name: String,
}
//自定义transfer方法
public fun transfer_company(company: Company, someone: address) {
    //只有can_be_transfered字段为true才可以transfer,否则退出程序
    assert!(company.can_be_tra	nsfered, ECanNotTransfer);
    transfer::transfer(company, someone);
} 

Copy

与key ability相反,copy ability不能用于对象。copy ability 就是用于标记这个结构体是否可以被复制

rust 复制代码
public struct Company  has key {
    id: UID,     
    person: Person,
    can_be_transfered: bool,
}
public struct Person has key,store {
    id:UID,
    name: String,
}
public entry fun new(ctx: &mut TxContext) {
    let person = Person {
        id: object::new(ctx),
        name: string::utf8(b"hanmeimei"),
    };
    let company = Company {
        id: object::new(ctx),
        person: person,
        can_be_transfered: false,
    };
    //使用关键词copy复制company对象
    let _company2 = copy company;
    transfer::transfer(company, tx_context::sender(ctx));
    transfer::transfer(_company2, tx_context::sender(ctx))
}

编译报错:

那我们是不是加上copy ability就可以顺利通过编译呢???我们加上之后继续编译,报错如下:

如果要对一个结构体加上copy ability,那么这个结构体内所有字段都需要拥有该ability 然而对象Company的id字段不具有copy ability,而这个id字段是每个对象都有的字段,所以可以得出结论:copy ability不能用于对象,只能用于非对象结构体

值得注意的是在对结构体设置copy 、store 和drop能力的时候,都需要先确保结构体内所有字段包含这些能力。

Drop

跟copy同理,drop ability也只能用于非对象结构体。drop表明这个结构体是否能在作用域结束的时候自动删除。如果不能自动删除则需要手动调用删除逻辑。删除结构体的方法详见:6.轻松入门Sui Move: 结构体

了解更多Sui Move内容:

相关推荐
麦麦大数据2 天前
基于以太坊区块链+Spring Boot+Solidity智能合约的投票系统设计与实现
spring boot·后端·区块链·智能合约·投票系统
程序员李程峰3 天前
基础知识④链和代币之间的关系
web3·去中心化·区块链·智能合约·同态加密·共识算法·信任链
程序员李程峰3 天前
基础知识⑤ERC-20、BEP-20 和TRC-20 这三种流行的加密代币标准
web3·去中心化·区块链·智能合约·同态加密·共识算法·信任链
程序员李程峰4 天前
基础知识——各种钱包之间的联系与区别
web3·去中心化·区块链·智能合约·同态加密·零知识证明·信任链
程序员李程峰4 天前
基础知识①区块链钱包基础
去中心化·区块链·智能合约·同态加密·共识算法·信任链·分布式账本
程序员李程峰4 天前
基础知识②区块链的链是什么
web3·去中心化·区块链·智能合约·同态加密·共识算法·信任链
木西5 天前
从零搭建 Amiko 受控金库|Solidity 链下签名链上执行实战
web3·智能合约·solidity
ithadoop7 天前
Solana入门:区块链新手速成指南(第二阶段:开发入门)
rust·web3·区块链·智能合约·solana
好家伙VCC11 天前
**发散创新:基于Solidity的通证经济模型设计与智能合约实现**在区块链技术日益成熟的今天,**通证经济(Token Econo
java·python·区块链·智能合约
木西11 天前
企业级 AI 智能账户:基于 ERC-4337 的权限分级与动态风控实践
web3·智能合约·solidity