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

相关推荐
Blockchina4 天前
Solana链上的Pump狙击机器人与跟单机器人的工作原理及盈利模式
web3·区块链·智能合约·solana·sol机器人
TMDOG6664 天前
微服务架构设计的初次尝试——基于以太坊智能合约 + NestJS 微服务的游戏社区与任务市场系统:架构设计
游戏·微服务·智能合约
电报号dapp1195 天前
ARB链挖矿DApp系统开发模式定制
区块链·智能合约
冲上云霄的Jayden10 天前
Hyperledger Fabric有那些核心技术,和其他区块链对比Hyperledger Fabric有那些优势
区块链·智能合约·fabric·数据隐私·共识机制·多通道技术·模块化架构
终有zy12 天前
Solidity智能合约中的异常处理error、require、assert
区块链·智能合约·1024程序员节
什么都想学。12 天前
智能合约分享
智能合约·1024程序员节
加密社13 天前
使用铭文思路对智能合约改进
区块链·智能合约
电报号dapp11913 天前
智能合约开发中的LP分红系统
区块链·智能合约
Keegan小钢13 天前
智能合约开发工具Remix
web3·智能合约·solidity
Sui_Network16 天前
Walrus + Sui:如何充分发挥Web3的潜力
大数据·前端·学习·web3·区块链·智能合约