Skip to main content

事件 (Events)

事件是用於通知鏈外監聽器關於鏈上事件的一種方式。它們用於發送有關交易的附加資訊,這些資訊不存儲在鏈上,因此無法在鏈上存取。事件由位於 Sui 框架 中的 sui::event 模組發送。

任何具有 copydrop 能力的自定義類型都可以作為事件發送。Sui 校驗器 (Verifier) 要求該類型必須是模組內部的。

module sui::event;

/// 發送一個自定義 Move 事件,將資料傳送到鏈外。
/// 用於建立自定義索引並以最適合特定應用程式的方式追蹤鏈上活動。
/// 類型 `T` 是索引事件的主要方式,可以包含 phantom 參數,
/// 例如 `emit(MyEvent<phantom T>)`。
public native fun emit<T: copy + drop>(event: T);

發送事件 (Emitting Events)

事件使用 sui::event 模組中的 emit 函式發送。該函式接收一個參數 — 要發送的事件。事件資料按值傳遞。

module book::events;

use sui::coin::Coin;
use sui::sui::SUI;
use sui::event;

/// 可購買的項目。
public struct Item has key { id: UID }

/// 購買項目時發出的事件。包含項目的 ID 和
/// 購買價格。
public struct ItemPurchased has copy, drop {
item: ID,
price: u64
}

/// 執行項目購買的市場函式。
public fun purchase(coin: Coin<SUI>, ctx: &mut TxContext) {
let item = Item { id: object::new(ctx) };

// 建立 `ItemPurchased` 的實例並將其傳遞給 `event::emit`。
event::emit(ItemPurchased {
item: object::id(&item),
price: coin.value()
});

// 省略實現的其餘部分以保持範例簡潔。
abort
}

Sui 校驗器要求傳遞給 emit 函式的類型必須是 模組內部的 (internal to the module)。因此,發送來自另一個模組的類型將導致編譯錯誤。原始類型雖然符合 copydrop 的要求,但不允許作為事件發送。

事件結構 (Event Structure)

事件是交易結果的一部分,存儲在 交易效果 (transaction effects) 中。因此,它們原生具有 sender 欄位,即發送交易的地址。因此,無需在事件中添加「sender」欄位。同樣地,事件元資料包含時間戳。但請注意,時間戳是相對於節點的,在不同節點之間可能會略有不同。