Events

Events are a way to emit data from a contract. All events must be defined in the Event enum, which must be annotated with the #[event] attribute. An event is defined as struct that derives the #[starknet::Event] trait. The fields of that struct correspond to the data that will be emitted. An event can be indexed for easy and fast access when querying the data at a later time. Events data can be indexed by adding a #[key] attribute to a field member.

Here's a simple example of a contract using events that emit an event each time a counter is incremented by the "increment" function:

#[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()
                        }
                    )
                );
        }
    }
}

Visit contract on Voyager or play with it in Remix.

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