事件
事件是从合约发出数据的一种方式。所有事件都必须在Event
枚举中定义,该枚举必须使用#[event]
属性进行注释。
事件被定义为派生#[starknet::Event]
特征的结构。该结构的字段对应于将要发出的数据。可以对事件编制索引,以便在以后查询数据时轻松快速地访问。可以通过向字段成员添加#[key]
属性来索引事件数据。
下面是合约使用事件的简单示例,这些事件在每次计数器通过“increment”函数递增时发出一个事件:
#[starknet::interface]
trait IEventCounter<TContractState> {
fn increment(ref self: TContractState);
}
#[starknet::contract]
mod EventCounter {
use starknet::{get_caller_address, ContractAddress};
#[storage]
struct Storage {
// Counter value
counter: u128,
}
#[event]
#[derive(Drop, starknet::Event)]
// The event enum must be annotated with the `#[event]` attribute.
// It must also derive the `Drop` and `starknet::Event` traits.
enum Event {
CounterIncreased: CounterIncreased,
UserIncreaseCounter: UserIncreaseCounter
}
// By deriving the `starknet::Event` trait, we indicate to the compiler that
// this struct will be used when emitting events.
#[derive(Drop, starknet::Event)]
struct CounterIncreased {
amount: u128
}
#[derive(Drop, starknet::Event)]
struct UserIncreaseCounter {
// The `#[key]` attribute indicates that this event will be indexed.
#[key]
user: ContractAddress,
new_value: u128,
}
#[abi(embed_v0)]
impl EventCounter of super::IEventCounter<ContractState> {
fn increment(ref self: ContractState) {
let mut counter = self.counter.read();
counter += 1;
self.counter.write(counter);
// Emit event
self.emit(Event::CounterIncreased(CounterIncreased { amount: 1 }));
self
.emit(
Event::UserIncreaseCounter(
UserIncreaseCounter {
user: get_caller_address(), new_value: self.counter.read()
}
)
);
}
}
}