This spec is a work-in-progress
Standard events with enough information for Indexers to reconstruct the state
When a record or a single field is edited, or when a record is deleted, Store emits a standard event with enough information for off-chain actors to reconstruct the new version of the Store with event-sourcing.
event Store_SetRecord(bytes32 indexed tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData),
event Store_SpliceStaticData(bytes32 indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data),
event Store_SpliceDynamicData(bytes32 indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data, bytes32 encodedLengths),
event Store_DeleteRecord(bytes32 indexed tableId, bytes32[] keyTuple),
Each event includes the table ID and each key encoded as bytes32
.
MUD comes with many libraries and services in order to reconstruct the state of any Store with typed columns and keys:
- Indexer is a service that mirrors the state of a Store in a database, and keeping it update to that with milliseconds of latency.
- The MUD Networking stack can reconstruct the state of Store in the browser using either JSON-RPC or an Indexer.
Data encoding
bytes data
uses custom encoding, which MUD networking stack decodes.
Each event carries only data. To get a table's schema (information on how to decode it), use IStore.getSchema(tableId)
or listen to Store_SetRecord
updates of the schema table.
Schema is a way to dynamically store solidity types.
Use the schema-type package (opens in a new tab) to work with it directly.
It's needed because abi.decode
requires statically hardcoded types, and ABI encoding is very inefficient.
Schema
itself is a tightly packed list of types, likeuint256, bytes32, ...
inabi.decode(data, (uint256, bytes32, ...))
, but the types aren't hardcoded.Record
data is multipleFields
together, withPackedCounter
to tell where arrays end/begin.PackedCounter
contains lengths to tell arrays apart, packed tightly in 1 bytes32 word.Field
data is very similar to solidity'sabi.encodePacked
, but for arrays it has no element padding (this is how solidity internally packs data for storage, but it doesn't expose this tight packing in any way (opens in a new tab))