Post
Share your knowledge.

From Zero to First Transaction on Sui (Step-by-Step, with Troubleshooting)
Who this is for: Builders who’ve never touched Sui and want to get from a blank machine to a successful on-chain transaction without mystery errors. What you’ll achieve: Install the toolchain, set up a wallet and keypair, fund yourself on a dev network or run localnet, publish a tiny Move package, and execute a transaction that changes state.
Prerequisites
A laptop with a recent macOS, Linux, or Windows (WSL recommended on Windows).
Familiarity with a terminal and Git basics.
Rust toolchain installed (for building Sui binaries).
Node.js (optional but handy if you’ll try the TypeScript SDK later).
Step 1 — Install Sui CLI and Tooling
- Install Rust (rustup) and confirm:
rustup --version cargo --version
- Clone Sui and build (release build is faster at runtime):
git clone https://github.com/MystenLabs/sui.git cd sui cargo build --release
- Make sure the CLI runs:
./target/release/sui --help
Common failure: Build times out or runs out of memory. Fix: Close other apps, add swap (Linux), or build without --release first.
Step 2 — Initialize Sui Client and Keypair
Create a client config and a primary keypair:
./target/release/sui client
Follow prompts to create or import a keypair
This creates a client YAML (usually at ~/.sui/sui_config/client.yaml) and a keystore with your addresses.
Tip: Back up the keystore file. Losing it means losing control of your objects and funds.
Step 3 — Pick Your Network: Devnet/Testnet vs Localnet
You have two realistic onboarding paths:
Devnet/Testnet: Good for learning with shared public infrastructure.
./target/release/sui client switch --env devnet ./target/release/sui client active-address
Localnet: Full control and instant resets—ideal for tight inner loops.
./target/release/sui start
In another terminal:
./target/release/sui client switch --env localnet
Step 4 — Get SUI for Gas
On Devnet/Testnet: Request faucet funds (CLI often includes a faucet helper):
./target/release/sui client faucet ./target/release/sui client gas
On Localnet: You’ll typically start with a funded address automatically. If not, use the local faucet endpoint printed in your sui start logs.
If you see InsufficientGas or GasBalanceTooLow: run faucet again or merge smaller coins:
./target/release/sui client merge-coin --primary <COIN_ID> --coin-to-merge <COIN_ID_2> --gas-budget 30000000
Step 5 — Scaffold a Minimal Move Package
- Create a new workspace:
mkdir hello_sui && cd hello_sui sui move new hello_sui
You’ll get a Move.toml and a sources/ folder.
- Replace sources/hello.move with a tiny module that writes and reads an object:
module hello_sui::hello { use sui::object; use sui::tx_context::{TxContext}; use sui::transfer;
/// A simple owned object with a message.
public struct Greeting has key, store {
id: object::UID,
message: vector<u8>,
}
/// Create a new Greeting object owned by the sender.
public entry fun create(message: vector<u8>, ctx: &mut TxContext) {
let g = Greeting {
id: object::new(ctx),
message,
};
transfer::transfer(g, tx_context::sender(ctx));
}
/// For shared-object practice, you’d add a `public entry` that takes &mut Greeting
/// after converting it to shared via a separate flow. Keeping it simple here.
}
- Build:
sui move build
Step 6 — Publish the Package
./target/release/sui client publish --path . --gas-budget 300000000
Note the printed package ID—you’ll need it to call functions.
If ModuleVerificationFailure: Check you’re importing from the correct Sui framework address in Move.toml and that your module name matches the file.
Step 7 — Call Your Entry Function
We’ll pass a UTF-8 message as bytes:
./target/release/sui client call
--package <PACKAGE_ID>
--module hello
--function create
--args "0x68656c6c6f2c2053756921"
--gas-budget 300000000
The response prints created objects—grab the new Greeting object ID.
Step 8 — View Objects You Own
./target/release/sui client objects ./target/release/sui client object --id <GREETING_ID>
You should see the message bytes. Convert hex to text to confirm.
Step 9 — Troubleshoot the Top 6 Onboarding Errors
-
Cannot connect to fullnode → You’re on the wrong env or node is down. Switch env or restart sui start.
-
Unknown package → You’re calling the wrong package ID (maybe from another network). Re-publish or switch env.
-
InsufficientGas → Run faucet or merge coins; raise --gas-budget.
-
TypeMismatch on --args → Encode arguments exactly as expected; bytes need hex like 0x....
-
Module not found → Module name must match module
:: . -
MoveAbort → Read the abort code; often ownership or capability checks failed.
Step 10 — Clean Resets for Fast Learning
Localnet reset: stop sui start, delete the local db folder printed in logs, then restart.
New account: create a fresh keypair to simulate a new user or multi-sig scenarios.
Quick Checklist
[ ] CLI built and runs
[ ] Active env set (devnet/testnet/localnet)
[ ] Address funded; gas coin merged
[ ] Package builds and publishes
[ ] Entry function executes successfully
You’ve now gone end-to-end: toolchain → wallet → funding → publish → transact → inspect. This foundation will make every later concept (shared objects, capabilities, Kiosk, policies, etc.) far easier.
- 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