CAP: 0046-08 (formerly 0056)
Title: Smart Contract Events
Working Group:
Owner: Siddharth Suresh <@sisuresh>
Authors:
Consulted:
Status: Final
Created: 2022-06-29
Discussion:
Protocol version: 20
This CAP proposes an update to TransactionMeta along with new host functions
to allow for contracts to write data to the meta that can be consumed by
downstream systems.
Contract writers will need a way to emit information about what their specific contracts are doing. Downstream consumers of these new messages can also push these to subscribers, allowing users to listen to specific messages.
This CAP is aligned with the following Stellar Network Goals:
- The Stellar Network should make it easy for developers of Stellar projects to create highly usable products
This CAP provides host functions for contracts to write events that will be put
into TransactionMeta. It also provides a way to cryptographically verify the events.
We introduced a TransactionMetaV3, which has an optional
SorobanTransactionMeta struct that should be set for Soroban transactions.
This contains a events vector of ContractEvent, which will contain the
events emitted by the host and contract.
TransactionMeta is not hashed into the ledger, which is an issue because the
events can't be cryptographically verified, and tests that replay historical
transactions will not catch instances where the events emitted have changed. To
fix this issue, InvokeHostFunctionOp returns the SHA-256 hash of
InvokeHostFunctionSuccessPreImage, which contains the SCVal return value of
the top level contract call, and the vector of events emitted. This makes the
events part of the protocol.
The host can also emit diagnostic events, which are not part of the protocol and
do not count towards metering and fees. These events are in a separate
diagnosticEvents vector in SorobanTransactionMeta with ContractEventType
DIAGNOSTIC. To be able to order diagnostic and non-diagnostic events,
diagnosticEvents will also contain all of the protocol events in the order
they were emitted.
The contract_event host function specified in CAP-0046-03
can be used to create events in contracts.
See the XDR diffs in the Soroban overview CAP, specifically those covering changes to transaction meta and results, result sets, history entries, and contract events.
Each event host function uses a different type. This gives downstream users
another fields to query off of. In addition to that, events from system_event
are also special in that they can only be used by the host functions, allowing
users to see "system" level events as opposed to ones generated by contracts.
For example, this can be used when contracts are created to emit the hash of the
created contract.
There are no limits on individual events, but the total size of all events
emitted in a transaction. The maximum combined events size will be
introduced as txMaxContractEventsSizeBytes in the
ConfigSettingContractEventsV0 ConfigSettingEntry(see
CAP-0046-09 for details on config entries).
txMaxContractEventsSizeBytes will be 10000 initially, and the minimum the
setting can be set to is 0.
Downstream systems will need to be able to parse TransactionMetaV3 for all
meta information.
The events can make TransactionMeta larger by at most txMaxContractEventsSizeBytes.
The security concerns from [CAP-0051] (https://github.com/stellar/stellar-protocol/blob/master/core/cap-0051.md#security-concerns) apply here as well.
TBD
TBD. See rs-stellar-contract-env and stellar-core’s repo (branch to be added) for the prototype implementation.