Skip to main content

Move Basics

Master the fundamentals of the Move programming language.

Module Structure

Every Move file defines a module:
module my_package::my_module {
    // Module contents
}
  • my_package - Package name (from Move.toml)
  • my_module - Module name (matches filename)

Basic Types

Primitive Types

module my_package::types_example {
    fun example() {
        // Integers
        let x: u8 = 255;
        let y: u64 = 1000000;
        let z: u128 = 340282366920938463463374607431768211455;

        // Boolean
        let is_valid: bool = true;

        // Address
        let addr: address = @0x1;
    }
}

Vectors

use std::vector;

fun vector_example() {
    let mut v = vector::empty<u64>();
    vector::push_back(&mut v, 10);
    vector::push_back(&mut v, 20);

    let first = vector::borrow(&v, 0); // &10
}

Functions

Basic Function

fun add(a: u64, b: u64): u64 {
    a + b
}

Public Functions

public fun greet(): vector<u8> {
    b"Hello, Sui!"
}

Entry Functions

Entry functions can be called directly from transactions:
entry fun transfer_coin(amount: u64, recipient: address) {
    // Transfer logic
}

Structs

Define custom types with structs:
struct User {
    name: vector<u8>,
    age: u8,
    is_active: bool
}

Creating Structs

fun create_user(): User {
    User {
        name: b"Alice",
        age: 25,
        is_active: true
    }
}

Abilities

Structs can have special abilities:
// Copy: can be copied
struct Point has copy {
    x: u64,
    y: u64
}

// Drop: can be discarded
struct Data has drop {
    value: u64
}

// Store: can be stored in global storage
struct Item has store {
    id: u64
}

// Key: can be used as a key in global storage
struct Resource has key {
    id: UID
}

References

Immutable References

fun read_value(x: &u64): u64 {
    *x
}

Mutable References

fun increment(x: &mut u64) {
    *x = *x + 1;
}

Control Flow

If Expressions

fun max(a: u64, b: u64): u64 {
    if (a > b) {
        a
    } else {
        b
    }
}

While Loops

fun sum_to_n(n: u64): u64 {
    let mut sum = 0;
    let mut i = 1;

    while (i <= n) {
        sum = sum + i;
        i = i + 1;
    };

    sum
}

Error Handling

Use assert! for validation:
const EInvalidAmount: u64 = 0;

fun transfer(amount: u64) {
    assert!(amount > 0, EInvalidAmount);
    // Transfer logic
}

Common Patterns

Option Type

use std::option::{Option, some, none};

fun find_user(id: u64): Option<User> {
    if (id == 1) {
        some(create_user())
    } else {
        none()
    }
}

Generics

struct Box<T> {
    value: T
}

fun create_box<T>(value: T): Box<T> {
    Box { value }
}

Complete Example

Here’s a complete module showcasing basic concepts:
module my_package::counter {
    use sui::object::{Self, UID};
    use sui::tx_context::TxContext;

    /// Counter object
    struct Counter has key {
        id: UID,
        value: u64
    }

    /// Create a new counter
    public fun create(ctx: &mut TxContext): Counter {
        Counter {
            id: object::new(ctx),
            value: 0
        }
    }

    /// Increment counter
    public fun increment(counter: &mut Counter) {
        counter.value = counter.value + 1;
    }

    /// Get current value
    public fun value(counter: &Counter): u64 {
        counter.value
    }
}

Next Steps

Now that you know Move basics, let’s write your first contract:

First Contract

Create and deploy your first Move smart contract