创建一个 Event
在Substrate上,Transactions 的处理方式与 Ethereum 上的处理方式不同。即使 transaction 可能已经完成,但并不一定意味着该 transaction 执行的函数完全成功。
3.1 声明一个 Event
为了知道执行函数是否完全成功,我们应该在函数结束时发出一个 Event
,不仅要报告成功,还要告诉 "off-chain world" 某些特定的状态转换已经发生了。
以下是声明 event 的示例:
decl_event!( pub enum Event<T> where <T as system::Trait>::AccountId, <T as system::Trait>::Balance { MyEvent(u32, Balance), MyOtherEvent(Balance, AccountId), } );
同样,如果我们想要使用一些自定义 Substrate 类型,我们需要将泛型集成到我们的 event 定义中。
3.2 添加一个 Event 类型
decl_event!
宏将生成一个新的 Event
类型,你需要在 module 中暴露出它。这种类型需要继承一些 traits,如下所示:
pub trait Trait: balances::Trait { type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>; }
3.3 Depositing an Event
为了在 runtime 中使用 event,你需要添加一个存储这些 events 的函数。由于这是 runtime 开发中的常见模式,因此 decl_module!
宏可以在你的 module 中自动添加一个默认实现。
只需在 module 中添加一个新函数,如下所示:
fn deposit_event<T>() = default;
如果你的 event 不使用任何泛型(例如只是 Rust 原始类型),你应该省略 <T>
,如下所示:
fn deposit_event() = default;
3.4 调用 deposit_event()
现在你已经在 module 中构建了一些东西,你可能想要在函数结束时生成一个 event。
这样做相对简单,你只需提供与 Event
定义中类型相同的值:
let my_value = 1337; let my_balance = <T::Balance as As<u64>>::sa(1337); Self::deposit_event(RawEvent::MyEvent(my_value, my_balance));
3.5 更新 lib.rs
来包含 Events
让 runtime 编译成功的最后一步是更新 lib.rs
文件以包含你定义的新 Event
类型。
在你的 module 的 Trait
实现中,你需要包括:
// `lib.rs` ... impl mymodule::Trait for Runtime { type Event = Event; } ...
最后,你还需要在 construct_runtime!
宏中包含 Event
或Event<T>
类型到你的 module 定义中。你包含哪一个取决于你的 event 是否使用了泛型。
// `lib.rs` ... construct_runtime!( pub enum Runtime with Log(InternalLog: DigestItem<Hash, Ed25519AuthorityId>) where Block = Block, NodeBlock = opaque::Block, InherentData = BasicInherentData { ... MyModule: mymodule::{Module, Call, Storage, Event<T>}, } ); ...
3.6 示例:更新 module 以支持 event
1.加入引用decl_event
记得更新lib.rs来包含Events
让 runtime 编译成功的最后一步是更新 lib.rs
文件以包含你定义的新 Event
类型。
在你的 module 的 Trait
实现中,你需要包括:
最后,你还需要在 construct_runtime!
宏中包含 Event
或Event<T>
类型到你的 module 定义中。你包含哪一个取决于你的 event 是否使用了泛型。
2. 声明一个 Event
3. 添加一个 Event 类型
4.Depositing an Event
为了在 runtime 中使用 event,你需要添加一个存储这些 events 的函数。由于这是 runtime 开发中的常见模式,因此 decl_module!
宏可以在你的 module 中自动添加一个默认实现。
只需在 module 中添加一个新函数,如下所示:
5 调用deposit_event()
现在你已经在 module 中构建了一些东西,你可能想要在函数结束时生成一个 event。
这样做相对简单,你只需提供与 Event
定义中类型相同的值: