发布事件

Sui 中的另一个重要概念是事件。 事件可以用于跟踪链上的活动,这在开发人员希望跟踪用户在特定合约交互(例如 NFT 铸造)期间的行为时特别有价值。

在我们的 Move Castle 游戏中,建造城堡的行为类似于铸造过程。因此,记录和跟踪此类事件非常重要。

在发布事件之前,你必须定义其结构,在 castle.move 中:

/// Event - castle built
public struct CastleBuilt has copy, drop {
    id: ID,
    owner: address,
}

然后使用 event::emit 来发布事件,在 build_castle 函数中:

use sui::event;

entry fun build_castle(...) {
    ...
    // 将城堡对象转移给拥有者。
    let owner = tx_context::sender(ctx);
    transfer::public_transfer(castle, owner);
    event::emit(CastleBuilt{id: id, owner: owner});
}

很简单,对吧?在 Sui testnet 上试试。

Sui 客户端 CLI 输出:

CLI_output

Sui explorer 交易页面:

Explorer

同样地,在战斗结束时发布战斗结果。在 battle.move 中添加事件结构:

/// Battle event
public struct CastleBattleLog has store, copy, drop {
    attacker: ID,
    winner: ID,
    loser: ID,
    winner_soldiers_lost: u64,
    loser_soldiers_lost: u64,
    reparation_economic_power: u64,
    battle_time: u64,
    reparation_end_time: u64
}

battle 函数的末尾发布事件:

use sui::event;

entry fun battle(castle: &Castle, clock: &Clock, game_store: &mut GameStore, ctx: &mut TxContext) {
    ...
    // 6. 发布事件
    event::emit(CastleBattleLog {
        attacker: attacker_id,
        winner: winner_id,
        loser: loser_id,
        winner_soldiers_lost: winner_soldiers_lost,
        loser_soldiers_lost: loser_soldiers_lost,
        reparation_economic_power: reparation_economic_power,
        battle_time: current_timestamp,
        reparation_end_time: current_timestamp + BATTLE_LOSER_ECONOMIC_PENALTY_TIME
    });
}