掘金 后端 ( ) • 2024-04-26 10:35

一:游戏简介

以传统的扫雷游戏规则为模板,将扫雷区域简化成 $\text 5\ \times\ \text {10}$ 的正方形,点开所有安全格子视为获得胜利。

二:功能设计

  • 游戏发布者可以在后续任何游戏对局当中持续获得利益,当链上存储的利益余额达到一定数量时自动提现到发布者钱包,当然,发布者也可以手动进行提现。
  • 任何人都可以支付 $\text {666}\ \mathit {balance}$ 来开启一局游戏,如果你获得了胜利,很可惜,除了快乐和自封的荣誉等精神层面的激励之外,并不会收到任何实质性的奖励。
  • 任何人都可以创建挑战任务,除了添加额外的赏金之外,游戏难度并不会发生改变,即使你的任务奖励是天价。赏金最低设置为 $\text {1998}\ \mathit {sui\ balance}$。
  • 在有挑战任务的前提下,任何人都可以选择挑战,一次挑战的费用是当前赏金的一半,这里以最低金额举例说明:
    • 挑战任务赏金是 $\text {1998}$,此时有玩家挑战,需要支付它的一半,也就是 $\text {1998}\ \div\ \text 2\ =\ \text {999}$(如果有小数点则下取整)。
    • 这一笔 $\text {999}$ 将进一步拆分,它的一半(上取整)将会累加到赏金当中,另一半将按照 $\text 1\ :\ \text 3$ 的比例分配给游戏发布者和挑战任务发布者(如果有小数点,那么游戏发布者赚取的收益下取整),当该挑战被完成时,任务发布者的收益将转账到其钱包。
    • 下一个挑战者(即使上一个挑战者的对局尚未结束)将以 $(\text {1998}\ +\ \lceil \frac{\lfloor \frac{\text {1998}}{\text 2} \rfloor}{\text 2} \rceil)\ \div\ \text 2\ =\ \text {1249}$ 的金额开启挑战,后续的赏金累计和开启挑战的金额以此类推。
    • 对于同一个挑战任务,第一个成功扫雷的人,将收割当前的全部赏金,其他正在进行任务挑战的玩家将终止游戏对局,即使有的人才刚刚开始。

三:结构设计

3.1 游戏发布者

3.1.1 ADMIN

借助 $\mathit {One}$-$\mathit {Time}$-$\mathit {Witness}$ 生成Publisher,需要一个与模块同名并全大写的结构体:

public struct ADMIN has drop {}

3.1.2 GameCap

存储游戏发布者的相关信息,主要是 $\mathit {Sui}$ 余额和发布者的地址:

public struct GameCap has key {
    id: UID,
    balance: Balance<SUI>,
    publisher_address: address,
}

3.2 挑战任务

3.2.1 任务信息

奖励金额和发布者收益是必须的,为了清楚任务发布者是谁,还需要他/她的地址,除此之外,还可以维护两个数 —— 正在挑战的人数和尝试挑战的总人数,为游戏更增添一份紧张刺激感:

public struct Task has store {
    in_task: u64,
    total_attempts: u64,
    reward: Balance<SUI>,
    earned: Balance<SUI>,
    task_publisher_address: address,
}

3.2.2 任务列表

任务信息的结构设计并不能单独存在,我们另外开辟一个列表来存储一系列任务:

public struct TaskList has key {
    id: UID,
    task_ids: vector<ID>,
    tasks: Table<ID, Task>,
}

3.2.3 询问任务详情事件

通过任务编号查询其信息,触发事件并返回时使用的结构体:

public struct QueryTaskEvent has copy, drop {
    task_id: ID,
    in_task: u64,
    total_attempts: u64,
    cur_reward: u64,
}

3.3 玩家

3.3.1 游戏内容

存储有扫雷区域现状,每个格子是否安全的哈希码,如果是从任务进入的游戏,还需要对应的任务编号:

public struct GameInfo has key {
    id: UID,
    task_id: ID,
    checkerboard: vector<vector<Char>>,
    hash_code: vector<u8>,
}

3.3.2 任务已被他人完成事件

一个任务可以同时被多个人开启,但最终完成并获得奖励的只有一人,此时其他人再尝试该任务时触发:

public struct PlayTooLate has copy, drop {
    loser: String,
}

3.4 游戏

一系列在游戏过程中可能触发的情况事件,包括每一次扫雷后的区域变化事件、游戏成功事件以及游戏失败事件:

public struct GameEvent has copy, drop {
    checkerboard: vector<String>,
}

public struct GameSuccessEvent has copy, drop {
    reward: u64,
}

public struct GameOverEvent has copy, drop {
    loser: String,
}

四:功能实现

4.1 游戏发布者

4.1.1 init

通过 $\mathit {One}$-$\mathit {Time}$-$\mathit {Witness}$ 生成Publisher,同时根据发布者信息创建并共享GameCap

fun init(otw: ADMIN, ctx: &mut TxContext) {
    // create and transfer Publisher
    package::claim_and_keep(otw, ctx);

    // create and transfer GameCap
    let game_cap = GameCap {
        id: object::new(ctx),
        balance: balance::zero(),
        publisher_address: ctx.sender(),
    };
    transfer::share_object(game_cap);
}

4.1.2 withdraw

根据游戏设计,提现到游戏发布者钱包有两种情况,一种是手动(仅限发布者本人调用),另一种是到达一定金额是自动,为了更好地满足这两种情况,将提现的函数进行拆分:

public(package) fun withdraw_(game_cap: &mut GameCap, ctx: &mut TxContext) {
    // check the balance value
    assert!(game_cap.balance.value() > 0, ENotEarnBalance);

    // withdraw all the balance
    let all = game_cap.balance.withdraw_all();
    transfer::public_transfer(coin::from_balance(all, ctx), game_cap.publisher_address);
}

entry fun withdraw(_: &Publisher, game_cap: &mut GameCap, ctx: &mut TxContext) {
    withdraw_(game_cap, ctx);
}

entry提现函数中用Publisher来限制可调用的用户,public提现函数用(package)来限制只能由包内的其它模块调用,功能是当赚取到收益时体现到游戏发布者的钱包。

4.2 挑战任务

4.2.1 init

创建并共享TaskList

