docs/content/guides/developer/objects/object-model.mdx
An object is a fundamental unit of storage on the network. Every resource, asset, or piece of data on-chain is an object. Many other blockchains structure storage around accounts containing key-value stores. Sui's storage is structured around objects addressable by unique IDs on-chain.
Every object has the following components:
A globally unique ID.
An owner, which might be an address or an object.
A version number that increments every time a change is made to the object.
Metadata, such as the digest of the last transaction that used the object.
There are 3 types of objects:
Sui object: Every resource, asset, or piece of data. Sui objects are what transactions interact with, and are the building blocks for all on-chain state.
Sui Move object: An object defined using the Move language. To create a Move object, you must use sui::object::new to create a struct. This struct must have the key ability and include a field id: UID as the first defined field. The struct can also contain primitive types, such as integers and addresses, other objects, and non-object structs. This struct can be stored on-chain as a Sui object.
Sui Move package: A smart contract that can manipulate other objects. Each Move package is a set of Sui Move bytecode modules. The modules within the package each have a name that's unique within the containing package. The combination of the package's on-chain ID and the name of a module uniquely identifies the module. When you publish smart contracts to Sui, a package is the unit of publishing. After you publish a package object, it is immutable and can never be changed or removed. A package object can depend on other package objects that were previously published to Sui.
You can refer to objects by their:
ID: The globally unique ID of the object. It is a stable identifier for the object that does not change and is useful for querying the current state of an object or describing which object was transferred between two addresses.
Versioned ID: An (ID, version) pair. It describes the state of the object at a particular point in the object's history and is useful for asking what the value of the object was at some point in the past or determining how recently an object was updated.
Object reference: An (ID, version, object digest) triple. The object digest is the hash of the object's contents and metadata. An object reference provides an authenticated view of the object at a particular point in the object's history. Transactions require object inputs to be specified through object references to ensure the transaction's sender and a validator processing the transaction agree on the contents and metadata of the object.
Every object has an owner field that dictates who can use it in transactions. This field can contain one of the following options:
Address owned: Owned by a specific 32-byte address that is either an account address derived from a particular signature scheme or an object ID.
Immutable: Not owned by anyone, so anyone can use it. It cannot be mutated, transferred, or deleted.
Party: Transferred using the sui::transfer::party_transfer or sui::transfer::public_party_transfer function and is accessible by the Party to which it is transferred. Party objects can be singly owned, but unlike address-owned objects, they are versioned by consensus.
Shared: Ownership is shared using the sui::transfer::share_object function and is accessible to everyone.
Wrapped: A data structure containing one struct type nested in another.
Every object has the following metadata:
A 32-byte globally unique ID: Derived from the digest of the transaction that created the object and a counter encoding the number of IDs generated by the transaction.
An 8-byte unsigned integer version: Monotonically increases with every transaction that modifies it.
A 32-byte transaction digest: Indicates the last transaction that included this object as an output.
A 32-byte owner field: Indicates how this object can be accessed.
In addition to common metadata, objects have a category-specific, variable-sized contents field containing a Binary Canonical Serialization (BCS)-encoded payload:
Move objects contain their Move type, whether the object can be transferred using public_transfer, and its fields.
Move packages contain the bytecode modules in the package, a table identifying which versions of a package introduced each of its types (type origin table), and a table mapping each of its transitive dependencies to a specific version of that package to use (linkage table).
Transactions take objects as input, read, write, or mutate these inputs, then produce mutated or freshly created objects as output. Each object knows the hash of the last transaction that produced it as an output. A natural way to represent the relationship between objects and transactions is a directed acyclic graph (DAG) where nodes are transactions and directed edges go from transaction A to transaction B if an output object of A is an input object of B. They are labeled by the reference of the object in question, which specifies the exact version of the object created by A and used by B.
The root of this DAG is a genesis transaction that takes no inputs and produces the objects that exist in the system's initial state. You can extend the DAG by identifying mutable transaction outputs that have not yet been consumed by any committed transaction and sending a new transaction that takes these outputs and optionally, immutable transaction outputs as inputs.
Live objects are available as input for a transaction. The global state maintained by Sui consists of the totality of such objects. The live objects for a particular Sui address A are all objects owned by A, along with all shared and immutable objects in the system.
When this DAG contains all committed transactions in the system, it forms a complete and cryptographically auditable view of the system's state and history. In addition, you can use the scheme above to construct a DAG of the relevant history for a subset of transactions or objects, for example, the objects owned by a single address.
Sui has some limits on transactions and data used in transactions, such as a maximum size and number of objects used.
The ProtocolConfig struct in the sui-protocol-config crate itemizes these limits:
lib.rs
Select a network from the following tabs to see the currently configured limits and values.