Set up your move development environment

Start Move-Based Programming works best as a sequence, not a scramble through settings. Do the minimum first: confirm compatibility, connect the core hardware, update only when needed, and test the result before adding optional features. That order keeps the task understandable and makes failures easier to isolate. After each step, pause long enough for the interface to finish syncing. Many setup problems are timing problems disguised as configuration problems. If the same step fails twice, record the exact error, restart the smallest affected piece, and retry before moving deeper.

The to Move-Based Programming
1
Confirm prerequisites
Check compatibility, account access, firmware, network, and physical access before changing the Start Move-Based Programming setup.
The to Move-Based Programming
2
Make one change at a time
Apply the setup steps in order so any connection, pairing, or permission failure is easy to isolate.
3
Verify the result
Test the final state from the app and from the physical device before adding automations or optional settings.

Create a new Move module structure

Move is a programming language based on Rust that was originally developed for Meta's Diem project. It was designed to be a universal language targeting the unique qualities of smart contract programming. Move's first class abstractions for the concept of assets, transfers, and access control make for safer and more efficient programming [1]. This section walks you through initializing a project and understanding the basic file structure of a Move module.

move-based programming
1
Initialize the project with Move CLI

Move allows developers to write programs that flexibly manage and transfer assets, while providing the security and protections against attacks on those assets [2]. To begin, use the Move CLI to create a new project. Run move init <package-name> in your terminal. This command scaffolds the directory structure, creating the necessary folders for your code. The CLI sets up the foundation for your smart contract, ensuring all paths are correctly configured for compilation and testing.

2
Locate the Move.toml configuration

Every Move project starts with a Move.toml file in the root directory. This file defines the project's metadata, dependencies, and compiler settings. It acts as the manifest for your module, telling the Move compiler how to build your code. You will edit this file to add external dependencies or change the language version. It is the single source of truth for your project's configuration.

3
Explore the sources directory

Inside your project, the sources folder holds your Move modules. When you create a new module, the CLI generates a .move file here. This is where you write your logic. Each file corresponds to a module, and the file name must match the module name. For example, a file named mymodule.move contains module mymodule { ... }. Keep your code organized by grouping related modules into subdirectories.

4
Understand the test structure

The tests folder contains your test scripts. Move uses Move script files for testing, which are distinct from modules. These scripts allow you to interact with your deployed modules in a simulated environment. When you run move test, the compiler looks for these files. Writing tests alongside your modules ensures your code works as intended before you deploy it to a blockchain.

The structure above provides a clear separation between configuration, logic, and testing. This organization is critical for maintaining large Move projects. As you develop, you will add more modules to the sources folder and corresponding tests to the tests folder. The Move CLI handles the compilation process, ensuring that all modules are correctly linked and type-checked before deployment.

Define first-class resources and assets

Move treats digital assets as first-class citizens through its resource model. Unlike standard data types, resources cannot be copied or discarded implicitly. This design prevents the duplication of tokens and ensures that every asset has a single, verifiable owner at any given time.

When you define a resource in Move, you are creating a secure container for value. The language enforces strict ownership rules at the compiler level. If you attempt to copy a resource or leave it in a state where it might be lost, the code will not compile. This shifts security from runtime checks to compile-time guarantees.

Consider the difference between a standard ERC-20 token and a Move resource. In many older languages, tokens are just balances in a ledger. If a smart contract has a bug, an attacker might duplicate those balances. In Move, the asset itself is the object. You cannot create a second copy of that object without destroying the first. This makes double-spending virtually impossible by design.

This approach simplifies the logic for developers. You do not need to write complex checks to ensure a token hasn't been spent twice. The language handles the safety guarantees for you. As noted in the official Move documentation, this allows developers to write programs that "flexibly manage and transfer assets, while providing the security and protections against attacks on those assets" [src-serp-2].

1
Define the resource struct

Create a struct that implements the key and store abilities. These abilities mark the struct as a resource that can be held in storage but not copied or destroyed implicitly.

2
Implement transfer functions

Write functions that move the resource from one account to another. Ensure that the source account no longer holds the resource after the transfer.

3
Handle destruction explicitly

If a resource is meant to be burned or removed, write a dedicated function that explicitly drops the resource. Never rely on implicit destruction.

By defining resources this way, you build a foundation where assets are safe by default. This is particularly important in high-stakes financial applications where the cost of a bug is high. The Move language ensures that your assets remain intact, regardless of how complex your smart contract logic becomes.

move-based programming

Write and test a simple transaction

Writing a transaction in Move requires defining a function that handles resource creation or transfer. Unlike traditional smart contracts where assets are just balances, Move treats assets as first-class citizens that must be explicitly moved or dropped. This structure prevents common errors like double-spending.