fun init(ctx: &mut TxContext) {
    // create and transfer task list
    let task_list = TaskList {
        id: object::new(ctx),
        task_ids: vector<ID>[],
        tasks: table::new<ID, Task>(ctx),
    };
    transfer::share_object(task_list);
}

4.2.2 create_task

支付一定金额(不能低于最小值)来创建一个挑战任务,同时别忘了维护TaskList

entry fun create_task(task_list: &mut TaskList, mut coin: Coin<SUI>, amount: u64, ctx: &mut TxContext) {
    // check the balance number
    assert!(coin.value() >= amount && amount >= MinimumBonus, ENotEnoughBalance);

    // split coin
    let reward_coin = coin.split(amount, ctx);
    let reward_balance = reward_coin.into_balance();

    // deal with the remaining coin
    if (coin.value() > 0) {
        transfer::public_transfer(coin, ctx.sender());
    } else {
        coin.destroy_zero();
    };

    // generate ID
    let id = object::id_from_address(ctx.fresh_object_address());
    // create task
    let task = Task {
        in_task: 0,
        total_attempts: 0,
        reward: reward_balance,
        earned: balance::zero(),
        task_publisher_address: ctx.sender(),
    };
    // store it
    task_list.task_ids.push_back(id);
    task_list.tasks.add(id, task);
}

4.2.3 complete_task

当有玩家完成任务时被调用,需要删除该任务相关的信息,以此来保证后续不再有人能够参与该任务,包括正在任务中的玩家再一次游戏时会被告知任务不存在,当然,对应的收益要按照游戏设计的规则发给对应的用户:

#[allow(lint(self_transfer))]
public fun complete_task(game_cap: &mut GameCap, task_id: ID, task_list: &mut TaskList, ctx: &mut TxContext) {
    // get task_ids
    let task_ids = &mut task_list.task_ids;
    // get index
    let (_, idx) = task_ids.index_of(&task_id);
    // remove it
    task_ids.remove(idx);

    // remove and get task
    let task = task_list.tasks.remove(task_id);
    // get task details
    let Task {
        in_task: _,
        total_attempts: _,
        reward,
        mut earned,
        task_publisher_address,
    } = task;

    // player reward
    transfer::public_transfer(coin::from_balance(reward, ctx), ctx.sender());

    // package publisher earned
    let amount = earned.value();
    let publisher_earned = earned.split(amount / 3);
    let publisher_balance = game_cap.borrow_balance_mut();
    publisher_balance.join(publisher_earned);
    // if the balance exceeds 10SUI then withdraw it
    if (publisher_balance.value() >= 10000000000) {
        game_cap.withdraw_(ctx);
    };

    // task publisher earned
    transfer::public_transfer(coin::from_balance(earned, ctx), task_publisher_address);
}

开篇的#[allow(lint(self_transfer))]是为了忽略一个警告,警告内容是函数中存在转移给自己的操作,经过分析判断,并没有什么逻辑上的问题,所以加这一句来忽略它。

4.2.4 update

当有玩家参加挑战时,挑战金额需要实时更新到对应的Task当中,尤其需要关注的是Coin如何根据游戏设计的规则进行拆分并存储:

#[allow(lint(self_transfer))]
public fun update(task: &mut Task, mut coin: Coin<SUI>, ctx: &mut TxContext) {
    // get reward and earned
    let reward = &mut task.reward;
    let earned = &mut task.earned;

    // check the coin value
    let amount = reward.value() / 2;
    assert!(coin.value() >= amount, ENotEnoughBalanceStart);

    let mut pay_coin = coin.split(amount, ctx);

    // deal with the remaining coin
    if (coin.value() > 0) {
        transfer::public_transfer(coin, ctx.sender());
    } else {
        coin.destroy_zero();
    };

    // update reward and earned
    let earned_amount = amount / 2;
    let earned_coin = pay_coin.split(earned_amount, ctx);
    earned.join(earned_coin.into_balance());
    reward.join(pay_coin.into_balance());
}

4.2.5 query_task

根据任务编号查询其相关信息:

entry fun query_task(task_id: ID, task_list: &TaskList) {
    // check id
    assert!(task_list.tasks.contains(task_id), ENotCorrectTaskOrCompleted);

    // get task and emit event
    let task = &task_list.tasks[task_id];
    event::emit(QueryTaskEvent {
        task_id,
        in_task: task.in_task,
        total_attempts: task.total_attempts,
        cur_reward: task.reward.value(),
    });
}

4.3 玩家

4.3.1 start_game

开启游戏(非挑战),只要支付的金额足够就可以启动游戏,对应的金额存储到GameCap下,同时生成GameInfo并将其所有权移交用户:

entry fun start_game(game_cap: &mut GameCap, mut coin: Coin<SUI>, ctx: &mut TxContext) {
    // check the coin value
    assert!(coin.value() >= MinimumStartBonus, ENotEnoughBalanceStart);

    let pay_coin = coin.split(MinimumStartBonus, ctx);

    // deal with the remaining coin
    if (coin.value() > 0) {
        transfer::public_transfer(coin, ctx.sender());
    } else {
        coin.destroy_zero();
    };

    // transfer the exact amount of coin
    let publisher_balance = game_cap.borrow_balance_mut();
    publisher_balance.join(pay_coin.into_balance());
    // if the balance exceeds 10SUI then withdraw it
    if (publisher_balance.value() >= 10000000000) {
        game_cap.withdraw_(ctx);
    };

    // prepare the GameInfo's id and taskid(fake)
    let id = object::new(ctx);
    let task_id = id.uid_to_inner();
    // create GameInfo
    let game_info = GameInfo {
        id,
        task_id,
        checkerboard: game::generate_empty_checkerboard(),
        hash_code: vector<u8>[],
    };
    transfer::transfer(game_info, ctx.sender());
}

GameInfo中的游戏区域是空的,包括地雷所在地的哈希码也是空的,这将在用户第一次尝试扫雷时生成。
因为链上一切都是公开的,若是一开始就将所有东西固定,连第一手的试错都没有,那还有人发布任务么? 还怎么收钱
当然,在有了码之后可以根据代码中的地雷规则来自行开启上帝视角。 可能有了前端之后会有办法解决这个问题?

4.3.2 start_task

开启游戏(挑战任务),通过任务编号来确定想要挑战哪个人物,同时传入的参数Coin余额必须足够,大体的代码任务与上面一致,不过别忘了维护Task当中的两个数 —— 正在挑战的人数和尝试挑战的总人数:

