> For the complete documentation index, see [llms.txt](https://thryec.gitbook.io/dev-compedium/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://thryec.gitbook.io/dev-compedium/sui/object-programming.md).

# Object Programming

#### Objects <a href="#objects" id="objects"></a>

In contrast to many other blockchains where storage is centered around accounts and each account contains a key-value store, Sui's basic storage unit is an object. Objects are the building blocks of programming in Sui Move, and they are characterized by having the following two properties:

* All objects are annotated with the **`has key`** keyword following their struct declaration.
* All objects have **`id: UID`** as their first field.

```rust
struct Car has key {
	id: UID,
	speed: u8,
	acceleration: u8,
	handling: u8
}
```

Object ownership can be classified using the following four methods:

**Owned by an address:** A Move object, upon creation in the Move code, can be transferred to an address. After the transfer, the address owns that object. An object owned by an address can be used (i.e. passed as a Move call parameter) only by transactions signed by that owner address. Owned objects can be passed as a Move call parameter in any of these three forms: read-only reference (**`&T`**), mutable reference (**`&mut T`**), and by-value (**`T`**).

```rust
struct ObjectA has key { id: UID }

public entry fun create_object_owned_by_an_address(ctx: &mut TxContext) {
	transfer::transfer({
		ObjectA { id: object::new(ctx) }
	}, tx_context::sender(ctx))
}
```

**Owned by another object:** When an object is owned by another object, it's not wrapped. The child object still exists independently as a top-level object and can be accessed directly in Sui storage. We will cover this in greater detail in the fourth session as we discuss [Dynamic Fields](https://docs.sui.io/build/programming-with-objects/ch5-dynamic-fields?ref=blog.sui.io).

```rust
struct ObjectB has key, store { id: UID }

public entry fun create_object_owned_by_an_object(parent: &mut ObjectA, ctx: &mut TxContext) {
	let child = ObjectB { id: object::new(ctx) };
	ofield::add(&mut parent.id, b"child", child);
}
```

**Immutable:** You can't mutate an immutable object, and an immutable object doesn't have an exclusive owner. Anyone can use an immutable object in a Move call. All Move packages are immutable objects: you can't change a Move package after you publish it. You can convert a Move object into an immutable object using the **`freeze_object`** operation. You can only pass an immutable object in Move calls as a read-only reference (**`&T`**).

```rust
struct ObjectD has key { id: UID }

public entry fun create_immutable_object(ctx: &mut TxContext) {
	transfer::freeze_object(ObjectD { id: object::new(ctx) })
}
```

**Shared:** An object can be shared, meaning that anyone can read or write this object. In contrast to mutable owned objects (which are single-writer), shared objects require consensus to sequence reads and writes. In other blockchains, every object is shared. However, Sui programmers often have the choice to implement a particular use-case using shared objects, owned objects, or a combination. This choice can have implications for performance, security, and implementation complexity.

```rust
struct ObjectC has key { id: UID }

public entry fun create_shared_object(ctx: &mut TxContext) {
	transfer::share_object(ObjectC { id: object::new(ctx) })
}
```

#### Functions <a href="#functions" id="functions"></a>

Several visibility modifiers limit or gate access to Sui Move functions. **`public`** functions allow other modules to import a particular function. **`public(friend)`** functions allow modules given explicit permission to import a particular function. entry functions allow a function to be called directly, such as in a transaction. A special function called **`init`** gets executed only once, when its associated module is published. It always has the same signature and only one argument: **`ctx: &mut TxContext`**.

#### Capabilities <a href="#capabilities" id="capabilities"></a>

A capability is a special pattern in Sui Move that gates access to certain functions. Capabilities can be used in conjunction with the **`init`** function to ensure that only one capability will ever exist, and that it will be sent to the module publisher.

```rust
struct AdminCapability has key { 
	id: UID 
}

fun init(ctx: &mut TxContext) {
	transfer::transfer(AdminCapability {
		id: object::new(ctx),
	}, tx_context::sender(ctx))
}
```
