Sui Move 合约升级与权限定制

一:猜数设计

让我们来设计一个简单的猜数程序,用户猜测一个数字并传入函数,判断与程序随机而成的数字是否相同,如果相同就给予一定奖励。

这里的奖励可以是链上流通的货币或是其它有价值的虚拟物品,不过作为一篇适合 S u i   M o v e \mathit {Sui\ Move} Sui Move 初学者的简单用例,直接牵扯到高昂物品似乎有所不妥,所以这里的奖励就用一个整型的 p r i z e \mathit {prize} prize 来表示,将含有奖金的 o b j e c t \mathit {object} object 发送给猜中数字的玩家,以此来作为激励手段。

同时,我们还可以用 E v e n t s \mathit {Events} Events 来记录链上发生的重大事件。在这个例子里,重大事件无疑就是 W i n n e r \mathit {Winner} Winner 了,我们可以用事件来记录胜者玩家的地址,为了让数据有一定的分析价值,还可以记录到这一次猜中数之前的所有玩家的尝试总数。

那么,根据分析,我们可以用三个 s t r u c t \mathit {struct} struct 来存储这些信息。

struct Count has key {
    id: UID,
    total: u64,
}

struct Prize has key {
    id: UID,
    prize: u8,
}

struct GuessEvent has copy, drop {
    total_count: u64,
    final_winner: address,
}
  • C o u n t \mathit {Count} Count 会作为一个共享对象,让所有玩家都可以访问并修改,其中的 t o t a l \mathit {total} total 将存储一共的尝试猜数的次数,直到猜中时清零重置。
  • P r i z e \mathit {Prize} Prize 直到被猜中数时才会被创建,同时被发送给此次交易的发起者,也就是猜中数字的玩家,其中的 p r i z e \mathit {prize} prize 可以简单设定为猜中的数等值的金额,由于猜数的范围不能太大,不妨就以 [ 0 ,  10 ] [\text 0,\ \text {10}] [0, 10] 这个闭区间为前置条件。
  • G u e s s E v e n t \mathit {GuessEvent} GuessEvent 是定义的一个事件,我们只关心事件当中的值,同时让它在作用域结束时自我消亡,所以设定了 c o p y ,   d r o p \mathit {copy},\ \mathit {drop} copy, drop 这两个能力。
    触发事件时只需要使用sui::event::emit(<ObjectEvent>);
    而交易产生的事件详情可以在 S u i   e x p l o r e r \mathit {Sui\ explorer} Sui explorer 中的 E v e n t s \mathit {Events} Events 标签页查看。

根据上述分析,我们可以很轻松地编写三个函数。

fun init(ctx: &mut TxContext) {
    let count = Count {
        id: object::new(ctx),
        total: 0,
    };
    transfer::share_object(count);
}

fun send_prize(count: u64, prize: u8, ctx: &mut TxContext) {
    transfer::transfer(Prize {
        id: object::new(ctx),
        prize,
    }, tx_context::sender(ctx));

    event::emit(GuessEvent {
        total_count: count,
        final_winner: tx_context::sender(ctx),
    });
}

public entry fun guess_between_zero_and_hundred(count: &mut Count, number: u8, clock: &Clock, ctx: &mut TxContext) {
    let des_number = ((clock::timestamp_ms(clock) % 11) as u8);
    if (number == des_number) {
        send_prize(count.total, number, ctx);
        count.total = 0;
    } else {
        count.total = count.total + 1;
    }
}
  • i n i t \mathit {init} init 函数只会在发布时被调用一次,用来创建 C o u n t \mathit {Count} Count 并将其共享再好不过。
  • s e n d _ p r i z e \mathit {send\_prize} send_prize 函数是在数字被猜中时调用的,作用是将奖励 P r i z e \mathit {Prize} Prize 发送给中奖者,同时触发一个事件。
  • e n t r y \mathit {entry} entry 函数是指在交易过程中能够被直接调用的,它不应该有返回值,因为即使有也没什么作用,入口函数被不被 p u b l i c \mathit {public} public 修饰的区别在于能否被其它模块调用,以及合约升级时能否被更改等。
    g u e s s _ b e t w e e n _ z e r o _ a n d _ h
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值