entry fun start_task(task_id: ID, task_list: &mut TaskList, coin: Coin<SUI>, ctx: &mut TxContext) {
    // check the task id
    assert!(task_list.contains(task_id), ENotCorrectTaskOrCompleted);

    // get task
    let task = task_list.borrow_task_mut(task_id);
    task.add_attempt();

    // update reward and earned
    task.update(coin, ctx);

    // create GameInfo
    let game_info = GameInfo {
        id: object::new(ctx),
        task_id,
        checkerboard: game::generate_empty_checkerboard(),
        hash_code: vector<u8>[],
    };
    transfer::transfer(game_info, ctx.sender());
}

4.3.3 game_click

扫雷(非挑战),通过传入的行、列,以及GameInfo来进行游戏,如果是该局游戏第一次点击,那么会生成哈希码来对应地雷位置,接着通过一些列分支条件进行判断,对游戏区域进行更新,判定游戏成功与失败,大部分都是直接调用的game模块的代码,这将在本文后续进行阐述:

entry fun game_click(mut r: u64, mut l: u64, mut game_info: GameInfo, ctx: &mut TxContext) {
    // check the r and l
    assert!(r >= 1 && r <= max_row() && l >= 1 && l <= max_list(), ENotCorrectRowOrList);

    // change the r and l to satisfy subscript
    r = r - 1;
    l = l - 1;

    // check the hash code
    if (game_info.hash_code.length() == 0) {
        let seed = ctx.epoch_timestamp_ms() % (l + r + 1);
        game_info.hash_code = game::generate_hash(seed, ctx);
    };

    // get checkerboard and hash
    let mut checkerboard = game_info.checkerboard;
    let hash = game_info.hash_code;

    // check click safe
    if (game::confirm_safe(r, l, &hash)) {
        // update checkerboard
        game::dfs(r, l, &mut checkerboard, &hash);
        // check success
        if (game::success_clear(&checkerboard, &hash)) {
            // emit event and destroy game info
            game::success_emit(0, &checkerboard);
            destroy_game_info(game_info);
        } else {
            // emit event and transfer game info for next click
            game::emit(&checkerboard);
            game_info.checkerboard = checkerboard;
            transfer::transfer(game_info, ctx.sender());
        };
    } else {
        // update checkerboard
        let square = &mut checkerboard[r][l];
        *square = char(b"x"[0]);

        // emit and destroy game info
        game::failure_emit(&checkerboard);
        destroy_game_info(game_info);
    };
}

4.3.4 game_click_task

扫雷(挑战任务),一旦挑战成功,将涉及金额转移,所以需要传入的参数比较多,但大体的代码思路与上面一致,区别的核心就是在适当的地方调用task模块当中的完成任务的函数,同时维护好正在挑战的人数和尝试挑战的总人数,当然,别忘了在挑战一个已经完成的任务时触发事件通知,并销毁玩家手中已经没有任何作用了的GameInfo

entry fun game_click_task(game_cap: &mut GameCap, mut r: u64, mut l: u64, mut game_info: GameInfo, task_list: &mut TaskList, ctx: &mut TxContext) {
    // check the task
    if (!task_list.contains(game_info.task_id)) {
        destroy_game_info(game_info);
        event::emit(PlayTooLate {loser: string(b"The bounty mission has been completed!!!")});
        return
    };

    // get the task
    let task = task_list.borrow_task_mut(game_info.task_id);

    // check the r and l
    assert!(r >= 1 && r <= max_row() && l >= 1 && l <= max_list(), ENotCorrectRowOrList);

    // change the r and l to satisfy subscript
    r = r - 1;
    l = l - 1;

    // check the hash code
    if (game_info.hash_code.length() == 0) {
        let seed = task.as_seed();
        game_info.hash_code = game::generate_hash(seed, ctx);
    };

    // get checkerboard and hash
    let mut checkerboard = game_info.checkerboard;
    let hash = game_info.hash_code;

    // check click safe
    if (game::confirm_safe(r, l, &hash)) {
        // update checkerboard
        game::dfs(r, l, &mut checkerboard, &hash);
        // check success
        if (game::success_clear(&checkerboard, &hash)) {
            // emit event, complete task and destroy game info
            game::success_emit(task.value(), &checkerboard);
            task::complete_task(game_cap, game_info.task_id, task_list, ctx);
            destroy_game_info(game_info);
        } else {
            // emit event and transfer game info for next click
            game::emit(&checkerboard);
            game_info.checkerboard = checkerboard;
            transfer::transfer(game_info, ctx.sender());
        };
    } else {
        // update checkerboard
        let square = &mut checkerboard[r][l];
        *square = char(b"x"[0]);

        // update attempt, emit and destroy game info
        task.failed_attempt();
        game::failure_emit(&checkerboard);
        destroy_game_info(game_info);
    };
}

4.4 游戏

4.4.1 emit event

一系列触发事件,核心是将用来存储扫雷区域变化的一个个Char合在一起转为String方便玩家查阅: 如果有前端这就不是问题了吧

public fun emit(vec: &vector<vector<Char>>) {
    // char => string
    // for ease of reading
    let mut checkerboard = vector<String>[];
    let mut i = 0;
    while (i < MaxRow) {
        let mut row = string(b"");
        let mut j = 0;
        while (j < MaxList) {
            row.push_char(vec[i][j]);
            j = j + 1;
        };
        checkerboard.push_back(row);
        i = i + 1;
    };
    event::emit(GameEvent {checkerboard});
}

public fun success_emit(reward: u64, vec: &vector<vector<Char>>) {
    event::emit(GameSuccessEvent {reward});
    emit(vec);
}

public fun failure_emit(vec: &vector<vector<Char>>) {
    event::emit(GameOverEvent {loser: string(b"Game Over")});
    emit(vec);
}

4.4.2 generate_empty_checkerboard

生成空的游戏区域,通过循环进行填充vector

public fun generate_empty_checkerboard(): vector<vector<Char>> {
    let c = char(b"-"[0]);

    // fill in_v in a loop
    let mut i = 0;
    let mut in_v = vector<Char>[];
    while (i < MaxList) {
        in_v.push_back(c);
        i = i + 1;
    };

    // fill out_v in a loop
    i = 0;
    let mut out_v = vector<vector<Char>>[];
    while (i < MaxRow) {
        out_v.push_back(in_v);
        i = i + 1;
    };

    // emit empty checkerboard and return
    emit(&out_v);
    out_v
}

