Skip to content

Deploy your First Move Contract

Welcome to your journey in deploying a Move module (smart contract) on the Movement .

Smart contracts are called modules in Move.

This guide will walk you through each step, from setup to deployment.

Prerequisites

You need to have one of these command-line interfaces (CLIs) installed :

Step 1: Initialize the CLI

Open your terminal and navigate to your project directory:

Terminal
movement init --skip-faucet

CLI Configuration Prompts

When prompted:

  1. Type custom for network selection

  2. Use these Network Endpoints:

    • RPC/Rest Endpoint: https://aptos.testnet.porto.movementlabs.xyz/v1
    • Faucet Endpoint: https://faucet.testnet.porto.movementnetwork.xyz/
  3. For Private Key:

    • Enter an existing private key, or
    • Press Enter to generate a new one

Step 2: Fund Your Account

  1. Copy your account address from the initialization message
  2. Visit the Movement Labs Web Faucet
  3. Request testnet tokens by pasting your account address

Step 3: Understand Project Configuration

The initialization creates a .movement folder with config.yaml:

config.yaml
profiles:
  default:
    network: Testnet
    private_key: "YOUR_PRIVATE_KEY"
    public_key: "YOUR_PUBLIC_KEY"
    account: "YOUR_ACCOUNT_ADDRESS"
    rest_url: "https://aptos.testnet.porto.movementlabs.xyz/v1/"
    faucet_url: "https://faucet.testnet.porto.movementlabs.xyz/"

Step 4: Scaffold the Move Project

Create your project structure:

Terminal
movement move init --name hello_blockchain

This generates:

  • Move.toml: Project configuration
  • Sources/: Module code directory
  • Scripts/: Transaction scripts
  • Tests/: Unit tests directory

Step 5: Write Your First Module

Create Sources/hello_blockchain.move:

Sources/hello_blockchain.move
module hello_blockchain::message {
    use std::error;
    use std::signer;
    use std::string::{String};
    use aptos_framework::account;
    use aptos_framework::event;
 
    struct MessageHolder has key {
        message: String,
        message_change_events: event::EventHandle<MessageChangeEvent>,
    }
 
    struct MessageChangeEvent has drop, store {
        from_message: String,
        to_message: String,
    }
 
    const ENO_MESSAGE: u64 = 0;
 
    #[view]
    public fun signature(): address {
        @hello_blockchain
    }
 
    #[view]
    public fun get_message(addr: address): String acquires MessageHolder {
        assert!(exists<MessageHolder>(addr), error::not_found(ENO_MESSAGE));
        borrow_global<MessageHolder>(addr).message
    }
 
    public entry fun set_message(account: signer, message: String) acquires MessageHolder {
        let account_addr = signer::address_of(&account);
        if (!exists<MessageHolder>(account_addr)) {
            move_to(&account, MessageHolder {
                message,
                message_change_events: account::new_event_handle<MessageChangeEvent>(&account),
            });
        } else {
            let message_holder = borrow_global_mut<MessageHolder>(account_addr);
            let from_message = message_holder.message;
            event::emit_event(&mut message_holder.message_change_events, MessageChangeEvent {
                from_message,
                to_message: copy message,
            });
            message_holder.message = message;
        }
    }
 
    #[test(account = @0x1)]
    public entry fun sender_can_set_message(account: signer) acquires MessageHolder {
        let addr = signer::address_of(&account);
        aptos_framework::account::create_account_for_test(addr);
        set_message(account, std::string::utf8(b"Hello, Blockchain"));
 
        assert!(
            get_message(addr) == std::string::utf8(b"Hello, Blockchain"),
            ENO_MESSAGE
        );
    }
 
    #[test]
    public fun signature_okay() {
        assert!(signature() == @hello_blockchain, ENO_MESSAGE);
    }
}

Step 6: Compile the Module

Option 1: Without Editing Move.toml
movement move compile --named-addresses hello_blockchain=default

Step 7: Test the Module

Standard Testing
movement move test

Step 8: Publish the Module

Standard Publish
movement move publish

Confirm the transaction when you're prompted to.

Congratulations! You've deployed your first Move module. You can view module details in the explorer and interact using Movement CLI or custom scripts.