Follow these steps to create a basic transaction that transfers a resource.

1
Define the resource structure

Start by defining the struct that represents your asset. In Move, resources must be marked with key and store capabilities to be stored in accounts or transferred. For a simple example, define a Coin struct with a value field.

2
Write the transfer function

Create a public function that accepts the sender’s address and the recipient’s address. Use the transfer function from the object module to move the resource from the sender to the recipient. Ensure the function signature includes signer for the sender to prove ownership.

3
Add unit tests

Move uses the mover tool for testing. Write a test function marked with #[test] that initializes a mock account. Create the resource, call your transfer function, and assert that the recipient’s balance has increased and the sender’s has decreased. This verifies the logic before deployment.

Testing locally is critical because Move’s type system catches many errors at compile time, but runtime logic still needs verification. Use mover test to run your unit tests. If the tests pass, you can be confident the transaction behaves as expected. For more details on Move’s testing framework, refer to the official Move documentation.

Once your tests pass, you can package the module and prepare it for deployment to a testnet. Remember that Move modules are reusable, which promotes efficient development and reduces redundancy across your project.

Deploy to the Sui testnet

To move your Move-based smart contracts from local testing to a live environment, you will deploy them to the Sui testnet. This network provides a stable, public environment for validating your code before it reaches the mainnet. The Sui CLI tools handle the compilation, publishing, and interaction processes, ensuring your modules are correctly formatted and secured.

move-based programming
1
Set up your wallet and fund it

Before deploying, you need a Sui-compatible wallet, such as Sui Wallet or Ethos Wallet, with SUI tokens in the testnet network. You can obtain free testnet SUI from the Sui Faucet by providing your wallet address. This balance covers the transaction fees (gas) required for publishing your module.

move-based programming
2
Compile and publish the module

Use the Sui CLI to compile your Move code and publish it to the testnet. Run the command sui client publish --gas-budget 50000000 from your project directory. This command packages your module and sends a transaction to the network. The CLI will return a package ID, which is the unique identifier for your deployed smart contract.

move-based programming
3
Interact with your deployed module

Once published, you can call your module's functions using the Sui CLI. Use sui client call to execute functions, passing the package ID and function name. For example, to call a function named init, you would run sui client call --package <PACKAGE_ID> --module <MODULE_NAME> --function init. This step verifies that your contract logic works as expected on the public network.

move-based programming
4
Verify the transaction on a block explorer

After each transaction, check the Sui Explorer to confirm the state changes. Copy the transaction digest from the CLI output and paste it into the explorer search bar. This allows you to view the event logs, gas fees, and the new state of your objects, providing transparency and proof of execution on the Sui testnet.

Common Move Programming Mistakes

Even with Move’s safety guarantees, developers can still introduce bugs or inefficiencies. The language’s strict ownership model is powerful, but it requires a shift in thinking from traditional Rust or Solidity development. Ignoring these nuances often leads to compilation errors or, worse, unexpected runtime behavior in production.

Misusing Resource Capabilities

Move treats assets as resources, which cannot be copied or dropped implicitly. A common error is attempting to copy a resource handle or failing to properly transfer ownership. This isn’t just a syntax preference; it’s the core mechanism preventing double-spending. If you try to duplicate a resource without using the correct copy capability, the compiler will reject it. Conversely, dropping a resource without burning it can lead to lost value. Always ensure resources are either transferred to another account, stored in a struct, or explicitly burned.

Ignoring Gas Costs in PTBs

In Move, gas costs are explicit and predictable, but they can still trip up developers building Pay-To-Byte (PTB) transactions. Each operation, from moving a resource to calling a function, consumes gas. If your transaction exceeds the block’s gas limit, the entire transaction fails. This is different from Ethereum’s EVM, where out-of-gas errors can leave partial state changes. In Move, it’s all or nothing. Always estimate gas consumption during testing and account for the overhead of multiple actions within a single PTB.

move-based programming

Frequently asked questions about move

What is move programming?

Move is a programming language designed specifically for smart contracts. Originally developed for Meta’s Diem blockchain, it focuses on the unique requirements of digital assets. It provides first-class abstractions for resources, ensuring that assets like tokens are transferred securely rather than simply copied.

What programming language is move based on?

Move is built on top of Rust. This foundation gives it strong type safety and memory safety guarantees. By adopting Rust’s syntax and tooling, Move allows developers to leverage familiar patterns while adding specialized features for blockchain state management.

Why was move created?

The language was created to solve safety issues in smart contract development. Traditional blockchains often treat assets as simple balances, which can lead to reentrancy attacks or accidental duplication. Move treats assets as unique resources that can only be moved, not copied, preventing these common vulnerabilities.