4.4.3 generate_hash

通过hmac_sha3_256函数来生成 $\text {32}$ 个u8类型的数字,生成的内容与传入的两个参数相关,这里其中一个与上下文ctx有关,应该可以确保每个人都不一致吧~

public fun generate_hash(seed: u64, ctx: &mut TxContext): vector<u8> {
    hmac_sha3_256(&bcs::to_bytes(&seed), &ctx.fresh_object_address().to_bytes())
}

4.4.4 confirm_safe

判断某一个格子是否安全,由哈希码决定:

public fun confirm_safe(r: u64, l: u64, hash: &vector<u8>): bool {
    let pos = r * MaxList + l;
    // pos % 30 + 1 => between 1 ~ 30
    let byte = hash[pos % 30 + 1] as u64;
    // unused is hash[0] and hash[31]
    let p1 = hash[0] as u64;
    let p2 = hash[31] as u64;
    // + 2 to avoid divisor < 2
    // divisor can't be 0
    // if divisor = 1 then (0, 0) must be safe
    (byte * p1 * p2) % (pos + 2) % 2 == 0
}

4.4.5 success_clear

如果所有未点开的格子当中全是雷,那么游戏结束,玩家获得胜利:

public fun success_clear(checkerboard: &vector<vector<Char>>, hash: &vector<u8>): bool {
    let mut i = 0;
    while (i < MaxRow) {
        let mut j = 0;
        while (j < MaxList) {
            if (checkerboard[i][j] == char(b"-"[0]) && confirm_safe(i, j, hash)) {
                return false
            };
            j = j + 1;
        };
        i = i + 1;
    };
    return true
}

4.4.6 dfs

深度优先遍历,由玩家点击的方格进行深搜,每一个被掀开的格子都将计算其周围的地雷数量,如果没被任何一个地雷包围,则向四周扩散掀开格子,否则就此停下并显示对应数目:

#[allow(implicit_const_copy)]
public fun dfs(r: u64, l: u64, checkerboard: &mut vector<vector<Char>>, hash: &vector<u8>) {
    // have be clicked
    if (checkerboard[r][l] != char(b"-"[0])) {
        return
    };

    // find mines in around
    let mut cur_byte = b"0"[0];
    let mut i = 0;
    while (i <= 2) {
        let mut j = 0;
        while (j <= 2) {
            let x = r + i;
            let y = l + j;
            // out of range
            if (x <= 0 || x > MaxRow || y <= 0 || y > MaxList) {
                j = j + 1;
                continue
            };
            // add the mine number
            if (!confirm_safe(x - 1, y - 1, hash)) {
                cur_byte = cur_byte + 1;
            };
            j = j + 1;
        };
        i = i + 1;
    };

    // set checkerboard
    let square = &mut checkerboard[r][l];
    *square = char(cur_byte);

    // have mines in around
    if (cur_byte != b"0"[0]) {
        return
    };

    // expand around
    i = 0;
    while (i < 4) {
        let x = r + XDirection[i];
        let y = l + YDirection[i];
        // out of range
        if (x <= 0 || x > MaxRow || y <= 0 || y > MaxList) {
            i = i + 1;
            continue
        };
        dfs(x - 1, y - 1, checkerboard, hash);
        i = i + 1;
    };
}

开篇的#[allow(implicit_const_copy)]是为了忽略一个警告,警告内容是copyconst定义的常量vector中的数值,这是为了方便处理上下左右四个方向是设立的,此警告对代码逻辑并无影响,选择忽略。

五:链上部署及交互

5.1 发布

  • 运行命令

sui client publish --gas-budget 100000000

  • 重要信息
╭────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes                                                                                     │
├────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects:                                                                                   │
│  ┌──                                                                                               │
│  │ ObjectID: 0x5e8923e7d955754ecfd4f1735dc671a494a92b5fba2cf2269fd61b9d740c825f                    │
│  │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67                      │
│  │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 )   │
│  │ ObjectType: 0x2::package::UpgradeCap                                                            │
│  │ Version: 839131                                                                                 │
│  │ Digest: 4cfE9XhJg6yuNe1AkrMm5LXGkGH3PfSCoyYPEdbatehL                                            │
│  └──                                                                                               │
│  ┌──                                                                                               │
│  │ ObjectID: 0xd8bdf81c0b94c8eab5ddeaa3d856297e25395360950ea777f5ae5cd76cbbc032                    │
│  │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67                      │
│  │ Owner: Shared                                                                                   │
│  │ ObjectType: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::task::TaskList  │
│  │ Version: 839131                                                                                 │
│  │ Digest: DKUgMGQmfj94HXAhr5s1NoXuvJ71aDQXcxMXxNNGCp3q                                            │
│  └──                                                                                               │
│  ┌──                                                                                               │
│  │ ObjectID: 0xe75fb50542e1d1d495845cc082b0cbe99121bdb5ece7b9d340069c3b7087e43c                    │
│  │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67                      │
│  │ Owner: Shared                                                                                   │
│  │ ObjectType: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::admin::GameCap  │
│  │ Version: 839131                                                                                 │
│  │ Digest: 3ePkN293EeiSMx3h8WBpKUHGm5oFWSRwS8M68hnQEa8w                                            │
│  └──                                                                                               │
│  ┌──                                                                                               │
│  │ ObjectID: 0xfcdbfe8e54ab870eb238901c5d5eb4494a1fcab8a7c72d6c3e347b72df488f31                    │
│  │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67                      │
│  │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 )   │
│  │ ObjectType: 0x2::package::Publisher                                                             │
│  │ Version: 839131                                                                                 │
│  │ Digest: 5SBanYYmE64uxFw6fRyqtkim3JzJUwGELYJhcPKK8MQB                                            │
│  └──                                                                                               │
│ Mutated Objects:                                                                                   │
│  ┌──                                                                                               │
│  │ ObjectID: 0x01676de212960b0689245914312ac6be3b4d5cffa0cae91ef527441b894f746a                    │
│  │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67                      │
│  │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 )   │
│  │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI>                                                      │
│  │ Version: 839131                                                                                 │
│  │ Digest: GvBuHNrnparwsq3avXBoMEABJQY7k9D65aJEfAnTRyyP                                            │
│  └──                                                                                               │
│ Published Objects:                                                                                 │
│  ┌──                                                                                               │
│  │ PackageID: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86                   │
│  │ Version: 1                                                                                      │
│  │ Digest: HMbbdGMZcXreav7Suz4aAZBjPSVMt2yo7gwwXnVfoEM5                                            │
│  │ Modules: admin, game, player, task                                                              │
│  └──                                                                                               │
╰────────────────────────────────────────────────────────────────────────────────────────────────────╯
  • 环境变量
