Move Programming Language Cheat Sheet

Move Programming Language Cheat Sheet

Move keeps your code tidy by grouping it into modules—think of them as neat packages containing structs, functions, and constants that shape how your smart contract works. Each module gets a unique address and name to stay organized on the blockchain.

Example:

move

module 0x1::MyModule {
    use std::signer;

    struct MyStruct has key, store {
        field: u64,
    }

    public fun my_function(arg: u64) {
        // Your code lives here
    }
}

What’s Happening:

  • Module Declaration: The module <address>::<ModuleName> line sets up the module’s namespace. The <address> (like 0x1) is a blockchain address, and <ModuleName> is a unique name for the module.
  • Imports: The use keyword grabs external modules, like std::signer, so you can tap into their functions or types.
  • Structs: These are custom data types (e.g., MyStruct) that can have special abilities like key or store (we’ll cover those soon).
  • Functions: Functions like my_function hold the contract’s logic. The public keyword means it’s callable from outside the module.

Why It’s Cool:

  • Modules are stored on-chain under a specific address, so they’re one-of-a-kind.
  • The use statement lets you reuse code by pulling in other modules’ functionality.
  • Everything in Move lives inside modules—there’s no wild, global space outside them.

Syntax

Move’s syntax is clean, strict, and built to keep your code safe and easy to follow.

Syntax Breakdown:

ConceptSyntax / ExampleWhat It Does
Declare modulemodule 0x1::MyModule {}Sets up a new module under address 0x1 named MyModule.
Importuse std::signer;Pulls in the signer module from the standard library.
Comment// single line /* multiline */Adds single-line or multi-line comments to explain your code.
SemicolonRequired at the end of statementsEvery statement needs a ; to keep things tidy and clear.

Let’s Break It Down:

  • Module Declaration: Modules are the core of Move programs. The address (e.g., 0x1) links the module to a blockchain account, avoiding naming conflicts.
  • Imports: Move’s modular setup means you explicitly import dependencies with use. For example, std::signer gives you tools for account authentication.
  • Comments: Just like in other languages, comments help you document your code. Move doesn’t let you sneak inline comments on the same line as code without a semicolon.
  • Semicolons: They’re a must to mark the end of statements, keeping the compiler happy and your code unambiguous.

Example:

move

module 0x1::Example {
    use std::signer; // Snag the signer module

    // A simple function
    public fun say_hello() {
        // Just waving hello
        let message = b"Hello, Move!"; /* Multi-line comment for extra notes */
    }
}

Data Type

Move is a statically typed language with a small, focused set of built-in types, plus support for custom structs and vectors.

The Types:

TypeWhat It Is
boolTrue or false values.
u88-bit unsigned integer (0 to 255).
u6464-bit unsigned integer, perfect for most number crunching.
u128128-bit unsigned integer for big numbers, like token balances.
addressA blockchain address, like 0x1.
vector<T>A dynamic array holding items of type T (e.g., vector<u64> for numbers).
&T, &mut TImmutable (&T) or mutable (&mut T) references to a value of type T.

What’s Going On:

  • Primitive Types: Move only uses unsigned integers (u8, u64, u128) to avoid issues with negative numbers in financial apps. No floating-point types here—keeps things predictable.
  • Address: Represents a blockchain account or contract, written in hex (e.g., 0x1).
  • Vectors: Think of vector<T> as a flexible list. You can store any type T that has the store ability (more on that later).
  • References: &T is for read-only access, while &mut T lets you tweak data without copying, which is huge for blockchain performance.

Example:

move

let x: u64 = 42;
let addr: address = @0x1;
let numbers: vector<u64> = vector[1, 2, 3];
let ref: &u64 = &x; // Read-only reference
let mut_ref: &mut u64 = &mut x; // Writable reference

Structs

Structs let you create custom data types, often used for things like tokens or account details.

Example:

move

struct Coin has key, store {
    value: u64,
}

What’s Happening:

  • Struct Definition: You define a struct with the struct keyword, a name, and its fields. Here, Coin has a value field of type u64.
  • Abilities: These are special rules that control what you can do with a struct:
    • copy: Lets you duplicate the struct (e.g., let x = y; copies y).
    • drop: Allows the struct to be discarded when it goes out of scope.
    • store: Means it can be saved in global on-chain storage.
    • key: Lets it act as a unique key in global storage, tied to an address.
  • Usage: Structs with key or store are for assets like tokens, while copy and drop are for temporary data.

Example:

move

struct User has copy, drop {
    name: vector<u8>, // UTF-8 string
    age: u64,
}

Why It’s Cool:

  • Abilities are Move’s secret sauce for keeping resources safe, preventing accidental duplication or loss.
  • Resources (structs with key or store) can’t be copied or dropped unless you say so, keeping assets like tokens secure.

