Siu是如何处理资产所有权在Sui上,Object是数据储存的基本单位,通过定义,创建和管理这些代表用户资产级的可编程对象。Objecttype(对象类型)Sui定义的每个对象都会用有key和UID。在区块链浏览器查看,可以看到五个基本参数—owner,objectId,ty
在Sui上,Object是数据储存的基本单位,通过定义,创建和管理这些代表用户资产级的可编程对象。
Sui 定义的每个对象都会用有key 和 UID。在区块链浏览器查看,可以看到五个基本参数 — owner,objectId, type, version, 最后一个交易摘要。 我们还可以通过其他字段来定义object 完善功能。
Sui链上的,每个对象都有一个owner字段,它决定了对象在事务中的使用方式。
地址所有对象限制了访问权限,只有对应地址的所有者才能对其进行操作。
public fun transfer<T: key>(obj: T, recipient: address)
public fun public_transfer<T: key + store>(obj: T, recipient: address)
Sui的动态字段和对象是动态添加和删除的,动态字段允许我们根据需要调整对象的机构,按需消耗gas。
Fields 可以存储任务课存储的值,Object Fields 只能存具有 key 能力的对象
不能被更改,转移活着删除,这类对象没有所有者,可以被任何人使用。
0x2::transfer::share_object
共享对象需要 key 能力,可被公开访问和使用。
下面例子是创建一个销售甜甜圈的商店,每个人都需要访问商店菜才能购买。
module examples::donuts {
use sui::transfer;
use sui::sui::SUI;
use sui::coin::{Self, Coin};
use sui::object::{Self, UID};
use sui::balance::{Self, Balance};
use sui::tx_context::{Self, TxContext};
/// For when Coin balance is too low.
const ENotEnough: u64 = 0;
/// Capability that grants an owner the right to collect profits.
struct ShopOwnerCap has key { id: UID }
/// A purchasable Donut. For simplicity's sake we ignore implementation.
struct Donut has key { id: UID }
/// A shared object. `key` ability is required.
struct DonutShop has key {
id: UID,
price: u64,
balance: Balance<SUI>
}
/// Init function is often ideal place for initializing
/// a shared object as it is called only once.
fun init(ctx: &mut TxContext) {
transfer::transfer(ShopOwnerCap {
id: object::new(ctx)
}, tx_context::sender(ctx));
// Share the object to make it accessible to everyone!
transfer::share_object(DonutShop {
id: object::new(ctx),
price: 1000,
balance: balance::zero()
})
}
/// Entry function available to everyone who owns a Coin.
public fun buy_donut(
shop: &mut DonutShop, payment: &mut Coin<SUI>, ctx: &mut TxContext
) {
assert!(coin::value(payment) >= shop.price, ENotEnough);
// Take amount = `shop.price` from Coin<SUI>
let coin_balance = coin::balance_mut(payment);
let paid = balance::split(coin_balance, shop.price);
// Put the coin to the Shop's balance
balance::join(&mut shop.balance, paid);
transfer::transfer(Donut {
id: object::new(ctx)
}, tx_context::sender(ctx))
}
/// Consume donut and get nothing...
public fun eat_donut(d: Donut) {
let Donut { id } = d;
object::delete(id);
}
/// Take coin from `DonutShop` and transfer it to tx sender.
/// Requires authorization with `ShopOwnerCap`.
public fun collect_profits(
_: &ShopOwnerCap, shop: &mut DonutShop, ctx: &mut TxContext
) {
let amount = balance::value(&shop.balance);
let profits = coin::take(&mut shop.balance, amount, ctx);
transfer::public_transfer(profits, tx_context::sender(ctx))
}
}
在Move,可以通过将结构
类型的字段放入另一个字段来组织数据结构。
store
能力结构体的组合和使用十分重要。
struct Foo has key {
id: UID,
bar: Bar,
}
struct Bar has store {
value: u64,
}
在这两个结构题中,Bar是一个普通结构体,Fo是一个Sui对象(具有 key
能力)。
struct Bar has key, store {
id: UID,
value: u64,
}
//添加了key 能力,就成为了Sui对象
如果将 Bar
类型的 Sui 对象放入 Foo
类型的 Sui 对象中,则对象类型 Foo
将包装对象类型 Bar
。对象类型 Foo
是包装器或包装对象
在 Sui 中,为了将一个结构体类型嵌入到另一个结构体类型中,被嵌入的类型必须具有 store
能力。而当结构体类型被嵌入到具有 key
能力的 Sui 对象结构体中时,它也成为一个 Sui 对象类型。
Option
包装struct SimpleWarrior has key {
id: UID,
sword: Option<Sword>,
shield: Option<Shield>,
}
struct Sword has key, store {
id: UID,
strength: u8,
}
struct Shield has key, store {
id: UID,
armor: u8,
}
public fun create_warrior(ctx: &mut TxContext) {
let warrior = SimpleWarrior {
id: object::new(ctx),
sword: option::none(),
shield: option::none(),
};
transfer::transfer(warrior, tx_context::sender(ctx))
}
public fun equip_sword(warrior: &mut SimpleWarrior, sword: Sword, ctx: &mut TxContext) {
if (option::is_some(&warrior.sword)) {
let old_sword = option::extract(&mut warrior.sword);
transfer::transfer(old_sword, tx_context::sender(ctx));
};
option::fill(&mut warrior.sword, sword);
}
vector
包装Option
包装struct Pet has key, store {
id: UID,
cuteness: u64,
}
struct Farm has key {
id: UID,
pets: vector<Pet>,
}
Sui Move 中有四种能力控制特定类型的值如何使用(赋予的权限)。
类型的值如何被使用,这些能力是:copy、drop、store 和 key。
相当于游戏中的职业,法师,射手等,具有不同的技能,职责就不同。
enum MoveAbility {
COPY //允许复制值。
DROP //允许弹出/删除值。
KEY //允许将值直接保存在全局存储中。
STORE //允许将值保存在全局存储中的结构内。
}
允许在不再需要的某个结构题将其删除,没有drop能力是不允许被忽略的,防止被随意丢弃。这个能力也是为了防止资产泄漏或错误处理。而具有单个 drop
能力的结构称为 Witness。
module book::drop_ability;
/// This struct has the `drop` ability.
public struct IgnoreMe has drop {
a: u8,
b: u8,
}
/// This struct does not have the `drop` ability.
public struct NoDrop {}
#[test]
// Create an instance of the `IgnoreMe` struct and ignore it.
// Even though we constructed the instance, we don't need to unpack it.
fun test_ignore() {
let no_drop = NoDrop {};
let _ = IgnoreMe { a: 1, b: 2 }; // no need to unpack
// The value must be unpacked for the code to compile.
let NoDrop {} = no_drop; // OK
}
我们可以使用copy
自定义类型来允许实例被复制。
public struct Copyable has copy {}
copy
在Move中允许类型的实例或值被复制,但Move的资源模型默认是不允许复制的。
copy
能力允许隐式和显式复制。隐式复制发生在赋值操作中,而显式复制可以通过解引用操作符实现。
copy能力通常搭配drop能力一起使用。
let a = Copyable {};
let b = a; // `a` is copied to `b`
let c = *&b; // explicit copy via dereference operator
let Copyable {} = a; // doesn't have `drop`
let Copyable {} = b; // doesn't have `drop`
let Copyable {} = c; // doesn't have `drop`
在move中,所有的原生类型和标准库中定义的类型都具有 copy
和 drop
能力,并且有Move编译器进行内存管理。
允许结构体被存储,并且第一个字段为UID
类型,确保对象的唯一性和非可丢弃性。可以直接由账户或者地址拥有。
具有key能力,就不能有 drop
和copy
。又因为UID
的存在,Move的原生类型和标准类型都没有key
能力,这能力仅适用于Sui框架和自定义的类型。
public struct Object has key {
id: UID, // required
name: String,
}
/// Creates a new Object with a Unique ID
public fun new(name: String, ctx: &mut TxContext): Object {
Object {
id: object::new(ctx), // creates a new UID
name,
}
}
store
能力在 Move 中能将数据持久化存储在区块链上,它可以允许开发者在Move模块中定义存储和检索的数据结构。
/// This type has the `store` ability.
public struct Storable has store {}
/// Config contains a `Storable` field which must have the `store` ability.
public struct Config has key, store {
id: UID,
stores: Storable,
}
/// MegaConfig contains a `Config` field which has the `store` ability.
public struct MegaConfig has key {
id: UID,
config: Config, // there it is!
}
store
与 key
的关系store
能力通常与 key
能力一起使用。key
能力用于访问和修改存储在区块链上的数据。在 Move 中,每个存储的数据项都对应一个唯一的 key
。
key
用于指向存储在区块链上的数据项的位置。store
能力通过 key
来读取和写入数据。因此,store
能力需要 key
来操作存储的数据,两者是紧密相关的。通过 key
,程序可以定位到特定的数据项,并通过 store
能力对其进行读写操作。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!