Introduction
Everything Theory is a protocol and a blockchain specification centered around a novel class of non-fungible tokens (NFTs).
Protocol of Everything
These new tokens, called object tokens or simply objects, are dynamic in nature: they can be modified, evolve over time, and interact with other tokens, offering significantly more functionality than traditional NFTs.
Each object is built from elements, created within a set, and assigned a specific kind. Creators can build sets using elements and kinds from different authors, enabling efficient and collaborative on-chain creation.
The protocol introduces the concept of space. Beyond ownership, tokens now also have a position, meaning they can not only be held by accounts but also exist in specific locations within the protocol.
Each blockchain supported by the protocol is treated as a universe, referred to as a universe chain. Since the protocol explains how time and space expand, how objects are created from elements, and how they interact, it is often called the Protocol of Everything (PRE).
Previous Network
While decentralized storage solutions like IPFS and Arweave address the centralization issues of static NFTs, challenges remain for dynamic NFTs. For instance:
- A gift card NFT that updates its balance in real-time.
- A PFP NFT that can be accessorized with NFTs from other issuers (e.g., hats, T-shirts).
These cases require decentralized, secure solutions for NFT mutability and interoperability, which are key to broader NFT adoption.
The Previous Network addresses these challenges in a fully decentralized manner. It consists of three primary types of nodes:
- Probes: Detect activities on universe chains and relay them to telescopes, functioning like bridges.
- Telescopes: Validator nodes responsible for validating and processing transactions.
- Satellites: Nodes that serve digital assets related to tokens and elements, allowing users and applications to access this data.
The Previous Network, also referred to as the Previous Chain or simply Previous, features the Object Virtual Machine (OVM)—a specialized virtual machine designed to process the digital assets of tokens. The OVM ensures deterministic and verifiable computations, providing a secure foundation for expanding NFT use cases.
Previous differs from universe chains by focusing on imaging, or the computation of underlying assets of objects. While Ethereum is often called a "world computer," Previous acts like a "world camera," and is sometimes referred to as the observer chain.
Unlike Layer 2 solutions focused on scaling, Previous adds programmability and data availability to token assets—areas that neither Layer 1 nor Layer 2 chains typically prioritize. This capability enables tokens to be applied in a wider range of engaging use cases on both layers.
Primitives
Several fundamental types are key to understanding and working within the protocol.
- Oid: A unique identifier for objects within a universe.
- Revision: Denotes the version of an object's state.
- Selector: Specifies a particular underlying asset of an object.
- Meta: Metadata containing key information about an object.
- Time: Represents a specific moment in the universe's timeline.
- Position: Defines the location within a universe.
- Adjacency: Defines how many objects of a certain kind can be accepted in a relation, acting as a core unit in the adjacency specification.
In addition, there are common primitives types used throughout the protocol:
- uint8, uint32, uint64, uint128, uint256: Unsigned integers of lengths.
- bytes32: A 32-byte fixed-length array.
- bytes: A variable-length array.
Oid
Oid is the unique identifier of an object within a universe.
Representation
Oid can be represented by the following structure:
struct Oid {
uint64 set;
uint64 id;
}
Fields
Type | Field | Description |
---|---|---|
uint64 | set | The set ID. |
uint64 | id | The object ID. |
ID
Both the set and the object ID are represented as 64-bit unsigned integers (uint64).
The valid range for an ID is [1, 2^64 - 2].
Two special values are reserved for specific purposes:
- uint64::MIN (0): Serves as a wildcard, indicating any valid ID.
- uint64::MAX (2^64 - 1): Represents infinity or total.
Encoding
Oid can be encoded as a uint128:
(uint128(set) << 64) | uint128(id)
Written Format
Oid is typically written in dot-decimal format, like {set}.{id}.
For example:
- 17.1: Represents the object with ID
1
within set17
.
For meta objects, the {set}. can be replaced with its name:
- kind 1: Represents the kind object with ID
1
within the set of kinds. - relation 17: Represents the relation object with ID
17
within the set of relations.
Revision
Revision is an index that indicates the version of an object’s state. It is represented by a 32-bit unsigned integer (uint32).
The valid range for a revision is [1, 2^32 - 2].
Two special values are reserved for specific purposes:
- uint32::MIN (0): Indicates that the object does not exist or refers to the latest revision of the object.
- uint32::MAX (2^32 - 1): Indicates that the object has been destroyed.
When an object is created, it starts with a revision of 1. As the object evolves or undergoes changes, its revision is incremented to reflect each state change.
Selector
A Selector is a 32-bit unsigned integer (uint32) that identifies an underlying asset of an object. It is calculated from the function signatures of asset functions within a kind contract.
uint32::MIN (0) and uint32::MAX (2^32 - 1) are not considered valid selectors.
Calculation
The calculation process follows the same method used in Ethereum:
bytes4(keccak256(sig))
In this context, the function signatures (sig
) are determined differently: since asset functions do not have arguments, the signature is simply the function name without parentheses.
For example, given the following kind
contract:
@kind
class Hat {
// ...
meta(): Json {
// ...
}
picture(): Image {
// ...
}
}
The selectors are calculated as follows:
bytes4 selMeta = bytes4(keccak256("meta")); // 0x0144b03a
bytes4 selPicture = bytes4(keccak256("picture")); // 0xeb0568a6
Time
Time represents a specific moment within a universe's timeline.
Representation
Time is conceptually similar to a tuple of (block_num, txn_index, log_index), providing a structured way to track when events occur.
struct Time {
uint64 block;
uint32 second;
uint32 third;
}
Fields
Type | Field | Description |
---|---|---|
uint64 | block | The number of the block on the universe chain where the event occurred. |
uint32 | second | The index of the transaction within that block where the event was logged. |
uint32 | third | The index of the log entry within the transaction that records the event. |
Encoding
The Time structure can be encoded into a u128:
(uint128(block) << 64) | (uint128(second) << 32) | uint128(third)
Written Format
Time is commonly written in the format of block:second:third.
For example:
- 0:0:0 - The beginning of a universe.
- 123456:0:0 - An event occurring at block 123456, transaction 0, log entry 0.
- 122456:7:8 - An event occurring at block 122456, transaction 7, log entry 8.
Position
Position represents the location of an object within a universe, classified into five main categories:
- Void: The object exists nowhere.
- Space: The object is located within a block of space, with optional specific coordinates.
- Object: The object is in relation to another object.
- World: The object has entered a world.
- Outerverse: The object has exited the current universe.
The primary part of a location is called the domain, while the secondary part, called coordinates, provides more specific location details when applicable.
Representation
A position is represented by the following structure:
struct Position {
uint64 domain;
uint64 coord;
}
Fields
Type | Field | Description |
---|---|---|
uint64 | domain | The domain ID, representing the primary part of a location. |
uint64 | coord | The coordinates within the domain, if applicable. |
Domain ID
Each category of location is assigned a unique category ID (cat) and indicated by a letter (indicator). The index specifies the primary part of the location under that category.
Category | Indicator | Cat | Index |
---|---|---|---|
Void | 's' | 0 | index = 0 |
Space | 's' | 0 | index = block ID |
Object | 'o' | 1 | index = set ID |
World | 'w' | 127 | index = world ID |
Outerverse | 'u' | 128 | index = universe ID |
The domain ID is constructed from a combination of cat and index, forming a unique unsigned 64-bit integer:
uint64(cat) << 56 | uint64(index)
Encoding
A position can be encoded as a uint128
:
(uint128(domain) << 64) | uint128(coord)
Written Format
Positions are typically written in dot notation as {letter}.{index}.{coord}. For void positions, you can use void
or 0
, and the trailing 0
can be omitted.
Examples:
Dot Notation | Alternative | Description |
---|---|---|
s.0.0 | void or 0 | The void. |
s.12.34:56 | Block 12, coordinates (34, 56) . | |
o.17.1 | Relation to object 17.1. | |
w.17.0 | w.17 | World 17. |
u.8453.0 | u.8453 | Universe 8453. |
Adjacency
Adjacency is a structure that defines how many objects of a particular kind can be accepted within a relation. It serves as an atomic unit in the adjacency specification, helping to define object interfactions within the protocol.
Representation
The adjacency structure is defined as follows:
struct Adjacency {
uint64 kind;
uint32 degMin;
uint32 degMax;
}
Fields
Type | Field | Description |
---|---|---|
uint64 | kind | The ID of the kind of objects that can be accepted. |
uint32 | degMin | The minimum number (inclusive) of objects of that kind. |
uint32 | degMax | The maximum number (inclusive) of objects of that kind. |
Encoding
A single adjacency structure can be encoded into a uint128;
(uint128(kind) << 64) | (uint128(degMin) << 32) | uint128(degMax)
Elements
Elements are the fundamental building blocks of objects in the protocol.
Several types of elements exist within a universe:
-
Material: Immutable content such as images, audio, structured data, and more. These are stored on the Previous chain and referenced on universe chains using a material hash.
-
Information: Arbitrary data associated with an object.
-
Value: Represents an amount of fungible tokens on a universe chain. Information and materials linked to values can be accessed during runtime in smart contracts on the Previous chain.
-
Artifact: Represents non-fungible tokens (NFTs) on a universe chain. Information and materials linked to artifacts can be accessed during runtime in smart contracts on the Previous chain.
All elements are 32 bytes in length. Values and Artifacts are collectively referred to as token elements due to their token-based nature.
Material
A Material represents digital content in various forms, such as images, audio files, JSON data, and other media types.
A 32-byte hash, known as the material hash, is generated from the content using a specific hashing algorithm. The original content from which this hash is derived is referred to as the preimage or the content of the material.
On universe chains, material hashes are typically used as elements within objects. On the Previous chain, the actual material content can be retrieved and processed to compute object assets.
Representation
The material structure1 is defined as follows:
#![allow(unused)] fn main() { pub struct Material { hasher: u32, content_type: Bytes32, // alias of [u8; 32] content: Bytes, // alias of Vec<u8> } }
Fields
Type | Field | Description |
---|---|---|
u32 | hasher | The identifier for the hashing algorithm. |
Bytes32 | content_type | A string specifying the content type, right-padded to 32 bytes with zeros. |
Bytes | content | The actual digital content. |
Hashing
The material hash is computed as follows:
#![allow(unused)] fn main() { let hash_func = ...; // get hash function by material.hasher let hash = hash_func(material.content); }
Hashers
The following table lists the currently supported hashing algorithms:
Hasher | Description | Hash Function | Implementation Status |
---|---|---|---|
1 | SHA256 | sha256 | Done |
2 | IPFS Content ID | ipfs_cid | Planned |
3 | Arweave Transaction ID | arweave_txnid | Planned |
Additional hashers may be introduced in the future.
This structure is expressed in Rust syntax, as defined and utilized on the Previous chain.
Information
An Information element represents an arbitrary piece of 32-byte data.
Information elements can be used to store part of an object's state, which can be accessed in both set contracts on the universe chain and kind contracts on the Previous chain.
Value
A Value element represents an amount of fungible tokens on a universe chain. Values standardize fungible tokens within the protocol, making them programmable both on universe chains and on the Previous chain.
Before a value can be used in objects, it must be registered in the Element Registry, providing the token standard, contract address, and related materials during registration.
For example, if you're creating an NFT representing a gift card, you can conceptualize it as an object composed of two elements: a value element representing the face value, say 20 $USDC, and a material element representing the card’s background image.
On the universe chain, the set contract holds the token for the object (meaning whoever owns the object can withdraw or use the $USDC). On the Previous chain, the kind contract can read the current balance from the Value element, load the token image, resize it, and overlay it on the background image.
Representation
A Value is represented by the following structure:
struct Value {
uint64 token;
uint192 amount;
}
Fields
Type | Field | Desc |
---|---|---|
uint64 | token | The ID of the fungible token contract. |
uint192 | amount | The amount of the fungible token. |
The higher 8 bits of the token field are used to indicate the token standard. The lower 56 bits of the token field are an index to identify a specific token among all tokens registered under the same standard.
Token Standards
Currently supported standards for fungible tokens include:
Standard Type | Standard Value | Description |
---|---|---|
TOKEN_STD_NATIVE | 1 | Native token (e.g., ETH). |
TOKEN_STD_20 | 2 | ERC-20-like tokens(e.g., USDC). |
Additional token standards can be registered by users, allowing for future token types to be supported.
Encoding
Value can be encoded as a uint256 or a bytes32::
uint256 encoded1 = (uint256(token) << 192) | uint256(amount);
bytes32 encoded2 = bytes32((uint256(token) << 192) | uint256(amount));
Limitation
The amount field is allocated 192 bits, which allows for a maximum value of 2^192 - 1
. While this is large enough for most scenarios, tokens with very high decimal places might approach this upper limit, potentially leading to an overflow or other boundary-related issues in cases of extremely high precision.
Artifact
An Artifact element represents one or more non-fungible tokens (NFTs) on a universe chain. Artifacts standardize NFTs within the protocol, making them programmable on both universe chains and the Previous chain.
Before an artifact can be incorporated into objects, it must first be registered in the Element Registry. During registration, essential details such as the token standard, contract address, ID range, and associated materials must be provided.
Representation
The Artifact structure is defined as follows:
struct Value {
uint64 token;
uint64 id;
uint128 amount;
}
Fields
Type | Field | Desc |
---|---|---|
uint64 | token | The identifier of the non-fungible token contract. |
uint64 | id | The ID of the non-fungible fungible token. |
uint128 | amount | The amount of the non-fungible token, or 1 if not applicable. |
The higher 8 bits of the token field are used to indicate the token standard. The lower 56 bits of the token field are an index to identify a specific token among all tokens registered under the same standard.
Token Standards
Currently supported standards for non-fungible tokens include:
Standard Type | Standard Value | Description |
---|---|---|
TOKEN_STD_721 | 3 | ERC-721-like token. |
TOKEN_STD_1155 | 4 | ERC-1155-like tokens. |
Additional token standards can be registered by users, allowing for future token types to be supported.
Encoding
Artifact can be encoded as a uint256 or a bytes32::
uint256 encoded1 = (uint256(token) << 192) | (uint256(id) << 128) | uint256(amount);
bytes32 encoded2 = bytes32((uint256(token) << 192) | (uint256(id) << 128) | uint256(amount));
Limitations
The id
field is constrained to 64 bits, limiting the maximum ID value. In ERC-721 and ERC-1155 standards, the token ID is typically represented as a uint256
, which allows for larger ID values compared to the protocol's 64-bit limit.
Additionally, the amount
field is limited to 128 bits. This creates a constraint on the maximum token amount that can be represented, whereas the ERC-1155 and ERC-721 standards use a uint256
for amounts, providing a larger range for representing token quantities.
Objects
Object tokens, or objects, are the novel class of non-fungible tokens central to the protocol.
Objects are constructed from elements, created within sets, and assigned a specific kind. Operations such as relations and transforms can be registered and applied to or between objects, allowing them to evolve and interact.
Meta objects, including sets, kinds, relations, and transforms, govern the lifecycle, structure, and behavior of other objects. Objects that are not meta objects are referred to as plain objects.
Objects can also be classified based on their creation time:
- Original objects: Created during the early stages of the universe.
- Emergent objects: Created after the early stages.
Object
The OpenZeppelin documentation1 provides a clear explanation to help distinguish between token contracts and tokens:
Much of the confusion surrounding tokens comes from two concepts getting mixed up: token contracts and the actual tokens.
A token contract is simply an Ethereum smart contract. "Sending tokens" actually means "calling a method on a smart contract that someone wrote and deployed." Essentially, a token contract is a mapping of addresses to balances, along with methods for adding or subtracting from those balances.
These balances represent the tokens themselves. Someone "has tokens" when their balance in the token contract is non-zero. These balances could be considered money, game experience points, ownership deeds, or voting rights, with each type stored in different token contracts.
In light of this, an ERC-721 token is a token defined by an ERC-721-compliant contract, which maintains a mapping between a token's ID, its owner and a URI pointing to its metadata. The structure of the mapping looks like this:
id => (owner, uri)
By comparison, an object is a token defined by a contract conforming to the object token standard. This contract maintains mappings for the object’s ID, its owner, and its state. Additionally, objects have a position property that tracks their location or relationship with other objects. This is managed by the OOPS (Object Operating and Positioning System), a core contract in the protocol. The mappings are as follows:
id => (owner, state) // maintained by the set contract
id => pos // maintained by OOPS
The state of an object is composed of two types of information:
- Metadata: Information about the object’s revision, kind, and set objects.
- Elements: The actual data that make up the object.
The address of the defining contract is stored as an information element within the object's set object, and is typically referred to as the set contract.
There is also another type of contract, executed on the Previous chain, responsible for computing the object's assets. The hash of this contract is stored as a material element of the object's kind, and it is commonly known as the kind contract.
Representation
An object can be represented by the following structure.
struct Object {
uint256 owner;
Meta meta;
bytes32[] elems;
uint256 pos;
}
id
The ID of an object is assigned by the set contract at the time of creation and must remain constant throughout the object's lifecycle. Although this field is essential, its implementation are left to the discretion of users.
owner
The owner field is stored as a uint256 to ensure compatibility with various universe chains. This allows for flexibility in managing ownership across different blockchains.
On Ethereum, ownership is typically represented by an address type. To convert an address into a uint256, the following Solidity code can be used:
uint256(uint160(address(owner)));
The owner field is updated when an object is transferred. Additionally, ownership might change when an object becomes related or unrelated to other objects, or when it enters or exits a space or world, depending on how the governing contract (such as a relation, space, or world contract) is structured.
meta
The meta field contains metadata about the object and is represented by a Meta structure, as defined below:
struct Meta {
uint32 flags;
uint32 rev;
uint32 kindRev;
uint32 setRev;
uint64 kind;
uint64 set;
}
The fields of a Meta structure include:
- flags: Status flags of the object.
- rev: The revision number of the object.
- kindRev: The revision number of the object's kind object.
- setRev: The revision number of the object's set object.
- kind: The ID of the kind object, which defines the object's structure and behavior.
- set: The ID of the set object, where the object was created.
A Meta structure can be encoded into a uint256
as follows:
(uint256(meta.flags) << 224) |
(uint256(meta.rev) << 192) |
(uint256(meta.kindRev) << 160) |
(uint256(meta.setRev) << 128) |
(uint256(meta.kind) << 64) |
uint256(meta.set)
elems
The elems field is an array of bytes32 values representing the elements of an object at a specific revision.
The length of this array and the interpretation of each element are governed by the stateSpec
of the object's kind. The specific revision of the kind object is determined by the meta.kind
and meta.kindRev
fields.
pos
The pos field is a uint256 value that records the object's location, along with additional associated information.
The lower 128 bits are reserved for the Position primitive, which specifies the object's exact location. The higher 128 bits store additional data. This allows the pos field to not only reflect spatial coordinates but also offer room for contextual data related to the operation.
The default value for pos is 0
, indicating that newly created objects initially reside in the void. As objects move, or become related to other objects, the pos field is updated to reflect their new location or relationship within the universe.
Operations
Objects can undergo various operations, ranging from modifications to ownership and interactions with other objects. These operations are either unary (affecting a single object) or inter-operations (interactions between objects).
Unary Operations
Unary operations are applied to individual objects and are defined by set contracts. These operations update specific fields related to the object's state or ownership.
Operation | Description | Fields Affected |
---|---|---|
transfer | Transfers the ownership of the object. | owner |
update | Updates the elements of the object. | meta.rev , elems |
upgrade | Applies new versions of the object's kind and/or set. | meta.rev , meta.kindRev , meta.setRev |
touch | Increments the object's revision without changing state. | meta.rev |
Inter-Operations
Inter-operations involve interactions between objects, are governed by the OOPS contract. These operations can modify relationships, positioning, and movement between spaces and universes.
Operation | Description | Fields Affected |
---|---|---|
move | Moves the object in space. | pos |
relate | Moves the object into a relation with another object. | meta.rev , pos , owner |
unrelate | Moves the object out of a relation with another object. | meta.rev , pos , owner |
enter | Moves the object into a world. | pos , owner |
leave | Moves the object out of a world. | pos , owner |
jump | Moves the object out of the current universe for another, verse-jumping. | pos , owner |
drop | Moves the object into the current universe from another, because of a verse-jumping. | pos , owner |
Compatibility
Objects are a next-generation NFT standard, but they can easily be made compatible with previous NFTs. By implementing the interfaces required by prior standards (e.g., ERC-721 or ERC-1155) alongside those needed for a valid set contract, developers can ensure that objects function like traditional tokens and integrate seamlessly with existing wallets, marketplaces, and block explorers, all with minimal effort.
https://docs.openzeppelin.com/contracts/5.x/tokens#but_first_coffee_a_primer_on_token_contracts
Set
Sets are the objects from which other objects are created.
All set objects originate from a special object called the Set of Sets, which is governed by the Set Registry contract. The Set of Sets itself is considered to have been created from its own structure.
Each set adheres to the Kind of Set, which defines the structure, interactions, and asset computations of set objects.
During the early stages of the universe, several original sets, including the Set of Sets, were created. From that point onward, more objects were either directly or indirectly created from these sets.
Creation
Set objects are created unpon registration, they are initialized as follows:
id
For original sets, the id
field is predefined by constants in the protocol:
uint64 constant ID_SET_OF_SPACE = 0;
uint64 constant ID_SET_OF_SET = 1;
uint64 constant ID_SET_OF_KIND = 2;
uint64 constant ID_SET_OF_RELATION = 3;
uint64 constant ID_SET_OF_TRANSFORM = 4;
For emergent sets, created dynamically later, their IDs are allocated from a specific range:
uint64 constant ID_SET_EMERGENT_MIN = 17;
uint64 constant ID_SET_EMERGENT_MAX = type(uint56).max;
The ID
is constrained to values no greater than 2^56 - 1
to ensure that the upper 8 bits of the uint64
remain unset. This applies to all meta objects, allowing combination with an 8-bit category value to form an efficient uint64
identifier.
meta
The meta
field is initialized in the following manner, applicable to both original and emergent sets.
meta.flags = 0;
meta.rev = 1;
meta.kindRev = latestKindOfSet(); // The latest revision of the Kind of Set
meta.setRev = latestSetOfSet(); // The latest revision of the Set of Sets
meta.kind = ID_KIND_OF_SET;
meta.set = ID_SET_OF_SET;
Since the kind and set objects always point to their latest revisions, the revision numbers for these fields might be incremented for later-created sets.
elems
According to the Kind of Set, a set object is composed of two elements:
Element | Alias | Mutable | Description |
---|---|---|---|
elems[0] | law | N | The address of the set contract. |
elems[1] | lineage | Y | The material hash of data shared by all objects. |
All elements should be provided upon registration, the law
element cannot be changed once it is set.
law
The law
element is the address of the set contract. For Ethereum-based chains, it can be encoded as bytes32
from an address
:
bytes32 law = bytes32(uint160(addr));
linage
The linage
element is the material hash representing the shared data for all objects from this set.
This data is typically utilized in the kind contract, and its format—both content type and structure—should conform to what the kind contract expects. The exact design is at the user’s discretion.
For example, in a typical scenario, the material might be required in JSON format and include fields such as:
- name: The name of the set.
- description: A brief description of the set.
- image (optional): A URL or reference to an image representing the set.
- ... (optional): Additional fields specific to the set.
Operations
Interoperations are not applicable to set objects, but all unary operations are supported and listed below:
Operation | Fields Affected |
---|---|
transfer | owner |
update | meta.rev , elems.linage |
upgrade | meta.rev , meta.kindRev , meta.setRev |
touch | meta.rev |
Kind
Kinds define the composition, interactions, and asset computations for specific types of objects within the protocol.
All kinds are created from the Set of Kinds, governed by the Kind Registry contract.
Each kind adheres to the Kind of Kind, which specifies the structure, interactions, and asset computations of kind objects themselves.
Several original kinds were established during the initial deployment of the protocol, and many more continue to emerge as users register new kinds.
Kinds are crucial in defining the behavior of objects created by sets. When an object is assigned a specific kind through its set contract, it commits to adhering to the behaviors and rules outlined by that kind.
Creation
Kind objects are created unpon registration, they are initialized as follows:
id
For original kinds, the id
field is predefined by constants in the protocol:
uint64 constant ID_KIND_OF_SPACE = 0;
uint64 constant ID_KIND_OF_SET = 1;
uint64 constant ID_KIND_OF_KIND = 2;
uint64 constant ID_KIND_OF_RELATION = 3;
uint64 constant ID_KIND_OF_TRANSFORM = 4;
For emergent kinds, created dynamically later, their IDs are allocated from a specific range:
uint64 constant ID_KIND_EMERGENT_MIN = 17;
uint64 constant ID_KIND_EMERGENT_MAX = type(uint56).max;
The id
is constrained to values no greater than 2^56 - 1
to ensure that the upper 8 bits of the uint64
remain unset.
meta
The meta
field is initialized in the following manner, applicable to both original and emergent kinds.
meta.flags = 0;
meta.rev = 1;
meta.kindRev = latestKindOfKind(); // The latest revision of the Kind of Kind
meta.setRev = latestSetOfKind(); // The latest revision of the Set of Kinds
meta.kind = ID_KIND_OF_KIND;
meta.set = ID_SET_OF_KIND;
Since the kind and set objects always point to their latest revisions, kinds created later may have higher values in these fields.
elems
According to the Kind of Kind, a kind object is composed of the following elements:
Element | Alias | Mutable | Description |
---|---|---|---|
elems[0] | shape | N | Specifies the element types that compose objects of this kind. |
elems[1] | code | Y | Material hash of the kind contract responsible for object imaging. |
elems[2] | gene | Y | Material hash of the data shared by all objects of this kind. |
elems[3] | rels0 | Y | Relations supported by destination objects of this kind. |
elems[4] | rels1 | Y | Relations supported by destination objects of this kind. |
All elements should be provided upon registration, the shape
element cannot be changed once it is set.
shape
The shape
element defines the types of elements that compose an object of this kind.
It is interpreted as an array of uint8
values, with any trailing zeroes removed. The length of this array must be between 0 and 16, meaning an object can have no elements or up to a maximum of 16 elements.
All element types must be greater than 0. The following types are supported:
uint8 constant ELEMENT_TYPE_OBJECT = 1;
uint8 constant ELEMENT_TYPE_INFORMATION = 2;
uint8 constant ELEMENT_TYPE_VALUE = 3;
uint8 constant ELEMENT_TYPE_ARTIFACT = 4;
uint8 constant ELEMENT_TYPE_MATERIAL_GENERAL = 5;
uint8 constant ELEMENT_TYPE_MATERIAL_JSON = 6;
uint8 constant ELEMENT_TYPE_MATERIAL_PTABLE = 7;
uint8 constant ELEMENT_TYPE_MATERIAL_MKTREE = 8;
uint8 constant ELEMENT_TYPE_MATERIAL_IMAGE = 9;
code
The code
element refers to the material hash of the kind contract.
A kind contract is a WebAssembly (Wasm) bytecode that conforms to specifications defined by the OVM (Object Virtual Machine). These contracts are often compiled from source code written in AssemblyScript using kind-as or in Rust using kind-rs.
gene
The gene
element is the material hash representing the shared data for all objects under this kind.
This data is typically utilized in the kind contract, and its format—both content type and structure—should conform to what the kind contract expects. The exact design is at the user’s discretion.
For example, in a typical scenario, the material might be required in JSON format and include fields such as:
- name: The name of the kind.
- description: A description of the kind.
- image (optional): A URL or reference to an image representing the kind.
- ... (optional): Additional fields specific to the kind.
relsN
The relsN
elements define the relations that objects of this kind should support.
These elements provide space for up to 8 relation IDs (uint64
). Each relation ID is encoded in big-endian format, written one by one into the relsN
elements, filling 32 bytes from left to right. If fewer than 8 relation IDs are specified, the remaining space is filled with zeroes.
Operations
Interoperations are not applicable to set objects, all unary operations are supported and listed below:
Operation | Fields Affected |
---|---|
transfer | owner |
update | meta.rev , elems.code , elems.gene , elems.relsN |
upgrade | meta.rev , meta.kindRev , meta.setRev |
touch | meta.rev |
Relation
Relations define adjacencies and rules governing how different kinds of objects interact. They specify which kinds of objects, and how many, can be accepted in a relation, as well as the outcomes when objects are connected (related) or disconnected (unrelated) from one another.
All relations are created from a special set called the Set of Relations, which is governed by the OOPS (Object Operating and Positioning System) contract.
Allrelations adhere to the Kind of Relation, which determines the elements that make up a relation object.
Relations play a crucial role in defining kind objects. By listing relation IDs in their fields, kinds declare support for the adjacencies defined by those relations, enabling objects of that kind to interact with others in a structured and regulated way.
Creation
Relation objects are created unpon registration, they are initialized as follows:
id
Relation IDs are allocated from a specific range:
uint64 constant ID_REL_EMERGENT_MIN = 17;
uint64 constant ID_REL_EMERGENT_MAX = type(uint56).max;
The id
is constrained to values no greater than 2^56 - 1
to ensure that the upper 8 bits of the uint64
remain unset.
meta
The meta
field is initialized in the following manner.
meta.flags = 0;
meta.rev = 1;
meta.kindRev = latestKindOfRelation(); // The latest revision of the Kind of Relation
meta.setRev = latestSetOfRelation(); // The latest revision of the Set of Relations
meta.kind = ID_KIND_OF_RELATION;
meta.set = ID_SET_OF_RELATION;
Since the kind and set objects always point to their latest revisions, relations created later may have higher values in these fields.
elems
According to the Kind of Relation, a relation object is composed of the following elements:
Element | Alias | Mutable | Description |
---|---|---|---|
elems[0] | desc | Y | Mateial hash of the metadata for the relation. |
elems[1] | rule | N | Rules for handling departure objects when being related or unrelated . |
elems[2] | adjs0 | N | Specifies adjacencies supported by the relation. |
elems[3] | adjs1 | N | Specifies adjacencies supported by the relation. |
elems[4] | adjs2 | N | Specifies adjacencies supported by the relation. |
elems[5] | adjs3 | N | Specifies adjacencies supported by the relation. |
All elements should be provided upon registration, the rule
and adjsN
cannot be changed once set.
desc
The desc
element is the material hash of the metadata for this relation. It does not play a role in the interactions defined by the relation on the universe chain.
Instead, it's only utilized by the kind contract on the Previous chain. The material should be a JSON object containing fields such as:
- name: The name of the relation.
- description: A detailed explanation of the relation.
- image (optional): A URL or reference to an image representing the relation.
rule
The rule
field encoding rules for handling departure objects when they are being related or unrelated.
(To Be Continued)
adjsN
The adjs[0..3]
elements collectively define the adjacencies supported by a relation, often referred to as the relation's adjacency specification.
These 4 elements can hold up to 8 adjacency primitives. To ensure a valid adjacency specification, the following rules apply:
-
Special Kinds:
type(uint64).min
(0): Represents any, allowing any kind of object not explicitly listed.type(uint64).max
(2^64 - 1): Represents total, specifying the maximum number of objects allowed in the relation.
-
Ordering: Adjacencies must be listed in ascending order of their kind values. If an adjacency with the
any
kind is present, it must be listed first, and iftotal
is included, it must be listed last.
These 4 elements are filled according to the adjacency primitives in the following manner:
Assuming all adjsN
elements are initially set to zero and ordered from left to right, each adjacency is encoded into a uint128 value and sequentially inserted into the array in big-endian format.
Operations
Interoperations are not applicable to relation objects, all unary operations are supported and listed below:
Operation | Fields Affected |
---|---|
transfer | owner |
update | meta.rev , elems.desc |
upgrade | meta.rev , meta.kindRev , meta.setRev |
touch | meta.rev |
Evolution
Before the singularity, there were no concepts of time, space, elements, objects, or laws—there was nothing.
From the moment of the singularity, time and space began expanding simultaneously, and the first element came into existence.
After a considerable amount of time, during a period referred to as the early stage of the universe, several original elements, objects, and laws were created. These original constructs laid the foundation for the universe's ongoing evolution.
Over time, more elements were discovered, new kinds were built, and new sets were created based on these kinds and elements. From these newly created sets, plain objects emerged.
Under the laws set by governing contracts, objects can mutate, evolve, and interact with one another. They can also traverse spaces, enter different worlds, and even leap beyond the current universe.
The entire universe evolves in a way that is both deterministic and unpredictable.
Singularity
The Singularity marks the inception of a universe, typically represented by the genesis block on its respective chain. A universe's singularity always occurs at time 0:0:0 for that universe. When discussing multiple universes, Coordinated Universal Time (UTC) is used as the standard reference.
Some known universes and their singularities:
- Universe 1 (Ethereum): Began on July 30, 2015, at 03:26:13 PM UTC.
- Universe 8453 (Base): Started on June 15, 2023, at 12:35:47 AM UTC.
Before the singularity, there is no concept of time, space, elements, objects, or laws. The singularity represents the moment from which time and space begin to expand, and the first element—typically the native token—comes into existence.
Expansion
The time and space of a universe expand simultaneously from the moment of the singularity.
Time
Time is a series of discrete instants organized into granular units. These units are called blocks, which can be subdivided into smaller intervals called seconds and thirds, providing a hierarchical structure that reflects how time is measured and flows within the universe.
Time can be represented with the following structure:
#![allow(unused)] fn main() { struct Time { block: u64, second: u32, third: u32, } }
Typically, time is written in the format block:second:third, and time begins at 0:0:0, which marks the start of a universe.
Space
Space is similarly composed of discrete units, referred to as blocks. These blocks are isolated from one another, and the distances or relationships between them are not currently understood. Collectively, these blocks make up the block space, often simply called the space.
There is also a special kind of space called the void space, which fills the gaps between blocks. The void space was formed at the singularity and is considered a unique block—block 0. As time progresses and space expands, each newly created block is assigned a number corresponding to the block element of its creation time.
The overall shape of the block space defines the shape of the universe. According to the Growing Block Theory1, it is hypothesized that the block space has a spiral shape, representing the continuous outward expansion of the universe with each new block. However, the precise mathematical structure of this space remains undefined.
Fictionalized according to Growing Block Universe.
Original Constructs
After a considerable passage of time, a brief yet pivotal period saw the emergence of several original constructs that shaped the foundation of the universe. This period is often referred to as the early stage of the universe.
Elements
The original elements that emerged include:
- Values: Representing the native tokens within the universe.
- Artifacts: The protocol’s original NFTs (OG NFTs).
- Materials: Resources related to original elements and objects.
Kinds
The original kind objects that define key constructs in the universe:
- The Kind of Set: Defines the structure of all sets.
- The Kind of Kind: Defines the structure of all kinds.
- The Kind of Relation: Defines the structure of all relations.
- The Kind of Transform: Defines the structure of all transforms.
Sets
The original set objects that serve as the source for other constructs:
- The Set of Sets: The foundation from which all sets are created.
- The Set of Kinds: The foundation from which all kinds are created.
- The Set of Relations: The foundation from which all relations are created.
- The Set of Transforms: The foundation from which all transforms are created.
Laws
The original governing laws that maintain order:
- Element Registry: Governs the registration and organization of elements.
- Set Registry: Governs the registration and organization of sets.
- Kind Registry: Governs the registration and organization of kinds.
- OOPS (Object Operating and Positioning System): Manages the registration of relations, transforms, and spaces, and governs object interaction and positioning.
Emergent Constructs
As the universe evolves, new elements, kinds, and sets emerge, all governed by the foundational original laws established in the early stages of its development.
Discovery of New Elements
Elements are needed by objects, without them objects can not be constructed.
In order for elements to be used by objects, they must be registered in the Element Registry
—this process is referred to as their element discovery.
Information elements do not require prior registration. They can be used directly as needed. Currently, there is no established method for registering materials. It is anticipated that, as the need arises, a method for registering and authorizing materials will be implemented.
Values
To register a value element in the registry.
function registerValue(TokenStandard std, address addr, bytes32 data)
external
returns (uint64);
Artifacts
To register a artifact element in the registry.
function registerArtifact(TokenStandard std, address addr, bytes32 data, uint64 idBeg, uint64 idEnd)
external
returns (uint64);
Emergence of New Kinds
Kinds serve as a type system for tokens, functioning as abstractions that allow real-world concepts to be represented within the crypto space. They simplify the process of creating interactive tokens, reducing complexity for developers. Essentially, kinds are like "species" within a universe, making the system more versatile.
To encourage reusability and prevent misuse, kinds are created with a cost. This approach incentivizes users to utilize existing kinds rather than continually creating new ones.
A fundamental aspect of the Previous chain's tokenomics is that kind owners are rewarded economically when their kinds are utilized. The system tracks which kinds are being employed by various objects, ensuring transparent and fair rewards for their owners.
To register a kind in the Kind Registry
:
function register(ElementType[] memory shape, bytes32 code, bytes32 gene, uint64[] memory rels)
external
returns (uint64);
Formation of New Sets
By leveraging elements, kinds, relations, and transforms, the creation of sets has become significantly more streamlined. These abstractions distribute the workload traditionally managed by teams to individuals across the entire network, all on-chain.
This not only simplifies the creation process and facilitates efficient on-chain collaboration, but also lowers the overall investment required.
To prevent spam, the creation of new sets involves a cost.
To register a set in the Set Registry
:
function register(address law, bytes32 lineage)
external
returns (uint64);
Development of Objects
The lifecycle of objects is managed by the set contract associated with the set object. Function calls are made to this contract to guide the object’s development.
Creation
Objects can be created from sets.
The method for creating new objects is determined by the set contract. A recommended function signature is:
function create(uint64 id, bytes memory data) external returns (uint64);
In this function:
- The
id
can be0
, meaning no specific ID is required, or non-zero if a specific ID is desired. - The
data
parameter can be empty or contain additional information, which is interpreted by the set contract according to its requirements.
Update
Objects have the ability to change through a call to the update
function:
function update(uint64 id, bytes memory data) external returns (Meta memory);
A set contract may choose not to implement the function, or it can revert the transaction, effectively disabling the ability to update the object.
Upgrade
Objects have the ability to evolve by applying updates from their kind or set objects. This process is initiated through a call to the upgrade
function:
function upgrade(uint64 id, uint32 kindRev, uint32 setRev)
external
returns (Meta memory);
It's important to note that updates to kind or set objects do not automatically trigger an upgrade. The upgrade only occurs when initiated by the object's owner, ensuring that the control over the object remains with its owner.
For unminted objects, the set contract can determine whether to adopt the most recent version of the kind or set object or a specific vision, allowing flexibility in how upgrades are managed.
A set contract may choose not to implement the function, or it can revert the transaction, effectively disabling the ability to upgrade the object.
Interactions
Operations involving two or more objects are generally referred to as interactions. These are actually interoperations that can be registered and executed through the OOPS
contract.
Research on transforms is ongoing, and they will be detailed in future updates.
New Relations
To register a new relation:
function registerRelation(bytes32 desc, RelationRule memory rule, uint128[] memory adjs)
external
returns (uint64);
Relating Objects
To relate a dependent object to a destination object:
function relate(uint256 dep, uint128 dest) external;
To relate multiple dependent objects to a destination object:
function relate(uint256[] memory deps, uint128 dest) external;
Unrelating Objects
To unrelate a dependent object from a destination object:
function unrelate(uint256 dep, uint128 dest) external;
To unrelate multiple dependent objects from a destination object:
function unrelate(uint256[] memory deps, uint256 dest) external;
Exploration
Spaces can be claimed by users if they are unoccupied.
The owner of a space can set rules to determine what kinds of objects can move into the space, similar to how relations are formed between objects. This is why move is also considered a type of interoperation.
Portals and wormholes can be built within a space, effectively turning the entire space into an entry point to another world or universe.
Space registration and related operations are governed by the OOPS contract.
Claim Spaces
To register a new space at a specific block:
function registerSpace(uint64 block, bytes32 desc) external;
Navigating Spaces
To move an object to a new position:
function move(uint256 obj, uint128 pos) external;
To move multiple objects to a new position:
function move(uint256[] memory objs, uint128 pos) external;
Discovering New Worlds
TBD
Verse Jumping
TBD
Imaging
Key information constantly transmitted in the air, such as chain committed, chain reorganized, and chain reverted, are referred to as radiation. Radiation is detected, filtered, and extracted by probes and transformed into signals, which are then relayed to the Previous chain.
A process called object imaging is carried out by the Object Virtual Machine (OVM) on the Previous chain. This process calculates assets for the new revision of an object, making them accessible to apps and users via satellites.
Radiation
Information that is constantly transmitted in the air is referred to as radiation. By detecting and analyzing these radiations, builders of probes discovered that they tend to approach some form of consensus, and can be categorized into three types:
-
Chain Committed: Represents confirmed events that have been accepted into the universe chain. These events form the foundation for more structured data, such as transactions or receipts. Committed radiations signal firm decisions and mark a point of finality in the chain.
-
Chain Reorganized: Indicates the reorganization of a chain, where previous states are reshuffled to accommodate new events. This alters the chain's structure but doesn't fully revert prior actions, making it a temporary shift rather than a complete undoing.
-
Chain Reverted: Refers to a full rollback of part of the chain. Events and transactions are effectively erased as though they never happened, signaling a complete reversal and restoration of the chain to an earlier state.
From these fundamental types of radiation, builders have been able to extract more specific and detailed signals. For instance, Chain Committed radiation often contain embedded commitments to structured data, such as transactions and receipts. By delving deeper into these layers, a variety of signals have been identified, enriching the understanding of the universe's activities.
Signals
Signals are events extracted from radiation emitted by universes within the protocol.
Below is a list of signal names with brief explanations. They are categorized for readability, and further details can be found in later chapters.
Universe Related
- UniverseExpanded: Indicates the expansion of a universe due to chain confirmations, representing the growth of space and time within that universe.
- UniverseRewound: Signals the rollback of a universe due to chain reverts or reorganizations.
- UniverseShifted: Reflects significant changes in the constants or laws that govern the universe.
Element Related
- ValueDiscovered: A new fungible token is identified.
- ArtifactDiscovered: A new non-fungible token is uncovered.
Meta Object Related
- SetCreated: Indicates the establishment of a new set.
- KindCreated: Signals the creation of a new kind.
- RelationCreated: A new relation is defined between objects.
- TransformCreated: Defines a new transformation rule.
- SpaceClaimed: A space is claimed within the universe.
Plain Object Related
Lifecycle signals:
- Created: A new object is minted.
- Updated: The object’s state is changed, leading to a new revision.
- Upgraded: The object's revision is incremented due to its kind and/or set is upgraded.
- Touched: The object’s revision is incremented without altering its core properties.
- Destroyed: The object is permanently removed.
Ownership, positioning, and relations:
- Transferred: The object’s ownership is transferred.
- Moved: The object’s position is changed within a space.
- Related: The object forms a connection with another object.
- Unrelated: The object is disconnected from another object.
World exploration:
- Entered: The object enters a new world.
- Left: The object exits a world.
Verse-jumping:
- Jumped: The object moves to a new universe.
- Dropped: The object arrives in the current universe from an outer-verse.
Imaging
Most lifecycle and relation-related signals cause a revision bump of the object, triggering the recalculation of its assets for the new revision. This process, known as object imaging (or simply imaging), is handled by the OVM on the Previous chain. Imaging is done by executing WebAssembly (Wasm) code defined in the object's kind contract.
Input/Output
Two key inputs are used to determine the code and data required for execution:
- oid: The object’s unique identifier.
- rev: The revision of the object.
The output is a vector, with each element consisting of:
- selector: Identifies the specific asset of the object.
- material: Represents the asset content of the object at the specified revision.
Selectors are extracted from the custom section (according to OVM specification) of the Wasm bytecode and correspond to public asset functions defined in the kind contract source code.
Execution
1. Loading the Kind Contract
The first step is loading the kind contract from chain storage. The code element of the kind object is used to retrieve the Wasm bytecode.
Pseudocode for retrieving the kind contract:
#![allow(unused)] fn main() { let kind_oid: Oid = oid.kind_oid(); let meta: Meta = storage.get_meta(oid, rev); let kind_elems: Vec<Bytes32> = storage.get_object_data(kind_oid, meta.kind_rev); let kind_code: Bytes32 = kind_elems[1]; let code_material: Material = storage.get_material(kind_code); let code: Bytes = code_material.content; }
2. Linking with Host Functions
The OVM specification requires a set of host functions to be available for the Wasm contract at runtime. These functions are critical for interacting with the blockchain state and for processing various types of materials.
Host functions handle materials such as:
- 2D images
- JSON data
- Merkle trees
- Plain tables
Other host functions provide access to object-related information, such as:
- Listing related objects: Helps retrieve the objects linked to the current object being processed.
- Fetching asset materials of related objects: Enables access to the assets of linked objects, crucial for interoperability.
New host functions can be added as the specification evolves. All host functions are designed to ensure determinism, which is essential for the security and verifiability of dynamic NFTs in a decentralized context.
3. Initializing Memory
The elements of the object are retrieved from chain storage and used to initialize the linear memory of the Wasm instance. Elements data is always starting from a fixed offset.
Pseudocode for loading the elements:
#![allow(unused)] fn main() { let elems: Vec<Bytes32> = storage.get_object_data(oid, rev); }
4. Invoking the Entry Function
The only function exported from a kind contract is the entry function. It is auto-generated by compilers to simplify the programming process. A selector is used to specify which asset function to call for each execution.
Pseudocode for entry function invacations:
#![allow(unused)] fn main() { let entry = instance.get_typed_func::<(u32, u32), Option<Rooted<ExternRef>>>(&mut store, "entry")?; let mut result = Vec::<ObjectAsset>::new(); for sel in selectors { let r = entry.call(&mut store, (OBJ_OFFSET, sel))?; let oa = Self::to_asset(sel, er, store)?; result.push(oa); } }
In theory, all asset functions need to be called to compute a new revision of an object, but the OVM can optimize this to only recalculate assets when necessary.
State Transition
Once execution succeeds, the generated assets are committed to chain storage, and a record of asset pointers (hashes to asset materials) is added to the object’s state for that revision. If the execution fails, no asset material is stored, and a record marking the object as malformed is saved.
This ensures that the assets of objects are accessible via satellites.
Accessing
Object assets can be accessed using PRE URIs and retrieved via satellites.
PRE URI
A PRE URI (Uniform Resource Identifier) is used to locate and access a specific asset of an object at a particular revision. The format for the URI is:
pre://{oid}/{rev}/{sel}
- oid: The unique identifier of the object, in dot-decimal format.
- rev: The object's revision number.
- sel: Selector to specify the asset type.
Alternatively, materials or object assets can be retrieved via a hash-based URI:
pre://{universe}/{hash}
- universe: The universe ID where the material's preimage is known.
- hash: The hexadecimal hash of the material or asset.
HTTP Gateway URL
For browsers or legacy systems that don’t natively support PRE URIs, object assets can be accessed using HTTP gateways:
https://preimage.link/{oid}/{rev}/{sel}
or through the hash-based URL:
https://preimage.link/{universe}/{hash}
These URLs allow assets to be easily viewed or downloaded via a web browser.
By leveraging satellites and gateways like preimage.link, the protocol ensures transparent, verifiable, and accessible object assets, whether accessed through decentralized command-line interfaces or web platforms.
Element Registry
Element registration and management.
Functions
registerValue
Registers a new value element in the registry.
function registerValue(TokenStandard std, address addr, bytes32 data) external returns (uint64);
Parameters
Name | Type | Description |
---|---|---|
std | TokenStandard | The token standard (e.g., ERC20, ERC777). |
addr | address | The address of the token contract. |
data | bytes32 | The material hash related to the token. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint64 | The ID of the newly registered value element. |
updateValue
Updates the material data of an existing value element.
function updateValue(uint64 token, bytes32 data) external;
Parameters
Name | Type | Description |
---|---|---|
token | uint64 | The ID of the token element being updated. |
data | bytes32 | New material hash for the token element. |
registerArtifact
Registers a new artifact element in the registry.
function registerArtifact(TokenStandard std, address addr, bytes32 data, uint64 idBeg, uint64 idEnd)
external
returns (uint64);
Parameters
Name | Type | Description |
---|---|---|
std | TokenStandard | The token standard (e.g., ERC721, ERC1155). |
addr | address | The address of the token contract. |
data | bytes32 | The material hash related to the token. |
idBeg | uint64 | The beginning ID of the token. |
idEnd | uint64 | The ending ID of the token. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint64 | The ID of the newly registered artifact element. |
updateArtifact
Updates the material data of an existing artifact element.
function updateArtifact(uint64 token, bytes32 data) external;
Parameters
Name | Type | Description |
---|---|---|
token | uint64 | The ID of the token element being updated. |
data | bytes32 | New material hash for the token element. |
Events
ValueRegistered
Emitted when a new value element is registered.
event ValueRegistered(uint64 token, TokenStandard std, address addr, bytes32 data, address admin);
Parameters
Name | Type | Description |
---|---|---|
token | uint64 | The ID of the newly registered value element. |
std | TokenStandard | The token standard (e.g., ERC20, ERC777). |
addr | address | The address of the token contract. |
data | bytes32 | The material hash related to the token. |
admin | address | The address of the administrator. |
ValueUpdated
Emitted when a value element is updated.
event ValueUpdated(uint64 token, bytes32 data);
Parameters
Name | Type | Description |
---|---|---|
token | uint64 | The ID of the value element being updated. |
data | bytes32 | New material hash for the token. |
ValueTransferred
Emitted when administrator of a value element is changed.
event ValueTransferred(uint64 token, address from, address to);
Parameters
Name | Type | Description |
---|---|---|
token | uint64 | The ID of the value element. |
from | address | The address of the current administrator. |
to | address | The address of the new administrator. |
ArtifactRegistered
Emitted when a new artifact element is registered.
event ArtifactRegistered(
uint64 token, TokenStandard std, address addr, bytes32 data, uint64 idBeg, uint64 idEnd, address admin
);
Parameters
Name | Type | Description |
---|---|---|
token | uint64 | The ID of the newly registered artifact element. |
std | TokenStandard | The token standard (e.g., ERC721, ERC1155). |
addr | address | The address of the token contract. |
data | bytes32 | The material hash related to the token. |
idBeg | uint64 | The beginning ID of the token. |
idEnd | uint64 | The ending ID of the token. |
admin | address | The address of the administrator. |
ArtifactUpdated
Emitted when an artifact element is updated.
event ArtifactUpdated(uint64 token, bytes32 data);
Parameters
Name | Type | Description |
---|---|---|
token | uint64 | The ID of the token being updated. |
data | bytes32 | New material hash for the token. |
ArtifactTransferred
Emitted when administrator of an artifact element is changed.
event ArtifactTransferred(uint64 token, address from, address to);
Parameters
Name | Type | Description |
---|---|---|
token | uint64 | The ID of the artifact element. |
from | address | The address of the current administrator. |
to | address | The address of the new administrator. |
Set Registry
Set registration and management.
Functions
register
Registers a new set in the registry.
function register(address impl, bytes32 data) external returns (uint64);
Parameters
Name | Type | Description |
---|---|---|
impl | address | The address of the set contract. |
data | bytes32 | The material hash of the set's data. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint64 | The ID of the newly registered set. |
update
Updates the metadata and description of a set.
function update(uint64 id, bytes32 data) external returns (Meta memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the set to update. |
data | bytes32 | The updated metadata or description hash. |
Returns
Name | Type | Description |
---|---|---|
<none> | Meta | The updated metadata of the set. |
upgrade
Upgrades a set's kind and/or set to a newer revision.
function upgrade(uint64 id, uint32 kindRev, uint32 setRev) external returns (Meta memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the set to upgrade. |
kindRev | uint32 | The newer revision of the set's kind object (0 indicates no upgrade). |
setRev | uint32 | The newer revision of the set's set object (0 indicates no upgrade). |
Returns
Name | Type | Description |
---|---|---|
<none> | Meta | The metadata of the set after the upgrade. |
touch
Touches the set to trigger a revision bump.
function touch(uint64 id) external returns (Meta memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the set. |
Returns
Name | Type | Description |
---|---|---|
<none> | Meta | The metadata of the set after touch. |
transfer
Transfers ownership of a set to a new address.
function transfer(uint64 id, address to) external;
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the set. |
to | address | The address of the new owner. |
ownerOf
Returns the owner of a specific set.
function ownerOf(uint64 id) external view returns (address);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the set. |
Returns
Name | Type | Description |
---|---|---|
<none> | address | The address of the set owner. |
implOf
Returns the implementation address of a set.
function implOf(uint64 id) external view returns (address);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the set. |
Returns
Name | Type | Description |
---|---|---|
<none> | address | The address of the set's implementation. |
metaAt
Returns the metadata of a set at a specific revision.
function metaAt(uint64 id, uint32 rev) external view returns (Meta memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the set. |
rev | uint32 | The revision number (0 indicates the latest revision). |
Returns
Name | Type | Description |
---|---|---|
<none> | Meta | The metadata of the set at the specified revision. |
stateAt
Returns the elements of a set at a specific revision.
function stateAt(uint64 id, uint32 rev) external view returns (bytes32[] memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the set. |
rev | uint32 | The revision number (0 indicates the latest revision). |
Returns
Name | Type | Description |
---|---|---|
<none> | bytes32[] | The elements of the set at the specified revision. |
revAt
Checks if a revision of a set is valid.
function revAt(uint64 id, uint32 rev) external view returns (uint32);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the set. |
rev | uint32 | The revision number to check (0 indicates the latest revision). |
Returns
Name | Type | Description |
---|---|---|
<none> | uint32 | The valid revision number, or 0 if the revision is invalid. |
Events
SetRegistered
Emitted when a new set is registered.
event SetRegistered(uint64 id, Meta meta, address impl, bytes32 data, address owner);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the set. |
meta | Meta | The intial metadata of the set. |
impl | address | The address of the set's contract. |
data | bytes32 | The material hash of the set's data |
owner | address | The address of the set's owner. |
SetUpdated
Emitted when a set is updated.
event SetUpdated(uint64 id, Meta meta, bytes32 data);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the set. |
meta | Meta | Updated metadata of the set. |
data | bytes32 | Updated material hash of the set's data. |
SetUpgraded
Emitted when a set is upgraded.
event SetUpgraded(uint64 id, Meta meta);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The unique ID of the set. |
meta | Meta | The metadata of the set after upgrade. |
SetTouched
Emitted when a set is touched.
event SetTouched(uint64 id, Meta meta);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the set. |
meta | Meta | The metadata of the set after touch. |
SetTransferred
Emitted when ownership of a set is transferred.
event SetTransferred(uint64 id, address from, address to);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the set. |
from | address | The address of the previous owner. |
to | address | The address of the new owner. |
Kind Registry
Kind registration and management.
Functions
register
Registers a new kind with the specified parameters.
function register(ElementType[] memory stateSpec, bytes32 code, bytes32 data, uint64[] memory relSpec)
external
returns (uint64);
Parameters
Name | Type | Description |
---|---|---|
stateSpec | ElementType[] | Specification of the elements that define the object's state. |
code | bytes32 | The material hash of the kind's code. |
data | bytes32 | The material hash of the kind's data. |
relSpec | uint64[] | List of relations supported by this kind. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint64 | The ID of the newly registered kind. |
update
Updates the code, data of an existing kind.
function update(uint64 id, bytes32 code, bytes32 data) external returns (Meta memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the kind to be updated. |
code | bytes32 | The new material hash representing the kind's code. A zero value indicates no change. |
data | bytes32 | The new material hash representing the kind's data. A zero value indicates no change. |
Returns
Name | Type | Description |
---|---|---|
<none> | Meta | The updated metadata for the kind. |
update
Updates the code, data, and relations of an existing kind.
function update(uint64 id, bytes32 code, bytes32 data, uint64[] memory relSpec) external returns (Meta memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the kind to update. |
code | bytes32 | The new material hash representing the kind's code. A zero value indicates no change. |
data | bytes32 | The new material hash representing the kind's data. A zero value indicates no change. |
relSpec | uint64[] | The updated list of relations for the kind. |
Returns
Name | Type | Description |
---|---|---|
<none> | Meta | The updated metadata of the kind. |
upgrade
Upgrades a kind's kind and/or set to a newer revision.
function upgrade(uint64 id, uint32 kindRev, uint32 setRev) external returns (Meta memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the kind to upgrade. |
kindRev | uint32 | The newer revision of the kind's kind object (0 indicates no upgrade). |
setRev | uint32 | The newer revision of the kind's set object (0 indicates no upgrade). |
Returns
Name | Type | Description |
---|---|---|
<none> | Meta | The metadata of the kind after the upgrade. |
touch
Increases the revision of the kind without any state changes.
function touch(uint64 id) external returns (Meta memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the kind to touch. |
Returns
Name | Type | Description |
---|---|---|
<none> | Meta | The updated metadata of the kind. |
transfer
Transfers ownership of a kind to another address.
function transfer(uint64 id, address to) external;
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the kind to transfer. |
to | address | The address of the new owner. |
ownerOf
Returns the owner of a kind.
function ownerOf(uint64 id) external view returns (address);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the kind. |
Returns
Name | Type | Description |
---|---|---|
<none> | address | The address of the owner. |
stateSpecAt
Retrieves the state specification of a kind at a given revision.
function stateSpecAt(uint64 id, uint32 rev) external view returns (ElementType[] memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the kind. |
rev | uint32 | The specific revision number. A zero value returns the latest revision. |
Returns
Name | Type | Description |
---|---|---|
<none> | ElementType[] | The state specification of the kind. |
codeAt
Retrieves the code hash of a kind at a given revision.
function codeAt(uint64 id, uint32 rev) external view returns (bytes32);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the kind. |
rev | uint32 | The specific revision number. A zero value returns the latest revision. |
Returns
Name | Type | Description |
---|---|---|
<none> | bytes32 | The code hash of the kind. |
relSpecAt
Retrieves the relations supported by a kind at a given revision.
function relSpecAt(uint64 id, uint32 rev) external view returns (uint64[] memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the kind. |
rev | uint32 | The specific revision number. A zero value returns the latest revision. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint64[] | The supported relations. |
metaAt
Returns the metadata of a kind at a specific revision.
function metaAt(uint64 id, uint32 rev) external view returns (Meta memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the kind. |
rev | uint32 | The revision number. A zero value returns the latest revision. |
Returns
Name | Type | Description |
---|---|---|
<none> | Meta | The metadata of the kind. |
stateAt
Retrieves the elements of a kind at a specific revision.
function stateAt(uint64 id, uint32 rev) external view returns (bytes32[] memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the kind. |
rev | uint32 | The revision number. A zero value returns the latest revision. |
Returns
Name | Type | Description |
---|---|---|
<none> | bytes32[] | The elements of the kind at the specified revision. |
revAt
Checks if a revision of a kind is valid.
function revAt(uint64 id, uint32 rev) external view returns (uint32);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The unique identifier of the kind. |
rev | uint32 | The specific revision to check, with zero indicating the latest revision. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint32 | The revision number requested. A zero return value means the revision is invalid. |
Events
KindRegistered
Emitted when a new kind is registered in the registry.
event KindRegistered(
uint64 id, Meta meta, ElementType[] stateSpec, bytes32 code, bytes32 data, uint64[] relSpec, address owner
);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the newly registered kind. |
meta | Meta | Metadata of the registered kind. |
stateSpec | ElementType[] | The element specification of objects belonging to this kind. |
code | bytes32 | The material hash of the kind's code. |
data | bytes32 | The material hash of the kind's data. |
relSpec | uint64[] | List of relations supported by this kind. |
owner | address | The address that owns the registered kind. |
KindUpdated
Emitted when a kind is updated.
event KindUpdated(uint64 id, Meta meta, uint64[] relSpec, bytes32 code, bytes32 data);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the updated kind. |
meta | Meta | Updated metadata of the kind. |
relSpec | uint64[] | Updated list of relations associated with the kind. |
code | bytes32 | Updated material hash of the kind's code. |
data | bytes32 | Updated material hash of the kind's data. |
KindUpgraded
Emitted when a kind is upgraded.
event KindUpgraded(uint64 id, Meta meta);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the upgraded kind. |
meta | Meta | Updated metadata of the upgraded kind. |
KindTouched
Emitted when a kind's revision is bumped without state change.
event KindTouched(uint64 id, Meta meta);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the kind. |
meta | Meta | Metadata of the touched kind. |
KindTransferred
Emitted when ownership of a kind is transferred.
event KindTransferred(uint64 id, address from, address to);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the kind being transferred. |
from | address | The current owner of the kind. |
to | address | The new owner of the kind. |
OOPS
OOPS (Object Operating and Positioning System) is the contract responsible for handling the registration and management of relations, transforms, and spaces, while also overseeing object interactions and positioning within the protocol.
Functions
registerRelation
Registers a new relation
function registerRelation(bytes32 desc, RelationRule memory rule, uint64[] memory adjSpec) external returns (uint64);
Parameters
Name | Type | Description |
---|---|---|
desc | bytes32 | The description of the relation |
rule | RelationRule | The rule defining the relation's behavior |
adjSpec | uint64[] | The adjacency specification for the relation |
Returns
Name | Type | Description |
---|---|---|
<none> | uint64 | The ID of the newly registered relation |
updateRelation
Updates an existing relation
function updateRelation(uint64 rel, bytes32 desc) external;
Parameters
Name | Type | Description |
---|---|---|
rel | uint64 | The ID of the relation to update |
desc | bytes32 | The new description of the relation |
transferRelation
Transfers ownership of a relation to another address
function transferRelation(uint64 rel, address to) external;
Parameters
Name | Type | Description |
---|---|---|
rel | uint64 | The ID of the relation |
to | address | The address to transfer ownership to |
registerSpace
Registers a new space at a specific block
function registerSpace(uint64 block, bytes32 desc) external;
Parameters
Name | Type | Description |
---|---|---|
block | uint64 | The block number of the space |
desc | bytes32 | The description of the space |
updateSpace
Updates an existing space
function updateSpace(uint64 block, bytes32 desc, uint64[] memory rels) external;
Parameters
Name | Type | Description |
---|---|---|
block | uint64 | The block number of the space |
desc | bytes32 | The new description of the space |
rels | uint64[] | Updated relations in the space |
transferSpace
Transfers ownership of a space to another address
function transferSpace(uint64 block, address to) external;
Parameters
Name | Type | Description |
---|---|---|
block | uint64 | The block number of the space |
to | address | The address to transfer ownership to |
relate
Relates a dependent object to a destination object
function relate(uint256 dep, uint128 dest) external;
Parameters
Name | Type | Description |
---|---|---|
dep | uint256 | The ID of the dependent object |
dest | uint128 | The ID of the destination object |
relate
Relates multiple dependent objects to a destination object
function relate(uint256[] memory deps, uint128 dest) external;
Parameters
Name | Type | Description |
---|---|---|
deps | uint256[] | Array of dependent object IDs |
dest | uint128 | The ID of the destination object |
unrelate
Unrelates a dependent object from a destination object
function unrelate(uint256 dep, uint128 dest) external;
Parameters
Name | Type | Description |
---|---|---|
dep | uint256 | The ID of the dependent object |
dest | uint128 | The ID of the destination object |
unrelate
Unrelates multiple dependent objects from a destination object
function unrelate(uint256[] memory deps, uint256 dest) external;
Parameters
Name | Type | Description |
---|---|---|
deps | uint256[] | Array of dependent object IDs |
dest | uint256 | The ID of the destination object |
move
Moves an object to a new position
function move(uint256 obj, uint128 pos) external;
Parameters
Name | Type | Description |
---|---|---|
obj | uint256 | The ID of the object |
pos | uint128 | The new position of the object |
move
Moves multiple objects to a new position
function move(uint256[] memory objs, uint128 pos) external;
Parameters
Name | Type | Description |
---|---|---|
objs | uint256[] | Array of object IDs |
pos | uint128 | The new position of the objects |
Events
RelationRegistered
Emitted when a new relation is registered
event RelationRegistered(uint64 rel, RelationRule rule, uint64[] adjSpec, bytes32 desc, address owner);
Parameters
Name | Type | Description |
---|---|---|
rel | uint64 | The ID of the registered relation |
rule | RelationRule | The rule defining the relation's behavior |
adjSpec | uint64[] | Specifies adjacencies or dependencies for the relation |
desc | bytes32 | The description of the relation |
owner | address | The owner of the relation |
RelationUpdated
Emitted when an existing relation is updated
event RelationUpdated(uint64 rel, bytes32 desc);
Parameters
Name | Type | Description |
---|---|---|
rel | uint64 | The ID of the updated relation |
desc | bytes32 | The updated description of the relation |
RelationTransferred
Emitted when a relation's ownership is transferred
event RelationTransferred(uint64 rel, address from, address to);
Parameters
Name | Type | Description |
---|---|---|
rel | uint64 | The ID of the transferred relation |
from | address | The current owner of the relation |
to | address | The new owner of the relation |
SpaceRegistered
Emitted when a new space is registered
event SpaceRegistered(uint64 block, bytes32 desc, address owner);
Parameters
Name | Type | Description |
---|---|---|
block | uint64 | The block number where the space is registered |
desc | bytes32 | The description of the space |
owner | address | The owner of the space |
SpaceUpdated
Emitted when a space's details are updated
event SpaceUpdated(uint64 block, bytes32 desc, uint64[] rels);
Parameters
Name | Type | Description |
---|---|---|
block | uint64 | The block number of the space |
desc | bytes32 | The updated description of the space |
rels | uint64[] | The updated relations in the space |
SpaceTransferred
Emitted when ownership of a space is transferred
event SpaceTransferred(uint64 block, address from, address to);
Parameters
Name | Type | Description |
---|---|---|
block | uint64 | The block number of the space |
from | address | The current owner of the space |
to | address | The new owner of the space |
Related
Emitted when an object is related to another object
event Related(uint256 dep, uint128 dest, uint32 rev);
Parameters
Name | Type | Description |
---|---|---|
dep | uint256 | The ID of the dependent object |
dest | uint128 | The ID of the destination object |
rev | uint32 | The revision number of the relation |
Related
Emitted when multiple objects are related to a destination object
event Related(uint256[] deps, uint128 dest, uint32 rev);
Parameters
Name | Type | Description |
---|---|---|
deps | uint256[] | Array of dependent object IDs |
dest | uint128 | The ID of the destination object |
rev | uint32 | The revision number of the relation |
Unrelated
Emitted when an object is unrelated (disconnected) from another object
event Unrelated(uint256 dep, uint128 dest, uint32 rev);
Parameters
Name | Type | Description |
---|---|---|
dep | uint256 | The ID of the dependent object |
dest | uint128 | The ID of the destination object |
rev | uint32 | The revision number of the relation |
Unrelated
Emitted when multiple objects are unrelated from a destination object
event Unrelated(uint256[] deps, uint128 dest, uint32 rev);
Parameters
Name | Type | Description |
---|---|---|
deps | uint256[] | Array of dependent object IDs |
dest | uint128 | The ID of the destination object |
rev | uint32 | The revision number of the relation |
Moved
Emitted when the position of an object is changed
event Moved(uint256 obj, uint128 pos);
Parameters
Name | Type | Description |
---|---|---|
obj | uint256 | The ID of the object being moved |
pos | uint128 | The new position of the object |
Moved
Emitted when multiple objects are moved to a new position
event Moved(uint256[] objs, uint128 pos);
Parameters
Name | Type | Description |
---|---|---|
objs | uint256[] | Array of object IDs being moved |
pos | uint128 | The new position of the objects |
Structs
RelationRule
Describes the rules of a relation between objects.
struct RelationRule {
uint8 ownerOnForm;
uint8 posOnForm;
uint8 connOnForm;
uint8 ownerOnTerm;
uint8 posOnTerm;
uint8 connOnTerm;
}
Set Interface
Interface a user-created set must implement.
interface ISet {
// events
event Created(uint64 id, Meta meta, bytes32[] state, address owner);
event Updated(uint64 id, Meta meta, bytes32[] state);
event Upgraded(uint64 id, Meta meta);
event Touched(uint64 id, Meta meta);
event Destroyed(uint64 id, Meta meta);
event Transferred(uint64 id, address from, address to);
// write functions
function update(uint64 id, bytes32[] memory state) external returns (Meta memory);
function upgrade(uint64 id, uint32 kindRev, uint32 setRev) external returns (Meta memory);
function touch(uint64 id) external returns (Meta memory);
function transfer(uint64 id, address to) external;
// view functions
function ownerOf(uint64 id) external view returns (address);
function metaAt(uint64 id, uint32 rev) external view returns (Meta memory);
function stateAt(uint64 id, uint32 rev) external view returns (bytes32[] memory);
function revAt(uint64 id, uint32 rev) external view returns (uint32);
}
Functions
update
Updates the elements of an object.
function update(uint64 id, bytes32[] memory state) external returns (Meta memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the object to update. |
state | bytes32[] | The new elements of the object. |
Returns
Name | Type | Description |
---|---|---|
<none> | Meta | The updated metadata of the object. |
upgrade
Upgrades the kind and/or set of an object to a newer revision.
function upgrade(uint64 id, uint32 kindRev, uint32 setRev) external returns (Meta memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the object to upgrade. |
kindRev | uint32 | The new revision of the kind object (0 indicates no upgrade). |
setRev | uint32 | The new revision of the set object (0 indicates no upgrade). |
Returns
Name | Type | Description |
---|---|---|
<none> | Meta | The metadata of the object after the upgrade. |
touch
Touches an object to trigger a revision bump.
function touch(uint64 id) external returns (Meta memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the object to touch. |
Returns
Name | Type | Description |
---|---|---|
<none> | Meta | The metadata of the object after the touch. |
transfer
Transfers the ownership of an object to a new address.
function transfer(uint64 id, address to) external;
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the object to transfer. |
to | address | The address to transfer the ownership to. |
ownerOf
Returns the owner of an object.
function ownerOf(uint64 id) external view returns (address);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the object. |
Returns
Name | Type | Description |
---|---|---|
<none> | address | The address of the object's owner. |
metaAt
Returns the metadata of an object at a particular revision.
function metaAt(uint64 id, uint32 rev) external view returns (Meta memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the object. |
rev | uint32 | The revision number. A zero value indicates the latest revision. |
Returns
Name | Type | Description |
---|---|---|
<none> | Meta | The metadata of the object. |
stateAt
Returns the elements of an object at a particular revision.
function stateAt(uint64 id, uint32 rev) external view returns (bytes32[] memory);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the object. |
rev | uint32 | The revision number. A zero value indicates the latest revision. |
Returns
Name | Type | Description |
---|---|---|
<none> | bytes32[] | The elements of the object. |
revAt
Checks if a revision of an object is valid.
function revAt(uint64 id, uint32 rev) external view returns (uint32);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the object. |
rev | uint32 | The specific revision. A zero value indicates the latest revision. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint32 | The revision number requested. Zero indicates an invalid revision. |
Events
Created
Emitted when a new object is created within a set.
event Created(uint64 id, Meta meta, bytes32[] state, address owner);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the object. |
meta | Meta | The metadata of the object. |
state | bytes32[] | The elements of the object. |
owner | address | The address of the object's owner. |
Updated
Emitted when an object is updated.
event Updated(uint64 id, Meta meta, bytes32[] state);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the object. |
meta | Meta | The updated metadata of the object. |
state | bytes32[] | The updated elements of the object. |
Upgraded
Emitted when an object is upgraded.
event Upgraded(uint64 id, Meta meta);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the object. |
meta | Meta | The updated metadata of the object after the upgrade. |
Touched
Emitted when an object is touched.
event Touched(uint64 id, Meta meta);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the object. |
meta | Meta | The metadata of the object. |
Destroyed
Emitted when an object is destroyed.
event Destroyed(uint64 id, Meta meta);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the object. |
meta | Meta | The metadata of the object before destruction. |
Transferred
Emitted when the ownership of an object is transferred.
event Transferred(uint64 id, address from, address to);
Parameters
Name | Type | Description |
---|---|---|
id | uint64 | The ID of the object. |
from | address | The address of the current owner. |
to | address | The address of the new owner. |
Profile Objects
Wearables
Blog 3.0
Generative Art
Algorithmic Living Objects
AI-Powered Living Objects
Game Items
Game Characters
Worlds
Contributing
Everything theory is in its early stages, and there are many ways to get involved. Your contribution help shape the future of the protocol.
Read & Share
The simplest way to contribute is by reading this document and sharing it with friends, colleagues, or communities who might be interested in the theory.
If these ideas excite you, consider contributing to help build the protocol.
Design
If you have visions about the future of NFTs or crypto, are familiar with concepts from Greg Egan’s novels, or are knowledgeable about universe theories, you can contribute by:
- Designing the Protocol: Help refine the protocol design, particularly in areas such as object interactions and positioning, which are current focuses.
- Documenting the Protocol: Expand and improve the documentation to make the protocol more accessible to others.
Build
Developers can contribute to several technical areas:
- Core Contracts: Participate in implementing the protocol on universe chains, currently focusing on Ethereum using Solidity and Foundry.
- Reference Chain: Contribute to the development of the Previous chain based on Substrate. The probe (bridge) is being developed using reth’s ExEx, both implemented in Rust.
- Compilers: Help develop or improve compilers for kind contracts to WASM. A basic, functional compiler, kind-as, is available (AssemblyScript, TypeScript), with kind-rs (Rust) planned.
- Tools: Enhance developer tools like pre-cli, a command-line interface for the protocol that interacts with the Previous chain and core contracts, written in TypeScript.
Create
Whether you’re an artist, musician, app developer, game developer, or any type of creative professional, consider how mutable, evolvable, and interoperable NFTs can unlock new possibilities for your work. We’d love to explore these opportunities with you.
Contacts
We’re always open to new ideas and collaborations! If you’d like to get in touch:
We look forward to connecting with you!