Functions

Functions are where the magic happens, defining how your smart contract behaves.

Example:

move

public fun add(x: u64, y: u64): u64 {
    x + y
}

What’s Going On:

  • Function Declaration: Use fun, a name, parameters, and an optional return type (e.g., : u64). This function adds two numbers and returns the sum.
  • Modifiers:
    • public: Callable from outside the module.
    • entry: Marks it as a transaction entry point (used in Aptos).
    • native: Means the function is built into the VM, not written in Move.
    • fun: A standard function, callable within the module or externally if public.
  • Return Values: Functions return a value (like u64) or () (nothing) if no return type is specified.

Example:

move

public entry fun transfer(sender: &signer, to: address, amount: u64) {
    // Code to move `amount` from `sender` to `to`
}

Why It’s Cool:

  • entry functions are your contract’s front door for blockchain transactions.
  • Move keeps functions deterministic—no random numbers or external calls—so things stay predictable.

Modules

Modules get bundled into packages for easy deployment and organization.

Move.toml Example:

toml

[package]
name = "MyMoveApp"
version = "0.1.0"

What’s Happening:

  • Modules: These live in .move files and hold your smart contract’s code. Each module gets deployed under a specific blockchain address.
  • Packages: A package is a collection of modules, defined in a Move.toml file. This file lists metadata like the package name and version, plus any dependencies or build settings.
  • Deployment: You compile and deploy packages to the blockchain using tools like the Aptos CLI (not “Ascertain CLI”—that was a typo in the original!).

Why It’s Cool:

  • Move.toml is your project’s roadmap, similar to Cargo.toml in Rust.
  • Packages keep your code modular and reusable, making development smoother.

move_to & move_from

Move’s storage model is all about keeping assets safe, unique, and never duplicated or lost.

Example:

move

move_to(&signer, my_struct);
move_from<MyStruct>(address);

What’s Happening:

  • Global Storage: Move stores data under specific blockchain addresses. Structs with the key ability can act as unique keys in this storage.
  • Key Operations:
    • signer: Identifies the account behind a transaction, ensuring only they can tweak their storage.
    • move_to: Saves a resource (like a struct with key or store) under the signer’s address.
    • move_from: Pulls a resource out of global storage.
    • borrow_global: Grabs a reference (read-only or writable) to a stored resource.
    • exists: Checks if a resource is present at an address.

Example:

move

struct Coin has key, store {
    value: u64,
}

public entry fun mint(account: &signer, amount: u64) {
    let coin = Coin { value: amount };
    move_to(account, coin); // Save coin to account’s storage
}

Why It’s Cool:

  • Move’s resource model ensures assets like Coin can’t be copied or lost—they’re moved, not duplicated.
  • The signer locks down storage changes to authorized accounts only.
  • Global storage is persistent and tied to addresses, ideal for tokens and other assets.

Controlling program flow

Move gives you the standard tools for controlling program flow, like conditionals and loops.

Example:

move

if (balance >= amount) {
    balance = balance - amount;
} else {
    abort 1; // Stop with an error code
}

while (i < 10) {
    i = i + 1;
}

What’s Going On:

  • if Statements: Handle conditional logic, with an optional else branch.
  • while Loops: Run a block of code as long as a condition is true.
  • abort: Halts execution with an error code to handle problems.
  • Other Tools: Move also supports loop (infinite loops with break) and return for exiting functions early.

Why It’s Cool:

  • Move’s control flow is straightforward but powerful enough for smart contract logic.
  • Use abort or assert to catch errors early, keeping invalid states off the blockchain.

Assert

Move is built with security first, especially for financial applications.

Example:

move

assert!(balance > 0, EINSUFFICIENT_FUNDS);

