Post
Share your knowledge.

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.
- 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.
- 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.
- 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.
- 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.
- 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>
- 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.
- 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
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.
- 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.
- 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).
- 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
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.
- How to Maximize Profit Holding SUI: Sui Staking vs Liquid Staking616
- Why does BCS require exact field order for deserialization when Move structs have named fields?65
- Multiple Source Verification Errors" in Sui Move Module Publications - Automated Error Resolution55
- Sui Move Error - Unable to process transaction No valid gas coins found for the transaction419
- Sui Transaction Failing: Objects Reserved for Another Transaction410