ERC-7208 Onchain data container (On-Chain Data Containers)

Final · Other · created 2023-06-09

A standard that separates the storage of asset data from the logic that handles that data into separate contracts. The same data can be exposed through the interfaces of multiple token standards, which makes compatibility between standards easier.

Why it is needed

Ethereum has many token standards, and even for the same asset, each standard stores and handles data differently. To exchange or interact between assets issued under different standards, each protocol has to support the relevant interfaces one by one, and until now each project has built its own ad hoc solution, leaving the ecosystem fragmented. In addition, a smart contract cannot be changed once deployed, so it is hard for protocols that are already deployed to adapt to newly introduced token standards. If data storage is separated from logic, the logic can be changed while the stored data stays as is, or the data can be exposed through several standards at once, which gives a common framework for building adapters that bridge standards.

What to implement

In depth

Five components

This standard defines five components with different roles. A data point (DP) is a unique identifier that points to an onchain data structure. A data object (DO) is a contract responsible for the low-level storage of information indexed by a data point. A data manager (DM) is one or more contracts that implement high-level logic and the end-user interface. A data point registry (DPR) manages the issuance of data points and defines the space of mutually compatible data points. A data index (DI) is the gateway that manages a data manager's access to data objects. Storage (DO) and logic (DM) are separated, and issuance (DPR) and access control (DI) connect the two.

Internal structure of a data point

A data point must be a bytes32 storage unit, and it must be used to index data, not to hold the asset data itself. The recommended structure is a 4-byte prefix at the front (2 bytes of type prefix, 1 byte of specification version, 1 reserved byte), a 32-bit identifier for internal use within the registry, a 4-byte chain ID (required), and finally 20 bytes holding the address of the registry that issued it. The prefix is used by data objects to quickly identify compatibility problems, and the registry address suffix is used to quickly filter out erroneous transactions that try to use a data point from a different registry. The bytes32 encoding was chosen to accommodate a variety of encodings and to let future data types be referenced without major changes.

The IDataObject interface

A data object must be used to store asset data and must use data points to index its internal structure. It must implement the IDataObject interface, and read(dp, operation, data) and write(dp, operation, data) are generic primitive functions that take an operation identifier (bytes4) and operation-specific data (bytes) and return the result as bytes. setDIImplementation(dp, newImpl) is the function that delegates the management functions of that data point to a new IDataIndex implementation, and it pairs with the requirement that a data object implement the logic for moving management to a different data index implementation. A data object responds to requests according to the gateway mechanism provided by a single data index.

Rules for data managers

A data manager is an independent contract that implements business logic. Reads may use IDataIndex.read() or IDataObject.read() (SHOULD), but writes must go through IDataIndex.write() (MUST). A single data manager may write to multiple data points, and a single data point may be shared by multiple data managers (MAY). It should also implement the logic that asks the data point registry to allocate data points (SHOULD). Multiple data managers sharing the same storage, each exposing a different standard interface, is the adapter structure this standard envisions.

Division of roles between the registry and the index

The data point registry manages the creation, transfer and access control of data points. It issues them with allocate(), moves ownership with transferOwnership(), and manages admin roles with grantAdminRole() and revokeAdminRole(). This is useful when a new data manager is deployed while the application is running. The data index is the gateway through which a data manager accesses data objects. It checks write approval with isApprovedDataManager(), manages approval with allowDataManager(), and read() and write() take the target data object address along with the request and forward it. The data index must also manage per-user internal IDs, and how these IDs are managed determines the space that is compatible across implementations.

Horizontal data portability

The data manager can move the entire storage management of a data object from one data index implementation to another. Because the data index handles user ID management, only the internal access control mechanism can be upgraded while the place where the value is stored (the data object) stays untouched. The original text calls this Horizontal Data Mobility/Portability. It also presents that a data object can hold mutable onchain data, so unlike the static storage of other standard interfaces, state that changes over time can be kept in a delegated storage.

Backward compatibility and reference implementation

This standard supplements the features of existing token standards and does not introduce breaking changes. Tokens of other ERCs that are already deployed can also be wrapped, indexed as data points, managed as data objects, and then exposed through any data manager implementation. However, every integration needs a compatibility analysis for its use case. The reference implementation is an educational example: a fungible token interface and a non-fungible token interface share storage through one Fungible Fractions data object, and both interfaces emit events no matter which side transfer() is called from. This example has not been audited, so it must not be used in production. The status of this proposal is finalized as Final.

Things to watch out for

Original ERC · ← ERCs