export PACKAGE=0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86
export PUBLISHER=0xfcdbfe8e54ab870eb238901c5d5eb4494a1fcab8a7c72d6c3e347b72df488f31
export GAMECAP=0xe75fb50542e1d1d495845cc082b0cbe99121bdb5ece7b9d340069c3b7087e43c
export TASKLIST=0xd8bdf81c0b94c8eab5ddeaa3d856297e25395360950ea777f5ae5cd76cbbc032

sui client gas

# output:
╭────────────────────────────────────────────────────────────────────┬────────────────────┬──────────────────╮
│ gasCoinId                                                          │ mistBalance (MIST) │ suiBalance (SUI) │
├────────────────────────────────────────────────────────────────────┼────────────────────┼──────────────────┤
│ 0x01676de212960b0689245914312ac6be3b4d5cffa0cae91ef527441b894f746a │ 930529320          │ 0.93             │
│ 0x03335f68ff3616af7e000b113c56a5ad53e8e8209784ca0a5623f70997c8d948 │ 3282792690         │ 3.28             │
╰────────────────────────────────────────────────────────────────────┴────────────────────┴──────────────────╯

export ADMINCOIN=0x03335f68ff3616af7e000b113c56a5ad53e8e8209784ca0a5623f70997c8d948

5.2 创建挑战任务

  • 运行命令

sui client call --package $PACKAGE --module task --function create_task --args $TASKLIST $ADMINCOIN 100000000 --gas-budget 100000000

  • 查看TaskList
sui client object $TASKLIST

# output:
╭───────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ objectId      │  0xd8bdf81c0b94c8eab5ddeaa3d856297e25395360950ea777f5ae5cd76cbbc032                                                                                                      │
│ version       │  28131891                                                                                                                                                                │
│ digest        │  3YfR5zdpUn2igrtqwP5x2bpsGH6pyHDzvmyqPhi4nTFJ                                                                                                                            │
│ objType       │  0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::task::TaskList                                                                                      │
│ owner         │ ╭────────┬───────────────────────────────────────╮                                                                                                                       │
│               │ │ Shared │ ╭────────────────────────┬──────────╮ │                                                                                                                       │
│               │ │        │ │ initial_shared_version │  839131  │ │                                                                                                                       │
│               │ │        │ ╰────────────────────────┴──────────╯ │                                                                                                                       │
│               │ ╰────────┴───────────────────────────────────────╯                                                                                                                       │
│ prevTx        │  6ptp6UT43swa26iZoSrDTyELYYbwt9q766UAGmwDnUJx                                                                                                                            │
│ storageRebate │  1839200                                                                                                                                                                 │
│ content       │ ╭───────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │
│               │ │ dataType          │  moveObject                                                                                                                                      │ │
│               │ │ type              │  0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::task::TaskList                                                              │ │
│               │ │ hasPublicTransfer │  false                                                                                                                                           │ │
│               │ │ fields            │ ╭──────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ │
│               │ │                   │ │ id       │ ╭────┬──────────────────────────────────────────────────────────────────────╮                                                     │ │ │
│               │ │                   │ │          │ │ id │  0xd8bdf81c0b94c8eab5ddeaa3d856297e25395360950ea777f5ae5cd76cbbc032  │                                                     │ │ │
│               │ │                   │ │          │ ╰────┴──────────────────────────────────────────────────────────────────────╯                                                     │ │ │
│               │ │                   │ │ task_ids │ ╭──────────────────────────────────────────────────────────────────────╮                                                          │ │ │
│               │ │                   │ │          │ │  0xd5e6b228ac08c7de1f6d3aba2a46d97997426a0f02e67d01d29e6d36ec060ad0  │                                                          │ │ │
│               │ │                   │ │          │ ╰──────────────────────────────────────────────────────────────────────╯                                                          │ │ │
│               │ │                   │ │ tasks    │ ╭────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ │ │
│               │ │                   │ │          │ │ type   │  0x2::table::Table<0x2::object::ID, 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::task::Task>  │ │ │ │
│               │ │                   │ │          │ │ fields │ ╭──────┬───────────────────────────────────────────────────────────────────────────────╮                             │ │ │ │
│               │ │                   │ │          │ │        │ │ id   │ ╭────┬──────────────────────────────────────────────────────────────────────╮ │                             │ │ │ │
│               │ │                   │ │          │ │        │ │      │ │ id │  0xc85fcd5de0d40deb7177583f89b2b6319d0c569826fe1e0833225096c8acea85  │ │                             │ │ │ │
│               │ │                   │ │          │ │        │ │      │ ╰────┴──────────────────────────────────────────────────────────────────────╯ │                             │ │ │ │
│               │ │                   │ │          │ │        │ │ size │  1                                                                            │                             │ │ │ │
│               │ │                   │ │          │ │        │ ╰──────┴───────────────────────────────────────────────────────────────────────────────╯                             │ │ │ │
│               │ │                   │ │          │ ╰────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │
│               │ │                   │ ╰──────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │ │
│               │ ╰───────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
╰───────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
  • 记录task_id

export TASKID=0xd5e6b228ac08c7de1f6d3aba2a46d97997426a0f02e67d01d29e6d36ec060ad0

  • 查询任务
sui client call --package $PACKAGE --module task --function query_task --args $TASKID $TASKLIST --gas-budget 100000000

