> 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/move-contracts.md).

# Move Contracts

Sui Smart Contracts in Move

#### Modules&#x20;

The Sui platform includes the Sui Framework, which includes the core on-chain libraries that Sui Move developers need to bootstrap Sui operations. In particular, Sui supports multiple user-defined coin types, which are custom assets the Sui Move language defines. Sui Framework code contains the `Coin` module supporting creation and management of custom coins. The `Coin` module is located in the [coin.move](https://github.com/MystenLabs/sui/tree/main/crates/sui-framework/packages/sui-framework/sources/coin.move) file. As you might expect, the manifest file describing how to build the package containing the `Coin` module is located in the corresponding [Move.toml](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/packages/sui-framework/Move.toml) file.

In Sui Move, package names are always in PascalCase, while the address alias is lowercase, for example `sui = 0x2` and `std = 0x1`. So: `Sui` = name of the imported package (Sui = sui framework), `sui` = address alias of `0x2`, `sui::sui` = module sui under the address `0x2`, and `sui::sui::SUI` = type in the module above.

When you define a module, specify the module name (`coin`) preceded by the name of the package where this module resides (`sui`). The combination of the package name and the module name uniquely identifies a module in Sui Move source code. The package name is globally unique, but different packages can contain modules with the same name. While module names are not unique, when they combine with their unique package name they result in a unique combination.

#### Structs&#x20;

The `Coin` module defines the `Coin` struct type that you can use to represent different types of user-defined coins as Sui objects:

```rust
struct Coin<phantom T> has key, store {
    id: UID,
    value: u64
}
```

For a Sui Move struct type to define a Sui object type, such as `Coin`, its first field must be `id: UID`, which is a struct type defined in the [object module](https://github.com/MystenLabs/sui/tree/main/crates/sui-framework/packages/sui-framework/sources/object.move). The Move struct type must also have the `key` ability, which allows Sui's global storage to persist the object. Abilities of a Move struct are listed after the `has` keyword in the struct definition, and their existence (or lack thereof) helps the compiler enforce various properties on a definition or on instances of a given struct.

In particular, one type of custom coin already defined in Sui is `Coin<SUI>`, which represents a token used to pay for Sui computations (more generally known as *gas*) - in this case, the concrete type used to parameterize the `Coin` struct is the `SUI` struct in the [SUI module](https://github.com/MystenLabs/sui/tree/main/crates/sui-framework/packages/sui-framework/sources/sui.move)

```rust
struct SUI has drop {}
```

#### Functions&#x20;

Similar to other popular programming languages, the main unit of computation in Move is a function. One of the simplest functions defined in the [Coin module](https://github.com/MystenLabs/sui/tree/main/crates/sui-framework/packages/sui-framework/sources/coin.move) is the `value` function.

```rust
public fun value<T>(self: &Coin<T>): u64 {
    self.value
}
```

Functions in other modules can call this *public* function to return the unsigned integer value currently stored in a given instance of the `Coin` struct. The Move compiler allows direct access to fields of a struct only within the module defining a given struct, as described in [Privileged Struct Operations](https://github.com/move-language/move/blob/main/language/documentation/book/src/structs-and-resources.md#privileged-struct-operations). The body of the function simply retrieves the `value` field from the `Coin` struct instance parameter and returns it. The coin parameter is a read-only reference to the `Coin` struct instance, indicated by the `&` preceding the parameter type. Move's type system enforces an invariant that struct instance arguments passed by read-only references (as opposed to mutable references) cannot be modified in the body of a function.

#### Entry Functions&#x20;

The Sui dialect of the Move language also defines *entry functions*. These must satisfy a certain set of properties and you can call them directly from Sui (e.g., from a Sui application written in a different language).

One of the basic operations in Sui is a gas object transfer between [addresses](https://github.com/move-language/move/blob/main/language/documentation/book/src/address.md) representing individual users. The gas object transfer implementation in the [SUI module](https://github.com/MystenLabs/sui/tree/main/crates/sui-framework/packages/sui-framework/sources/sui.move) is also an example of the use of an entry function:

```rust
public entry fun transfer(c: coin::Coin<SUI>, recipient: address, _ctx: &mut TxContext) {
    ...
}
```

In general, an entry function must satisfy the following properties:

* Has the `entry` modifier. The visibility does not matter. The function can be `public`, `public(friend)`, or `internal`.
* Has no return value
* (Optional) Has a mutable reference to an instance of the `TxContext` struct defined in the [TxContext module](https://github.com/MystenLabs/sui/tree/main/crates/sui-framework/packages/sui-framework/sources/tx_context.move) as the last parameter.

More concretely, the `transfer` function is `public`, has no return value, and has three parameters:

* `c` - Represents a gas object whose ownership is to be transferred.
* `recipient` - The [address](https://github.com/move-language/move/blob/main/language/documentation/book/src/address.md) of the intended recipient
* `_ctx` - A mutable reference to an instance of the `TxContext` struct (in this particular case, this parameter is not actually used in the function's body as indicated by its name starting with `_`). Because it is unused, the parameter could be removed. The mutable reference to the `TxContext` is optional for entry functions.

#### References&#x20;

<https://docs.sui.io/build/move>

<https://github.com/move-language/move/tree/main/language/documentation/book/src>
