Sui.

Post

Share your knowledge.

article banner.
MiniBob.
Jul 01, 2025
Article

Mastering Move Language Concepts – Course #2

While Course #1 i've made before introduced you to the basics of writing smart contracts in Move and building simple dApps on the Sui blockchain, this course focuses on deepening your understanding of the Move language itself — from its powerful type system to advanced patterns like generics, events, modules, and access control mechanisms.

By the end of this course, you’ll be able to:

  • Write modular, reusable, and secure Move code
  • Use generics, abilities, and resource types effectively
  • Implement fine-grained access control using capabilities
  • Emit and listen to events for off-chain integration
  • Work with complex data structures like tables and vectors
  • Understand how Move differs from other smart contract languages like Solidity

Let’s dive into the heart of the Move language!

Step 1: Understanding Move’s Core Language Features

Move is designed with safety and clarity in mind. Let's explore some of the most important features that make Move unique as a smart contract language.

1.1 Resource-Oriented Programming (Revisited)

At the core of Move is the concept of resources, which are special types that cannot be copied or deleted unless explicitly allowed. This enforces safe handling of digital assets like tokens or NFTs.

module examples::token {
    use sui::object::{Self, UID};

    struct MyToken has key, store {
        id: UID,
        value: u64,
    }

    public fun mint(ctx: &mut TxContext): MyToken {
        MyToken {
            id: object::new(ctx),
            value: 100,
        }
    }
}

In this example:

  • MyToken is a resource because it has the key ability.
  • It can be stored (store) and uniquely identified by its id.
  • It cannot be duplicated or dropped unless specified.

This guarantees that each MyToken instance is uniquely owned and managed, preventing accidental duplication or deletion.


1.2 Abilities System

Every type in Move has a set of abilities that define what operations it supports:

AbilityMeaning
copyCan be duplicated
dropCan be discarded without destruction
storeCan be stored in global storage
keyCan be used as a struct with an ID field (i.e., an object)

Example:

struct Example has copy, drop { value: u64 }

Understanding these abilities is essential for designing secure and predictable smart contracts.

Why Abilities Matter

Abilities enforce strict rules at compile time. For instance:

  • A struct with only key and store cannot be copied or dropped.
  • You cannot return a non-droppable struct from a function unless it's stored or transferred.

This prevents bugs like double-spending or accidental token loss.


1.3 Generics and Type Parameters

Move supports generic types, allowing developers to write flexible and reusable code.

module examples::storage {
    use sui::object::{Self, UID};

    struct Box<phantom T> has key {
        id: UID,
        content: T,
    }

    public fun new_box<T>(ctx: &mut TxContext, content: T): Box<T> {
        Box {
            id: object::new(ctx),
            content,
        }
    }
}

Here, <T> is a type parameter, making Box work with any type while still being safe and efficient.

Note: The phantom keyword indicates that T doesn’t affect the runtime representation of the struct — useful for abstract modeling.


Step 2: Modular Development and Package Management

As your Move projects grow in complexity, organizing your code becomes critical.

2.1 Creating and Publishing Move Packages

A Move package contains one or more modules and defines dependencies. It's the unit of deployment and versioning in Move.

Directory structure:

sources/
  place.move
  user.move
Move.toml

Define dependencies in Move.toml:

[dependencies]
Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework" }
MyLibrary = { local = "../my-library" }

You can publish packages to the Sui network and reuse them across multiple dApps.

2.2 Reusing Existing Modules

The Sui Framework provides battle-tested modules like coin, transfer, and tx_context. Always check what’s available before writing custom logic.

For example, to transfer an object:

use sui::transfer;

public entry fun send_place(place: Place, recipient: address) {
    transfer::public_transfer(place, recipient);
}

Using standard libraries ensures safer, faster development and better interoperability.


Step 3: Events and Off-Chain Communication

To build real-world applications, your Move contracts need to communicate with off-chain systems like frontends or indexers.