# import output:
╭────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Block Events                                                                               │
├────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│  ┌──                                                                                                   │
│  │ EventID: APe9owSN7Jq6rcLq4ZsZU4wcjv8UhbMusFV2RALxMseC:0                                             │
│  │ PackageID: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86                       │
│  │ Transaction Module: task                                                                            │
│  │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67                          │
│  │ EventType: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::task::QueryTaskEvent │
│  │ ParsedJSON:                                                                                         │
│  │   ┌────────────────┬────────────────────────────────────────────────────────────────────┐           │
│  │   │ cur_reward     │ 100000000                                                          │           │
│  │   ├────────────────┼────────────────────────────────────────────────────────────────────┤           │
│  │   │ in_task        │ 0                                                                  │           │
│  │   ├────────────────┼────────────────────────────────────────────────────────────────────┤           │
│  │   │ task_id        │ 0xd5e6b228ac08c7de1f6d3aba2a46d97997426a0f02e67d01d29e6d36ec060ad0 │           │
│  │   ├────────────────┼────────────────────────────────────────────────────────────────────┤           │
│  │   │ total_attempts │ 0                                                                  │           │
│  │   └────────────────┴────────────────────────────────────────────────────────────────────┘           │
│  └──                                                                                                   │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────╯

5.3 进行挑战任务

  • 切换用户

sui client switch --address <Your Address Alias>

  • 记录Coin
sui client gas

# output:
╭────────────────────────────────────────────────────────────────────┬────────────────────┬──────────────────╮
│ gasCoinId                                                          │ mistBalance (MIST) │ suiBalance (SUI) │
├────────────────────────────────────────────────────────────────────┼────────────────────┼──────────────────┤
│ 0x516586df0c5e9c9567696840981f720d64335ac6e8ad409f4ba4843b8dc2274a │ 100                │ 0.00             │
│ 0x82ec01655d746b42dba5c5951841472e5d1715e74238a5ef8e39d0b0566dc3be │ 996215577          │ 0.99             │
│ 0x8ef6503cb330c4114bc7995a403adf4015190d8effc02504fd849377caa6499b │ 963358100          │ 0.96             │
│ 0xad3fa2545f5db01bd4d349871df5af4d6de913600e7e3e032d5229c006d35851 │ 100                │ 0.00             │
│ 0xcb24b30fe196f4f2ca6d5f8d87a273bf168f7f86f6b7ae3f1f20fc5cf447e557 │ 990920960          │ 0.99             │
│ 0xe4f2d7831241583d534271d8d777d7558290124779e98e03b059a2fe108d37b0 │ 989                │ 0.00             │
╰────────────────────────────────────────────────────────────────────┴────────────────────┴──────────────────╯

export PLAYERCOIN=0xcb24b30fe196f4f2ca6d5f8d87a273bf168f7f86f6b7ae3f1f20fc5cf447e557
  • 开始游戏

sui client call --package $PACKAGE --module player --function start_task --args $TASKID $TASKLIST $PLAYERCOIN --gas-budget 100000000

  • 重要输出
╭───────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Block Events                                                                          │
├───────────────────────────────────────────────────────────────────────────────────────────────────┤
│  ┌──                                                                                              │
│  │ EventID: H1gc93rXVNqqcBw9ixSvYycw2cGqEHiaJoDvKRJotRkE:0                                        │
│  │ PackageID: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86                  │
│  │ Transaction Module: player                                                                     │
│  │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b                     │
│  │ EventType: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::game::GameEvent │
│  │ ParsedJSON:                                                                                    │
│  │   ┌──────────────┬────────────┐                                                                │
│  │   │ checkerboard │ ---------- │                                                                │
│  │   │              ├────────────┤                                                                │
│  │   │              │ ---------- │                                                                │
│  │   │              ├────────────┤                                                                │
│  │   │              │ ---------- │                                                                │
│  │   │              ├────────────┤                                                                │
│  │   │              │ ---------- │                                                                │
│  │   │              ├────────────┤                                                                │
│  │   │              │ ---------- │                                                                │
│  │   └──────────────┴────────────┘                                                                │
│  └──                                                                                              │
╰───────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes                                                                                                                             │
├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects:                                                                                                                           │
│  ┌──                                                                                                                                       │
│  │ ObjectID: 0x2359ffba7bbad6a1297a689973ab12be92aea5f6bc56ceb6e820057c9bc312c9                                                            │
│  │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b                                                              │
│  │ Owner: Account Address ( 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b )                                           │
│  │ ObjectType: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::player::GameInfo                                        │
│  │ Version: 28131892                                                                                                                       │
│  │ Digest: FiJNKn7F4tHPLjXqZ5CLe2TimgYopgVYcd5KQrGwwBpD                                                                                    │
│  └──                                                                                                                                       │
│ Mutated Objects:                                                                                                                           │
│  ┌──                                                                                                                                       │
│  │ ObjectID: 0x069127c1917ba074790e6bafc5d396fedb9ea2b082adbb0aa23a6aef2b1a1d52                                                            │
│  │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b                                                              │
│  │ Owner: Object ID: ( 0xc85fcd5de0d40deb7177583f89b2b6319d0c569826fe1e0833225096c8acea85 )                                                │
│  │ ObjectType: 0x2::dynamic_field::Field<0x2::object::ID, 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::task::Task>  │
│  │ Version: 28131892                                                                                                                       │
│  │ Digest: 8Y2wyvyFYbaQ5csxsPRS9CgYjUz4L3gVaQ9zMHjEagWH                                                                                    │
│  └──                                                                                                                                       │
│  ┌──                                                                                                                                       │
│  │ ObjectID: 0x82ec01655d746b42dba5c5951841472e5d1715e74238a5ef8e39d0b0566dc3be                                                            │
│  │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b                                                              │
│  │ Owner: Account Address ( 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b )                                           │
│  │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI>                                                                                              │
│  │ Version: 28131892                                                                                                                       │
│  │ Digest: DQZQbuQ2TwmrTVGWh6ePBtk3A1DXGdMHZTLUSQvu1Uh6                                                                                    │
│  └──                                                                                                                                       │
│  ┌──                                                                                                                                       │
│  │ ObjectID: 0xcb24b30fe196f4f2ca6d5f8d87a273bf168f7f86f6b7ae3f1f20fc5cf447e557                                                            │
│  │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b                                                              │
│  │ Owner: Account Address ( 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b )                                           │
│  │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI>                                                                                              │
│  │ Version: 28131892                                                                                                                       │
│  │ Digest: 8RfS2pfuFQdXVa1tdPMmnPWwnnRD2te67uGYc9Wsn4Q5                                                                                    │
│  └──                                                                                                                                       │
│  ┌──                                                                                                                                       │
│  │ ObjectID: 0xd8bdf81c0b94c8eab5ddeaa3d856297e25395360950ea777f5ae5cd76cbbc032                                                            │
│  │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b                                                              │
│  │ Owner: Shared                                                                                                                           │
│  │ ObjectType: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::task::TaskList                                          │
│  │ Version: 28131892                                                                                                                       │
│  │ Digest: BtVRqM9uXYRYwCpPf2oYfXrWv7o2UCdaHdRqXU7oqpie                                                                                    │
│  └──                                                                                                                                       │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
  • 记录GameInfo

