Back to Learn
events
Events
Emit events from your contracts for off-chain tracking and indexing.
Events
Events allow contracts to communicate with the outside world. They're stored in transaction logs and can be indexed for efficient querying.
Defining Events
Use the sol! macro from alloy_sol_types:
`` use alloy_sol_types::sol; sol! { event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 value); }rust
`
Emitting Events
Use evm::log to emit:
` use stylus_sdk::evm; evm::log(Transfer { from, to, amount });rust
``
Indexed Parameters
- Up to 3 indexed parameters per event
- Indexed params enable efficient filtering
- Non-indexed params stored in data
Code Example
#![cfg_attr(not(feature = "export-abi"), no_main)]
extern crate alloc;
use stylus_sdk::prelude::*;
use stylus_sdk::{evm, msg};
use stylus_sdk::storage::StorageMap;
use alloy_primitives::{Address, U256};
use alloy_sol_types::sol;
// Define events
sol! {
event Transfer(address indexed from, address indexed to, uint256 amount);
event Deposit(address indexed user, uint256 amount);
}
#[storage]
#[entrypoint]
pub struct Token {
balances: StorageMap<Address, U256>,
}
#[public]
impl Token {
#[payable]
pub fn deposit(&mut self) {
let sender = msg::sender();
let amount = msg::value();
let balance = self.balances.get(sender);
self.balances.insert(sender, balance + amount);
// Emit event
evm::log(Deposit { user: sender, amount });
}
pub fn transfer(&mut self, to: Address, amount: U256) -> bool {
let sender = msg::sender();
let balance = self.balances.get(sender);
if balance >= amount {
self.balances.insert(sender, balance - amount);
self.balances.insert(to, self.balances.get(to) + amount);
evm::log(Transfer { from: sender, to, amount });
true
} else {
false
}
}
}