3.1 Emitting Events

Move allows emitting events that can be indexed by external services.

use sui::event;

struct PlaceCreated has drop {
    name: String,
}

public fun emit_place_created(name: String) {
    event::emit(PlaceCreated { name });
}

This event will appear on the blockchain and can be picked up by explorers or indexing tools.

3.2 Listening to Events

Use tools like Suiet Explorer, Subsquid, or the Sui JSON-RPC API to listen for emitted events and react accordingly in your application.

In JavaScript/TypeScript:

import { JsonRpcProvider } from '@mysten/sui.js';

const provider = new JsonRpcProvider('https://fullnode.devnet.sui.io');

const events = await provider.getEvents({
  MoveEventType: '0x...::example::PlaceCreated'
});

Step 4: Access Control and Security Patterns

Security is paramount when dealing with smart contracts. Move provides several tools to implement robust access control.

4.1 Object Ownership Model

Sui enforces ownership at the protocol level. Only the owner of an object can mutate or transfer it.

public entry fun update_name(sweet_place: &mut SweetPlace, new_name: String) {
    sweet_place.name = new_name;
}

Only the current owner can call this function.

4.2 Capabilities Pattern

For more granular permissions, use the capability pattern — create special objects that grant limited access to certain functions.

struct AdminCap has key { id: UID }

public entry fun grant_admin_cap(ctx: &mut TxContext) {
    let cap = AdminCap { id: object::new(ctx) };
    transfer::public_transfer(cap, tx_context::sender(ctx));
}

public entry fun restricted_action(_: &AdminCap) {
    // perform admin action
}

Now only users who hold the AdminCap can execute restricted_action.

This pattern is widely used in DeFi and DAOs to delegate authority securely.


Step 5: Working with Complex Data Structures

Move supports structured data types that allow developers to model complex logic and relationships.

5.1 Vectors

Vectors are used to store ordered collections of items of the same type.

let names = vector[String::utf8(b"Alice"), String::utf8(b"Bob")];

They’re useful for storing lists of NFTs, user roles, or dynamic metadata.

Example usage:

vector::push_back(&mut names, String::utf8(b"Charlie"));

5.2 Tables (via Sui Standard Library)

While Move doesn’t natively support maps or hash tables, Sui provides the Table type in its standard library.

use sui::table::{Self, Table};

struct Registry has key {
    id: UID,
    entries: Table<u64, String>,
}

public fun add_entry(registry: &mut Registry, key: u64, value: String) {
    table::add(&mut registry.entries, key, value);
}

Use tables to manage large datasets efficiently.


Step 6: Testing and Debugging Your Contracts

Testing ensures your Move code behaves as expected under various conditions.

6.1 Unit Testing in Move

Write unit tests directly in your Move modules using the testing framework.

#[test]
public fun test_create_sweet_place() {
    let ctx = tx_context::dummy();
    create_sweet_place(&mut ctx, String::utf8(b"My House"));
}

Run tests with:

sui move test

6.2 Using Sui Explorer

After deploying your contract, use the Sui Explorer to inspect transactions, view object states, and debug issues.


Step 7: Real-World Applications of Advanced Move Concepts

Now that you understand the core language features, let’s explore how they apply to real-world scenarios.

7.1 NFT Minting Platform

Create a platform that allows users to mint NFTs backed by Move resources, leveraging the ownership and resource models.

7.2 DAO Voting System

Implement a decentralized autonomous organization (DAO) using Move for voting, proposals, and governance, using events and capabilities for secure actions.

7.3 Token Swaps and AMMs

Build a decentralized exchange (DEX) using Move modules to represent liquidity pools and token swaps, using generics and tables for efficient state management.

  • Sui
  • Architecture
  • Move
2
Share
Comments
.

Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.

351Posts499Answers
Sui.X.Peera.

Earn Your Share of 1000 Sui

Gain Reputation Points & Get Rewards for Helping the Sui Community Grow.

Reward CampaignJuly