Skip to main content

What are events and why are they useful?

Smart Contract Events in Solidity allow developers to emit logs containing indexed data, extending the EVM’s logging capabilities to offchain applications. Offchain services can subscribe to and listen for these events via the RPC interface. Events are used extensively in Ethereum for two main reasons:
  1. They are the cheapest way to “store” data in Ethereum, which is very useful for bigger data loads.
  2. They allow for offchain complex interactions like indexing, filtering, querying, etc.
However, event data is unusable onchain by definition. Solidity cannot query event data internally. Currently, the workflow for smart contracts reacting to events is:
  • Emit an event.
  • Subscribe and listen to the event offchain.
  • Initiate an onchain transaction with relevant data in response to the emitted event.

So why use Steel Events?

Allowing smart contracts to verifiably query event data directly onchain significantly streamlines this workflow, unlocking previously impossible trustless applications. Steel Events enables smart contracts to verify and directly use Ethereum events onchain, eliminating the need for complex event middleware. Leveraging the same blockhash trust anchor and Steel Commitments scheme, Steel Events ensures provable event data inherits Steel’s robust security guarantees, unlocking powerful new use cases:
  • Trustless On-Chain Reactions: Execute complex logic based on verified aggregations or event patterns (e.g., swap volumes, user activity), without prohibitive gas costs.
  • Secure Bridging of Off-Chain Logic: Bring existing offchain analytics safely onchain, without modifying your smart contract logic or storage patterns.
  • Cross-Contract Interaction via Events: Enable Contract B to verifiably react to Contract A’s events, even if A has no direct query API.
This unlocks sophisticated, trustless interactions using Ethereum’s inexpensive event logs as secure, verifiable onchain inputs.

How does Steel Events work?

Steel event syntax allows the developer to query events directly within their guest program. The Steel guest program can specify the event to query using alloy’s sol! Macro. For example, we can specify the signature for the ERC20 Transfer event:
To query all Transfer events in a single block for a specific token contract, we first must specify the contract address:
This allows Steel in the host preflight call to populate the EVM environment, within the guest program, with the correct contract data. This EVM environment, in tandem with Merkle storage proofs, is used to verify all relevant data within the guest, and commit the data needed, to verify the blockhash onchain, to the journal. To read about this flow in detail, please refer to How Does Steel Work.

Guest Program

Example Guest Program The guest program requires the usual Steel workflow:
  1. Read the input from the host environment: let input: EthEvmInput = env::read();
  2. Convert the input into an EvmEnv for execution, with the correct chain configuration: let env = input.into_env(&ETH_SEPOLIA_CHAIN_SPEC);
  3. Save the blockhash for the block where we are querying the event: let event_block_hash = env.header().seal();
After which, we are ready to query all Transfer events in a single block for the specified CONTRACT:
To grab the total USDT transferred across all the events in the pinned block, we iterate through each log, grab the value and sum them all into one uint256 type: total_usdt
And finally, we commit this sum, the commitment data, and the event block hash to the journal, ready for validation onchain:

Host Program

Example Host Program The host program preflights the event query using the Event::preflight method. This populates the EVM environment with the relevant data ready for verification in the guest.

Running the Events Example

To get started with events, you can use the Steel Events example:
To run the example:
This should give you something like this: