This comprehensive guide walks you through the complete process of creating, compiling, deploying, and interacting with a Move module from scratch. You’ll build a simple “Hello World” module that demonstrates core Move concepts and deployment workflows.
Before starting, ensure you have set up your development environment, created an account, and funded it with testnet tokens. Follow the Setting Up Your Development Environment guide if you haven’t completed these prerequisites.

Overview

In this tutorial, you’ll learn to:
  • Create a new Move project and module structure
  • Compile Move source code into bytecode
  • Deploy your module to the blockchain
  • Interact with your deployed module through transactions and queries
This guide supports both Initia L1 and Move rollup development. Code examples are provided for CLI tools and InitiaJS SDK to accommodate different development preferences.

What You’ll Build

You’ll create a simple message storage module with two functions:
  • save_message: Store a string message in the user’s account
  • view_message: Retrieve the stored message from an account
1

Set Up Environment Variables

Configure your development environment with the necessary network parameters.
export RPC_URL=https://rpc.testnet.initia.xyz # Replace with your target network's RPC
export CHAIN_ID=initiation-2 # Replace with your target network's chain ID  
export GAS_PRICES=0.015uinit # Replace with appropriate gas prices for your network

Network Parameters Reference

VariableDescription
RPC_URLThe RPC endpoint for blockchain interaction and transaction broadcasting
CHAIN_IDUnique identifier for the specific blockchain network you’re targeting
GAS_PRICESTransaction fee rates in {amount}{denomination} format
Find network-specific values in our Networks Documentation for Initia L1, or the Initia Registry for Move rollups.
2

Create Your Project Structure

Start by creating a new directory and initializing it as a Move project.

Create Project Directory

mkdir hello_world
cd hello_world

Initialize Move Package

Initialize your directory as a Move package, which creates the necessary project structure.
initiad move new hello_world

Understanding the Project Structure

Your project now contains these essential components:
hello_world/
├── Move.toml          # Package manifest and configuration
└── sources/           # Directory for Move source code files
3

Write Your Move Module

Create your first Move module with message storage functionality.

Create the Module File

Create a new file called hello_world.move in the sources directory:
hello_world.move
module hello::hello_world {
    use std::string::String;

    struct Message has key {
        content: String,
    }

    public entry fun save_message(account: &signer, message: String) {
        let message_struct = Message { content: message };
        move_to(account, message_struct);
    }

    #[view]
    public fun view_message(account: address): String acquires Message {
        borrow_global<Message>(account).content
    }
}

Understanding the Code

4

Configure and Compile Your Module

Set up your module’s deployment address and compile the source code.

Get Your Deployment Address

First, retrieve your account’s hexadecimal address for the Move.toml configuration:
initiad keys parse $(initiad keys show example --address)
Expected output:
bytes: CC86AF3F776B95A7DED542035B3B666A9FDE2EE9
human: init

Configure Move.toml

Update your Move.toml file with the deployment address and dependencies:
Move.toml
[package]
name = "hello_world"
version = "0.0.0"

[dependencies]
InitiaStdlib = { git = "https://github.com/initia-labs/movevm.git", subdir = "precompile/modules/initia_stdlib", rev = "main" }

[addresses]
std = "0x1"
hello = "0xCC86AF3F776B95A7DED542035B3B666A9FDE2EE9" # Replace with your address from above
Address Configuration Ensure you add the “0x” prefix to your address and replace the example address with your actual deployment address. This determines where your module will be deployed on the blockchain.

Compile Your Module

Build your Move module into deployable bytecode:
initiad move build
Successful compilation output:
Compiling, may take a little while to download git dependencies...
UPDATING GIT DEPENDENCY https://github.com/initia-labs/movevm.git
INCLUDING DEPENDENCY InitiaStdlib
INCLUDING DEPENDENCY MoveNursery
INCLUDING DEPENDENCY MoveStdlib
BUILDING hello_world

Verify Build Output

After compilation, you’ll find a new build/ directory containing:
  • Compiled bytecode modules
  • Dependency information
  • Build artifacts and metadata
5

Deploy Your Module

Deploy your compiled module to the blockchain network.
initiad move deploy \
  --path .
  --upgrade-policy COMPATIBLE \
  --from example \
  --gas auto --gas-adjustment 1.5 \
  --gas-prices $GAS_PRICES \
  --node $RPC_URL \
  --chain-id $CHAIN_ID

Understanding Deployment Options

Successful Deployment Once deployed successfully, your module will be stored at the address specified in your Move.toml file and can be interacted with by any user on the network.
6

Interact with Your Deployed Module

Test your module by executing transactions and querying stored data.

Execute Transactions

Call your module’s save_message function to store data on-chain:
export MODULE_ADDRESS=0xcc86af3f776b95a7ded542035b3b666a9fde2ee9 # Replace with your deployer address
initiad tx move execute $MODULE_ADDRESS hello_world save_message \
  --args '["string:Hello from Move!"]'  \
  --node $RPC_URL \
  --from example \
  --gas-prices $GAS_PRICES \
  --chain-id $CHAIN_ID

Query Stored Data

Retrieve the message you just saved using the view_message function:
initiad query move view $MODULE_ADDRESS hello_world view_message \
    --args '["address:0xcc86af3f776b95a7ded542035b3b666a9fde2ee9"]' \
    --node $RPC_URL

Expected Results

If both operations succeed, your query should return:
{
  "data": "\"Hello from Move!\"",
  "events": [],
  "gas_used": "1071"
}
Success! You’ve successfully created, deployed, and interacted with your first Move module. The message is now permanently stored on the blockchain and can be retrieved by anyone.