Types of Object Ownership
Every object has an owner that determines who can use it in transactions and whether the object is versioned on the fastpath or through consensus. The ownership type you choose affects transaction latency, concurrency, and the security model your smart contract must enforce.
| Ownership type | Access model | Versioning path | Typical latency |
|---|---|---|---|
| Address-owned | A single address can use the object. | Fastpath | Lowest (no consensus needed) |
| Shared | Any address can use the object, subject to Move checks. | Consensus | Higher (consensus ordering required) |
| Immutable | Any address can read the object; no one can mutate it. | Fixed after it becomes immutable | Lowest (read-only, no versioning) |
| Wrapped | Only accessible through the object that wraps it. | Depends on the wrapper | Depends on the wrapper |
| Consensus-address owned / party | A single address owns the object, but the object is sequenced by consensus. | Consensus | Higher (consensus sequencing) |
Choosing an ownership type
Choose the ownership type based on your access pattern.
- Use address-owned objects when a single user owns and controls the object (for example, a user's NFT, a personal wallet, or a capability token). Address-owned objects skip consensus, so transactions against them have the lowest latency.
- Use shared objects when multiple users need to read and write the same object (for example, a marketplace, a liquidity pool, or a game board). Shared objects go through consensus, which adds latency but enables concurrent access. Contention on a single shared object can reduce transaction throughput, so minimize the number of transactions that write to the same shared object in the same checkpoint (Security Best Practices).
- Use immutable objects for data that never changes after creation (for example, published packages, configuration constants, or reference data). Immutable objects have no versioning overhead and any transaction can read them without consensus.
- Use wrapped objects when an object should only be accessible through its parent (for example, a ticket inside an envelope, or inventory items inside a character). See Wrapped Objects for details.
Address-owned
Use address-owned objects when a single user owns and controls the object (for example, a user's NFT, a personal wallet, or a capability token). Address-owned objects skip consensus, so transactions against them have the lowest latency.
Shared
Use shared objects when multiple users need to read and write the same object (for example, a marketplace, a liquidity pool, or a game board). Shared objects go through consensus, which adds latency but enables concurrent access. Contention on a single shared object can reduce transaction throughput, so minimize the number of transactions that write to the same shared object in the same checkpoint.
Immutable
Use immutable objects for data that never changes after creation (for example, published packages, configuration constants, or reference data). Immutable objects have no versioning overhead and any transaction can read them without consensus.
Wrapped
Use wrapped objects when an object should only be accessible through its parent (for example, a ticket inside an envelope, or inventory items inside a character). See Wrapped Objects for details.
Party
Use party objects when you want single-address ownership but need to allow multiple inflight transactions against the same object without fastpath locks. Party objects are sequenced by consensus but owned by a single address.
APIs expose consensus-address-owned objects with a ConsensusAddressOwner owner variant. Party objects are the public Move-facing way to create this ownership form with sui::party::Party and sui::transfer::party_transfer or sui::transfer::public_party_transfer.
Anyone can submit a transaction that references a shared object. Shared-object access is not restricted by ownership, so secure it in Move with explicit authorization checks (such as a capability argument, a tx_context::sender() check, or validating object ownership). Do not assume that referencing a shared object implies the caller is authorized. See Access control.
Address-Owned Objects
Address-owned objects are owned by a Sui 32-byte address, which can either be an account address or an object ID. Learn how to create and access these objects.
Shared Objects
Anyone can access shared objects on the Sui network, so care must be taken to secure access, if needed.
Immutable Objects
Immutable objects cannot be changed, transferred, or deleted. Immutable objects cannot have an owner and anyone can use them.
Wrapped Objects
Wrapped objects are object data structures nested inside of another object data structure. Objects can be wrapped directly, through `Option`, or through `vector` fields.
Party Objects
Party objects are owned by a specified party at the time of transfer and versioned by consensus. Learn how to create, transfer, and access these objects.