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内容:

相关推荐
Sui_Network10 小时前
Crossmint 与 Walrus 合作,将协议集成至其跨链铸造 API 中
人工智能·物联网·游戏·区块链·智能合约
Allover#566991 天前
GZ036区块链卷一 EtherStore合约漏洞详解
区块链·智能合约
电报号dapp1193 天前
Web3游戏全栈开发实战指南:智能合约与去中心化生态构建全解析
游戏·web3·去中心化·区块链·智能合约
CertiK5 天前
重磅 | CertiK《Hack3d:2025第一季度安全报告》(附报告全文链接)
安全·web3·区块链·智能合约
Blossom.1186 天前
大数据时代的隐私保护:区块链技术的创新应用
人工智能·深度学习·自动化·区块链·智能合约
人类群星闪耀时6 天前
智能合约的法律挑战与解决之道:技术与法律的交融
区块链·智能合约
我是前端小学生11 天前
一文详细梳理Bank合约业务逻辑
智能合约
Blockchina13 天前
第 4 章 | Solidity安全 权限控制漏洞全解析
安全·web3·区块链·智能合约·solidity
Blockchina14 天前
第十四章 | DeFi / DAO / GameFi 项目高级实战
web3·区块链·智能合约·solidity
龙兵兵科技14 天前
利用智能合约技术打破线下陪玩私单僵局的可行性分析
智能合约·软件开发·线下陪玩·同城陪玩