[SEP-48] Contract Interface Spec: Events #1724
Replies: 9 comments 32 replies
|
To experiment with the event schema xdr above, the following branches exist:
To generate and work with XDR for the schema, install the An example of the XDR-JSON for an event: {
"event_v0": {
"doc": "",
"lib": "",
"name": "transfer",
"fields": [
{
"doc": "",
"name": "from",
"type_":"address",
"location": "topic_list"
},
{
"doc": "",
"name": "to",
"type_":"address",
"location": "topic_list"
},
{
"doc": "",
"name": "amount",
"type_":"i128",
"location": "data"
}
],
"data_format": "single_value"
}
}The above XDR-JSON can be encoded into XDR with: If you have an IDE with a JSON LSP (e.g. VSCode), run the following command to generate a JSON Schema file, then open VSCode and create a new .json file containing the following, and you'll get auto-complete. {
"$schema": "./ScSpecEntry.json",
} |
The proposal in its current form makes it possible to define a contract event struct that will map to any of the three major shapes that events take:
The stellar asset contract uses all three shapes in its own events, and being able to describe the SAC with these event schemas is critical. However, that does increase the complexity of the events, how they work, and what a developers needs to know about to use them. Does anyone have alternative ideas? |
|
The proposal for event specs and how it enables dev tooling use cases later sounds good. Some observations:
|
This is true for 95% of contract events. Soroswap events, however take a different shape, which accounts for ~1M events on network: In these examples, both topic names should be Can there be flexibility in how the topic name is set? If the developer could specify the data type of the topic name and location within the topic array, this interface would have better coverage for events because it could dynamically pull the topic name based on data type + location, with the default being first element, type Symbol. If this adds too much overhead or isn't possible, I don't feel strongly about it, just wanted to surface that there are relevant protocols that do not conform to this current interface and whether we want to accommodate that. |
|
Response above seems favourable and given that this proposal is not particularly controversial or novel, I suggest we move ahead and have opened this change to the Stellar XDR: |
I have a rather small suggestion: I think the SEP should specify that all the entries in map data are optional, or alternatively allow specifying that an entry is optional explicitly. In either case it should be able to represent optional entries. |
|
An example of what's possible once contract event specs are available is here: It is a CLI that accepts a single event, and a list of specs to match against, and outputs a self-describing JSON view of the event by combining the internals of both. |
|
Linking out to other places where discussions are starting for how to incorporate the use of these event specifications: |
|
The pull request updating SEP-48 is here: |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Hi all,
I propose we extend SEP-48 Contract Interface Spec to add support for events. I suggest this extension be made by modifying SEP-48 rather than writing a new SEP, but a new SEP would also work if folks think that is preferred.
Motivation
Today contract specs describe and document:
Events are only documented in comments and in SEPs, and not in the contract spec itself.
While this has little impact on contracts, since events are not consumable on chain by other contracts, it makes it more difficult to exchange information about the events with other developers or to offchain systems and applications.
Changes to XDR
A new
SCSpecEntrykind is added for events that stores the event name, fields, and data format.The event name maps to the first topic as a symbol. Reviewing all existing events on the network the majority of events take this shape. See events_topics_types query results.
Any other fields annotated to be located in the topics will have their value inserted into the topics in the order they appear in the struct.
The data format indicates whether the fields annotated to be located in the data are stored in a map, vec, or as a single value. This configuration allows for supporting all types of existing events that are seen on mainnet. See events_data_types query results.
If the data format is map, the data fields are stored in a map with each entry having its key be the symbol name of the field, and the value be the field value. Entries are sorted according to the rules for
ScMapentries.If the data format is vec, the data field values are stored in a vec in the order they appear in the struct.
If the data format is single-value, there must be only one data field. The value of that data field is stored as the data value.
Events and fields may be accompanied by docs.
The XDR changes are backwards compatible.
The XDR is expected to change as such:
Use Cases
There are a few use cases that can make use of events in the contract specs.
Contract Code
Contract code will better self describe the event being emitted. For example:
Today an event emitted appears in contract code as a very simple list:
And this change will require a type, either a struct or a function, so that there's a single location that defines the event once. That definition is what will cause the XDR to be built and written into the contract spec. Likely this will be modelled off the existing contract type struct definitions, but it could also be modelled as a function type.
Developer Products
Developer products such as stellar-cli, stellar.expert, lab, okashi.dev, etc will be able to display information about what events can be emitted.
For example, the tools will be able to include the shape of the events when inspecting the spec:
Products that Inspect and Map Events
Products that inspect and map events. For example, the recently released OpenZeppelin Monitor allows defining triggers based on events, and for EVM those triggers are defined based on event param names, where-as for Stellar today they are defined based on event param indexes, not names. For example: https://docs.openzeppelin.com/monitor/0.1.0/#stellar_variables cc @bramhoogenkamp @brozorec @janewang
Stellar SDKs / Event Bindings
Stellar SDKs can code generate event bindings in a variety of languages and data formats, such generating JS, Go, Python, Java, etc, with transformations from the XDR to those code types. For example:
Go:
Rust:
Data Products Dynamic Transformations
Data processing products such as stellar-cli, Go Stellar SDK's ingest pkg, Hubble, etc will be able to at runtime convert ContractEvent XDR into a simplified JSON format that renders the shape of the event itself, rather than what XDR-JSON does which is render the shape of the XDR.
For example, a ContractEvent XDR contains the following, rendered in XDR-JSON. Even though it is rendered in a human readable form, it is not self describing because the event structure does not contain the names of the fields.
{ "ext": "v0", "contract_id": "6994dcf9f3c32d623b91139d8906640387fb7ef8f6a8023a68774d23a075962e", "type_": "contract", "body": { "v0": { "topics": [ { "symbol": "transfer" }, { "address": "GBMBVAHBE6D4AJXJJVTBQTVU4G7SN4FEIJOL5YTOHZ4WCUMKQ52ANL2B" }, { "address": "GCAN5IE4PWMWSMFZCYQRCJM73MCPG5JD2R7WF5HIFHHHDBWSDJFIWX7X" } ], "data": { "i128": { "hi": 0, "lo": 10000 } } } } }With contract specs containing the shape of events, tooling could transform the ContractEvent XDR into a self-describing form.
{ "contract_id": "6994dcf9f3c32d623b91139d8906640387fb7ef8f6a8023a68774d23a075962e", "body": { "transfer": { "from": "GBMBVAHBE6D4AJXJJVTBQTVU4G7SN4FEIJOL5YTOHZ4WCUMKQ52ANL2B", "to": "GCAN5IE4PWMWSMFZCYQRCJM73MCPG5JD2R7WF5HIFHHHDBWSDJFIWX7X", "amount": { "i128": { "hi": 0, "lo": 10000 } } } } }Data Products Code Generated Static Transformations
Data processing products such as Go Stellar SDK's ingest pkg, etc can code generate event bindings in a variety of languages and data formats, such generating Proto IDL, Avro, etc, and generate transformations from the XDR to those formats. For example:
Or potentially a mapping to existing protos emitted by the TokenTransferProcessor (ref).
Downstream Impact
A type such as those demonstrated above in the use cases will need to be added to the Rust Soroban SDK, because each event must have a single location where it is described. It might be possible to annotate existing event call sites, but in any contract where the same event is published at multiple call sites duplicate schemas may be published, or worse inconsistent schemas may be published.
The above changes are the minimum work required to incorporate events into the contract specs. It will be possible and likely that other tools such as the stellar-cli, Go Stellar SDK ingest pkg, etc may wish to make use of the event specs to do ideas noted in the motivation section, but any adoption is independent of this proposal.
Prior Work
This proposal is based on concepts that have been discussed a few times in the last couple years, and this proposal takes the learnings from those prior conversations and prior work:
Other Discussions
Discord: https://discord.com/channels/897514728459468821/1368933406057955519/1368933406057955519
All reactions