事件 (Events)
事件是用於通知鏈外監聽器關於鏈上事件的一種方式。它們用於發送有關交易的附加資訊,這些資訊不存儲在鏈上,因此無法在鏈上存取。事件由位於 Sui 框架 中的 sui::event 模組發送。
任何具有 copy 和 drop 能力的自定義類型都可以作為事件發送。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)。因此,發送來自另一個模組的類型將導致編譯錯誤。原始類型雖然符合 copy 和 drop 的要求,但不允許作為事件發送。
事件結構 (Event Structure)
事件是交易結果的一部分,存儲在 交易效果 (transaction effects) 中。因此,它們原生具有 sender 欄位,即發送交易的地址。因此,無需在事件中添加「sender」欄位。同樣地,事件元資料包含時間戳。但請注意,時間戳是相對於節點的,在不同節點之間可能會略有不同。