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 :
- Movement CLI: Installation Guide
- Aptos CLI: Installation Guide
Step 1: Initialize the CLI
Open your terminal and navigate to your project directory:
movement init --skip-faucet
CLI Configuration Prompts
When prompted:
-
Type
custom
for network selection -
Use these Network Endpoints:
- RPC/Rest Endpoint:
https://aptos.testnet.porto.movementlabs.xyz/v1
- Faucet Endpoint:
https://faucet.testnet.porto.movementnetwork.xyz/
- RPC/Rest Endpoint:
-
For Private Key:
- Enter an existing private key, or
- Press Enter to generate a new one
Step 2: Fund Your Account
- Copy your account address from the initialization message
- Visit the Movement Labs Web Faucet
- Request testnet tokens by pasting your account address
Step 3: Understand Project Configuration
The initialization creates a .movement
folder with 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:
movement move init --name hello_blockchain
This generates:
Move.toml
: Project configurationSources/
: Module code directoryScripts/
: Transaction scriptsTests/
: Unit tests directory
Step 5: Write Your First Module
Create 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
movement move compile --named-addresses hello_blockchain=default
Step 7: Test the Module
movement move test
Step 8: Publish the Module
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.