Sui.

Post

Share your knowledge.

article banner.
OYETUNJI HELEN .
Aug 26, 2025
Article

A Step-by-Step Guide from “What is Sui?” to Your First Deployed App

Sui is a high-performance Layer-1 blockchain designed around objects instead of plain account balances. That design unlocks fast, parallel transaction execution, low latency, and developer-friendly patterns using Sui Move, a safety-focused smart-contract language. This article walks you through Sui from zero to a deployed contract, while solving common problems you’ll hit along the way.

  1. What Makes Sui Different (and why you should care)

The challenge: Many new builders arrive with an “account + balances” mental model (like UTXOs or EVM) and get confused by Sui’s object approach.

The fix learn the three pillars:

Objects: Everything is an object with an ID and version: coins, NFTs, game characters, vaults, etc.

Ownership: Objects are either owned (by an address), shared (globally accessible), or immutable.

Move: Sui Move defines and enforces how objects can be created, mutated, transferred, or shared.

Result: Clearer state transitions, safer code, and parallel execution when transactions touch independent objects.

  1. Set Up Your Environment

The challenge: Environment setup can block newcomers (wrong binaries, PATH issues, RPC config).

Step-by-step solution:

Install the Sui CLI

Download a prebuilt binary for your OS or build from source.

Verify:

sui --version

If the shell can’t find sui, add its folder to your PATH.

Pick a network

Sui provides devnet/testnet (for practice) and mainnet (for production).

Configure your client:

sui client

Follow prompts to set an RPC and create or import keys

Create or import a wallet

You can use the CLI keypair or a browser wallet (e.g., Sui Wallet).

On testnet/devnet, request faucet tokens (SUI coins for gas).

Common problem & fix: “RPC not reachable.”

Ensure you copied the RPC URL correctly, your internet is up, or try a different public RPC.

  1. Understand Sui Coins & Gas (and avoid fee headaches)

The challenge: On Sui, gas is a coin object, not just a number. You might have many small coins after transactions.

Step-by-step solution:

Check coins:

sui client gas

Merge tiny coins into one big gas coin (to avoid “insufficient gas” or “too many coins” issues):

sui client merge-coin
--primary-coin <BIG_COIN_ID>
--coin-to-merge <SMALL_COIN_ID>

Split a coin (handy for payments or funding multiple calls):

sui client split-coin
--coin-id <BIG_COIN_ID>
--amounts 100000000,200000000

Common problem & fix: “Insufficient gas budget.”

Increase --gas-budget on your command, merge coins, or request more faucet SUI on testnet/devnet.

  1. Scaffold Your First Sui Move Package

The challenge: Structuring a project and compiling Move modules.

Step-by-step solution:

Create a new package:

sui move new hello_sui cd hello_sui

Explore the layout:

Move.toml — package metadata and dependencies.

sources/ — your .move modules.

Write a simple module (conceptual example):

module {{addr}}::counter { use sui::object::{Self, UID}; use sui::tx_context::{Self, TxContext}; use sui::transfer;

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

/// Create a new counter owned by the signer
public entry fun create(ctx: &mut TxContext) {
    let c = Counter { id: object::new(ctx), value: 0 };
    transfer::transfer(c, tx_context::sender(ctx));
}

/// Increment an owned counter
public entry fun inc(c: &mut Counter) {
    c.value = c.value + 1;
}

/// Share it so anyone can increment (global state)
public entry fun share(c: Counter) {
    transfer::share_object(c);
}

}

Note: This is a simplified example to illustrate patterns: creating an object, mutating it, and sharing it.

Build & test locally:

sui move build sui move test

Common problem & fix: “Unresolved address or dependency.”

Add needed dependencies to Move.toml and check versions. Re-run sui move build.

  1. Publish Your Package

The challenge: First-time publishers hit gas or path issues.

Step-by-step solution:

Publish to the selected network:

sui client publish --path . --gas-budget 100000000

Record the output:

Package ID (where your modules live).

Upgrade capability (keep it safe if you plan upgrades).

Common problem & fix: “Object not found/version mismatch.”

Fetch the latest state before calling functions:

sui client object <OBJECT_ID>

  1. Call Functions & Interact

The challenge: Knowing how to pass object IDs and arguments.

Step-by-step solution:

Create your object:

sui client call
--package <PACKAGE_ID>
--module counter
--function create
--gas-budget 10000000

Save the new Counter object ID from the output.

Increment (owned object):

sui client call
--package <PACKAGE_ID>
--module counter
--function inc
--args <COUNTER_OBJECT_ID>
--gas-budget 10000000

Share it (turn into globally accessible state):

sui client call
--package <PACKAGE_ID>
--module counter
--function share
--args <COUNTER_OBJECT_ID>
--gas-budget 10000000

Common problem & fix: “Mutable reference required.”

Ensure your function signature expects &mut for mutation and you’re passing an owned object, not an immutable/shared one.

  1. Events & Indexing (so your UI can find data)

The challenge: Frontends need reliable ways to find on-chain state and history.

Step-by-step solution:

Emit events in your Move code (e.g., event::emit(...)) for state changes you want to observe.

Query events from your backend or indexer to build feeds, histories, or analytics.

Use dynamic fields when you need scalable per-object maps (e.g., inventories, registries) without bloating a single big object.

Common problem & fix: “Can’t find my object via simple queries.”

Rely on events and dynamic fields to create predictable discovery paths.

  1. Upgrades & Migrations

The challenge: Evolving your app without bricking state.

Step-by-step solution:

Keep the upgrade capability from initial publish.

Design for upgrades: separate logic/storage modules and keep a migration plan (events help you coordinate off-chain).

Test upgrades on testnet/devnet before mainnet.

Run migration calls to adjust objects to the new schema.

Common problem & fix: “Missing upgrade authority.”

Only the holder of the upgrade capability object can upgrade. Store it securely.

  1. Security Checklist (baseline)

Use capabilities for admin or privileged flows.

Minimize shared object usage unless you need global coordination.

Prefer owned objects for user-specific state.

Validate inputs, bounds-check numbers, and think carefully about who can mutate what.

Add tests for failure paths (sui move test).

  1. Shipping to Production

The challenge: Going live safely.

Step-by-step solution:

Audit your modules (peer review + formal tools if possible).

Pin exact dependency versions in Move.toml.

Set monitoring: track events, gas usage, and error rates.

Document object lifecycles and provide user-visible error messages in your UI.

You made it!

You now understand the object model, created a package, published it, interacted with objects, and learned the key patterns (gas, events, upgrades). That’s the foundation for every Sui app you’ll build next.

  • Sui
0
Share
Comments
.