Run the Example
First go through the Setup process to get your development environment configured, then clone themain branch of the soroban-examples repository:
events directory, and use cargo test.
Code
events/src/lib.rs
How it Works
This example contract extends the increment example by publishing an event each time the counter is incremented. Contract events let contracts emit information about what their contract is doing. Contracts can publish events creating a definedstruct and publishing it to the smart contract environments.
First, the #[contractevent] struct must be defined
Event Topics
Topics can be defined either statically or dynamically. In the sample code two static topics are used, which will be of theSymbol type: COUNTER and increment.
snake_case name will be the first topic. For example, the following event will have two topics: the Symbol “increment”, followed by an Address.
Event Data
An event also contains a data object of any value or type including types defined by contracts using#[contracttype]. In the example the data is the u32 count. The data_format = "single-value" tells the event to publish the data alone, with no surrounding data structure.
struct. The data_format can also be specified as vec or single-value. Again, please refer to the Rust SDK documentation for more details.
Publishing
Publishing an event is done by calling thepublish function on the created event struct. The function returns nothing on success, and panics on failure. Possible failure reasons can include malformed inputs (e.g. topic count exceeds limit) and running over the resource budget (TBD). Once successfully published, the new event will be available to applications consuming the events.
Tests
Open theevents/src/test.rs file to follow along.
events/src/test.rs
Env, which is the Soroban environment that the contract will run in.
impl block that is annotated with the #[contractimpl] attribute have a corresponding function generated in a generated client type. The client type will be named the same as the contract type with Client appended. For example, in our contract the contract type is IncrementContract, and the client is named IncrementContractClient.
env.events().all() returns a ContractEvents value containing all the events published by the last contract invocation, which can be compared in a few different ways.
The event struct defined with #[contractevent] can be converted to its XDR form with to_xdr and compared directly, which is the most convenient way to assert on events when the contract defines them using the macro.
filter_by_contract narrows the events down to those emitted by a specific contract address, which is useful when a contract invocation calls into other contracts that also emit events.
(contract_id, topics, data), which is useful when the contract does not define its events using the #[contractevent] macro.
Build the Contract
To build the contract, use thestellar contract build command.
.wasm file should be outputted in the target directory:
Run the Contract
If you havestellar-cli installed, you can deploy the contract and invoke its functions.
Deploy
- macOS/Linux
- Windows (PowerShell)
Invoke
- macOS/Linux
- Windows (PowerShell)
Symbol, and the data object containing the u32.