export GAMEINFO=0x2359ffba7bbad6a1297a689973ab12be92aea5f6bc56ceb6e820057c9bc312c9

  • 点击坐标 $\text {(3,\ 5)}$

sui client call --package $PACKAGE --module player --function game_click_task --args $GAMECAP 3 5 $GAMEINFO $TASKLIST --gas-budget 100000000

  • 游戏进程
╭───────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Block Events                                                                          │
├───────────────────────────────────────────────────────────────────────────────────────────────────┤
│  ┌──                                                                                              │
│  │ EventID: A3iF7tcE28cPzfhQFCBt1aBYXnkF9cEAcPdQAwoMkT1G:0                                        │
│  │ PackageID: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86                  │
│  │ Transaction Module: player                                                                     │
│  │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b                     │
│  │ EventType: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::game::GameEvent │
│  │ ParsedJSON:                                                                                    │
│  │   ┌──────────────┬────────────┐                                                                │
│  │   │ checkerboard │ ---------- │                                                                │
│  │   │              ├────────────┤                                                                │
│  │   │              │ ---------- │                                                                │
│  │   │              ├────────────┤                                                                │
│  │   │              │ ----3----- │                                                                │
│  │   │              ├────────────┤                                                                │
│  │   │              │ ---------- │                                                                │
│  │   │              ├────────────┤                                                                │
│  │   │              │ ---------- │                                                                │
│  │   └──────────────┴────────────┘                                                                │
│  └──                                                                                              │
╰───────────────────────────────────────────────────────────────────────────────────────────────────╯
  • 根据游戏区域继续选择点击 $\text {(2,\ 9)}$

sui client call --package $PACKAGE --module player --function game_click_task --args $GAMECAP 2 9 $GAMEINFO $TASKLIST --gas-budget 100000000

  • 游戏进程
╭───────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Block Events                                                                          │
├───────────────────────────────────────────────────────────────────────────────────────────────────┤
│  ┌──                                                                                              │
│  │ EventID: BTgdBFY619JsUoq2EQvxjs3bMhmgzR5bpNkpg6QoXVNc:0                                        │
│  │ PackageID: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86                  │
│  │ Transaction Module: player                                                                     │
│  │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b                     │
│  │ EventType: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::game::GameEvent │
│  │ ParsedJSON:                                                                                    │
│  │   ┌──────────────┬────────────┐                                                                │
│  │   │ checkerboard │ ---------- │                                                                │
│  │   │              ├────────────┤                                                                │
│  │   │              │ --------3- │                                                                │
│  │   │              ├────────────┤                                                                │
│  │   │              │ ----3----- │                                                                │
│  │   │              ├────────────┤                                                                │
│  │   │              │ ---------- │                                                                │
│  │   │              ├────────────┤                                                                │
│  │   │              │ ---------- │                                                                │
│  │   └──────────────┴────────────┘                                                                │
│  └──                                                                                              │
╰───────────────────────────────────────────────────────────────────────────────────────────────────╯
  • 重复上述操作(不带脑子的),先点了 $\text {(1,\ 1)}$,再点了 $\text {(5,\ 10)}$,导致游戏失败
╭───────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Block Events                                                                              │
├───────────────────────────────────────────────────────────────────────────────────────────────────────┤
│  ┌──                                                                                                  │
│  │ EventID: FecsgeihJicnn7n1A9CEmwCj97HDwtyS1zzgzbiWNjRS:0                                            │
│  │ PackageID: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86                      │
│  │ Transaction Module: player                                                                         │
│  │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b                         │
│  │ EventType: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::game::GameOverEvent │
│  │ ParsedJSON:                                                                                        │
│  │   ┌───────┬───────────┐                                                                            │
│  │   │ loser │ Game Over │                                                                            │
│  │   └───────┴───────────┘                                                                            │
│  └──                                                                                                  │
│  ┌──                                                                                                  │
│  │ EventID: FecsgeihJicnn7n1A9CEmwCj97HDwtyS1zzgzbiWNjRS:1                                            │
│  │ PackageID: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86                      │
│  │ Transaction Module: player                                                                         │
│  │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b                         │
│  │ EventType: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::game::GameEvent     │
│  │ ParsedJSON:                                                                                        │
│  │   ┌──────────────┬────────────┐                                                                    │
│  │   │ checkerboard │ 00002----- │                                                                    │
│  │   │              ├────────────┤                                                                    │
│  │   │              │ 1121----3- │                                                                    │
│  │   │              ├────────────┤                                                                    │
│  │   │              │ ----3----- │                                                                    │
│  │   │              ├────────────┤                                                                    │
│  │   │              │ ---------- │                                                                    │
│  │   │              ├────────────┤                                                                    │
│  │   │              │ ---------x │                                                                    │
│  │   └──────────────┴────────────┘                                                                    │
│  └──                                                                                                  │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────╯
  • 查询任务
sui client call --package $PACKAGE --module task --function query_task --args $TASKID $TASKLIST --gas-budget 100000000

# output:
╭────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Block Events                                                                               │
├────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│  ┌──                                                                                                   │
│  │ EventID: BbXxmWmZJjCgB5MfbwDYZCv2X66gRgV54h4L9HuKNB89:0                                             │
│  │ PackageID: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86                       │
│  │ Transaction Module: task                                                                            │
│  │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b                          │
│  │ EventType: 0x2b772f60f0794e23718d47ea32b9d61eb29b79dc45f026e31985575b8edd5a86::task::QueryTaskEvent │
│  │ ParsedJSON:                                                                                         │
│  │   ┌────────────────┬────────────────────────────────────────────────────────────────────┐           │
│  │   │ cur_reward     │ 125000000                                                          │           │
│  │   ├────────────────┼────────────────────────────────────────────────────────────────────┤           │
│  │   │ in_task        │ 0                                                                  │           │
│  │   ├────────────────┼────────────────────────────────────────────────────────────────────┤           │
│  │   │ task_id        │ 0xd5e6b228ac08c7de1f6d3aba2a46d97997426a0f02e67d01d29e6d36ec060ad0 │           │
│  │   ├────────────────┼────────────────────────────────────────────────────────────────────┤           │
│  │   │ total_attempts │ 1                                                                  │           │
│  │   └────────────────┴────────────────────────────────────────────────────────────────────┘           │
│  └──                                                                                                   │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────╯

