事件

事件是从合约发出数据的一种方式。所有事件都必须在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()
                        }
                    )
                );
        }
    }
}

Voyager 上访问 合约 或在 Remix 中尝试它。

Last change: 2023-10-12, commit: 90aa7c0