What’s Happening:

  • Signer-Based Access: Only the signer (the account sending the transaction) can modify its own resources, blocking unauthorized access.
  • Assertions: `assert!(condition, errorrello: Move enforces strict rules to prevent errors like double-spending or unauthorized access. Here’s how Move ensures safety and correctness in its programming model: Key Storage Operations: signer: Aemotion code) checks a condition and stops execution with an error if it fails.
  • Function Visibility: Keep sensitive functions internal (no public modifier) to limit access. Use public only when necessary.
  • Error Codes: Custom codes like EINSUFFICIENT_FUNDS help identify what went wrong.

Why It’s Cool:

  • Move’s type system and abilities prevent nasty issues like reentrancy or double-spending.
  • Assertions ensure your contract’s rules are rock-solid.

Move Testing

Move makes testing a breeze with built-in unit tests in .move files.

Example:

move

#[test]
public fun test_addition() {
    let result = add(2, 3);
    assert!(result == 5, 1);
}

What’s Happening:

  • Test Functions: Tag them with #[test] to run them in Move’s testing framework.
  • Assertions: Use assert! to verify expected behavior. If it fails, the test stops with an error code.
  • Running Tests: The aptos move test CLI command runs all your tests.

Why It’s Cool:

  • Tests are critical for catching bugs in financial contracts before they go live.
  • Move’s built-in testing system makes writing and running tests super easy.

Standard library

Move’s standard library is small but mighty, with tools for common tasks.

ModuleFunctionsWhat They Do
signeraddress_of, borrow_addressGet or borrow a signer’s address.
vectorpush_back, pop_back, lengthManage dynamic arrays (add, remove, get size).
optionsome, none, is_someHandle optional values (like Rust’s Option).
stringutf8, concat, lengthWork with UTF-8 strings.

Example:

move

use std::vector;

let v: vector<u64> = vector::empty();
vector::push_back(&mut v, 42);
let len = vector::length(&v); // Returns 1

Why It’s Cool:

  • The standard library is lean but covers the essentials for blockchain apps.
  • Use vector for lists, option for nullable values, and string for text.

Handles errors

Move handles errors with assertions and custom error codes.

Example:

move

const EINSUFFICIENT_FUNDS: u64 = 0;

assert!(balance > 0, EINSUFFICIENT_FUNDS);

What’s Happening:

  • Error Codes: Define constants (e.g., EINSUFFICIENT_FUNDS) to flag specific issues.
  • Assertions: assert! checks conditions and aborts with the error code if they fail.
  • Abort: The abort keyword stops everything, rolling back the transaction.

Why It’s Cool:

  • Unique error codes make debugging a snap by clearly pointing out issues.
  • Assertions keep your contract’s state safe by catching problems early.

Aptos CLI

The Aptos CLI is your trusty toolkit for Move projects.

CommandWhat It Does
aptos move initSets up a new Move project.
aptos move compileTurns Move code into bytecode.
aptos move testRuns all your test functions.
aptos move publishDeploys modules to the Aptos blockchain.
aptos move runExecutes a transaction (calls an entry function).

Breaking It Down:

  • init: Creates a new project with a Move.toml file and basic structure.
  • compile: Converts your code to bytecode for deployment.
  • test: Runs all #[test] functions to spot bugs.
  • publish: Puts your modules on the Aptos blockchain under a specific address.
  • run: Sends a transaction to call an entry function.

Why It’s Cool:

  • The Aptos CLI is your go-to for building and deploying Move code.
  • Run aptos move test often to catch issues before they hit the blockchain.

Some golden tips

The cheat sheet drops some golden tips for writing clean, secure Move code:

  1. Use has key Wisely:
    • Only give the key ability to structs that need to be unique in global storage. Skip it for temporary data to keep things simple.
  2. Avoid copy and drop for Assets:
    • Don’t use copy or drop for things like tokens to avoid accidental duplication or loss.
  3. Keep entry Functions Simple:
    • entry functions are transaction entry points—focus on validation and pass the heavy work to internal functions for modularity.
  4. Break Code into Small Modules:
    • Split your code into small, focused modules for better readability and reuse.

Example:

move

module 0x1::Token {
    struct Token has key, store {
        value: u64,
    }

    public entry fun transfer(sender: &signer, to: address, amount: u64) {
        // Keep it lean: validate and delegate
        assert!(amount > 0, 1);
        do_transfer(sender, to, amount);
    }

    fun do_transfer(sender: &signer, to: address, amount: u64) {
        // Handle the transfer logic
    }
}

Why It’s Cool:

  • These practices reduce bugs and make your contracts more secure.
  • Modular code fits Move’s vibe of clarity and safety.

The cheat sheet highlights some awesome resources for learning Move:

  • Move Book: The official guide to Move’s syntax, semantics, and advanced features.
  • Aptos Dev Docs: Tutorials and guides for building on Aptos with Move.
  • Sui Dev Docs: Docs for Move development on Sui.

Why It’s Cool:

  • The Move Book is your go-to for mastering the language’s core ideas.
  • Aptos and Sui docs give you platform-specific tips, since Move has slight differences between them.

A Few Extra Nuggets About Move

  • Resource-Oriented Programming: Move’s killer feature is its resource model, treating assets like tokens as linear types that can’t be copied or discarded without permission. This makes financial apps ultra-secure.
  • Aptos vs. Sui: Both use Move, but they’ve got their own flavors:
    • Aptos: Loves entry functions and account-based storage.
    • Sui: Treats resources as unique objects with IDs.
  • Tooling: Beyond the CLI, tools like the Move Prover (for formal verification) and IDE plugins (like VS Code) make coding smoother.

Comments

No comments yet. Why don’t you start the discussion?

    Leave a Reply

    Your email address will not be published. Required fields are marked *