5.4 提现

用开启普通游戏给GameCap送 $\text {666}$( 绝对不是扫雷太难了才不做任务 ),通过命令提现并查看余额,当然,提现的时候要切换到发布者账户,否则会报错:

sui client call --package $PACKAGE --module admin --function withdraw --args $PUBLISHER $GAMECAP --gas-budget 100000000

sui client gas

# output:
╭────────────────────────────────────────────────────────────────────┬────────────────────┬──────────────────╮
│ gasCoinId                                                          │ mistBalance (MIST) │ suiBalance (SUI) │
├────────────────────────────────────────────────────────────────────┼────────────────────┼──────────────────┤
│ 0x01676de212960b0689245914312ac6be3b4d5cffa0cae91ef527441b894f746a │ 923479812          │ 0.92             │
│ 0x03335f68ff3616af7e000b113c56a5ad53e8e8209784ca0a5623f70997c8d948 │ 3182792690         │ 3.18             │
│ 0xf0d1ea4828fe7391b41b2b07cc8c4c5fd1831aee6b6a4e5195b236dea20fbde4 │ 666                │ 0.00             │
╰────────────────────────────────────────────────────────────────────┴────────────────────┴──────────────────╯

5.5 其它

由于篇幅有限,且其它大部分逻辑都是类似的,这里就不再赘述了,大家可以自行体验。

上面的内容发布在测试网($\mathit {testnet}$),据说一般不会清理这上面的内容,所以大家可以尽情游玩,如果想要实际的资产收入,下面列举了在主网发布的相关信息。

六:主网相关信息

╭────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes                                                                                     │
├────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects:                                                                                   │
│  ┌──                                                                                               │
│  │ ObjectID: 0x013207a4563b3cd4f5571210c6137b88e6b49632c55e1f973273a89bd394189a                    │
│  │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67                      │
│  │ Owner: Shared                                                                                   │
│  │ ObjectType: 0x61fae5877c2d1a8005850bdcc4f7af8e9db748bd8934fd267cb962b0a2682cea::task::TaskList  │
│  │ Version: 93823811                                                                               │
│  │ Digest: bn9MjEfoPmQF5dzQ8x4hqYfDSXdzQhaFGEB4Bj9TVun                                             │
│  └──                                                                                               │
│  ┌──                                                                                               │
│  │ ObjectID: 0x4149443de1b23dbe2d3ff3af3e4386d21b702fe0e9b98c6da328a779c8bc3b64                    │
│  │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67                      │
│  │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 )   │
│  │ ObjectType: 0x2::package::Publisher                                                             │
│  │ Version: 93823811                                                                               │
│  │ Digest: 4185sDwsbBUfqwH7UdNRNgeUV3UYcXxeacDbgRxMDPuG                                            │
│  └──                                                                                               │
│  ┌──                                                                                               │
│  │ ObjectID: 0x4f4b954324e48fa3dfcce7fc9122b8b8f2529161d900d603d58dfbba697ad2b9                    │
│  │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67                      │
│  │ Owner: Shared                                                                                   │
│  │ ObjectType: 0x61fae5877c2d1a8005850bdcc4f7af8e9db748bd8934fd267cb962b0a2682cea::admin::GameCap  │
│  │ Version: 93823811                                                                               │
│  │ Digest: 89MaCQUw3fQi2Mk3XDmesieAiiAg6hheZBPVTT7qxzFf                                            │
│  └──                                                                                               │
│  ┌──                                                                                               │
│  │ ObjectID: 0x7d138d46e14b53065ea2b81118a13a9d5328bc3e7fefbb21a61ba33bc85ef33c                    │
│  │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67                      │
│  │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 )   │
│  │ ObjectType: 0x2::package::UpgradeCap                                                            │
│  │ Version: 93823811                                                                               │
│  │ Digest: 2mdqWWJ6rSEksAakRtrvqbjAXVRUKRDLuy4GWndpXyNY                                            │
│  └──                                                                                               │
│ Mutated Objects:                                                                                   │
│  ┌──                                                                                               │
│  │ ObjectID: 0x5bd3822d01aa5aff68b8079b8a0f41563d423d8f5993daaddf338533a0735ab5                    │
│  │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67                      │
│  │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 )   │
│  │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI>                                                      │
│  │ Version: 93823811                                                                               │
│  │ Digest: 3XrAe2vgxnVzhtm4QCErADLLgx5wyYXFtM3J9bxsEYT5                                            │
│  └──                                                                                               │
│ Published Objects:                                                                                 │
│  ┌──                                                                                               │
│  │ PackageID: 0x61fae5877c2d1a8005850bdcc4f7af8e9db748bd8934fd267cb962b0a2682cea                   │
│  │ Version: 1                                                                                      │
│  │ Digest: Et5czEYSphmx1ZiBhhmYUASbuXvc3WWVDh7Md662q4Xq                                            │
│  │ Modules: admin, game, player, task                                                              │
│  └──                                                                                               │
╰────────────────────────────────────────────────────────────────────────────────────────────────────╯

export PACKAGE=0x61fae5877c2d1a8005850bdcc4f7af8e9db748bd8934fd267cb962b0a2682cea
export UPGRADECAP=0x7d138d46e14b53065ea2b81118a13a9d5328bc3e7fefbb21a61ba33bc85ef33c
export PUBLISHER=0x4149443de1b23dbe2d3ff3af3e4386d21b702fe0e9b98c6da328a779c8bc3b64
export GAMECAP=0x4f4b954324e48fa3dfcce7fc9122b8b8f2529161d900d603d58dfbba697ad2b9
export TASKLIST=0x013207a4563b3cd4f5571210c6137b88e6b49632c55e1f973273a89bd394189a

欢迎大家来主网玩,完整的代码也可以点击这里查看。

七:加入组织,共同进步!