The iota move command provides tools for developing Move smart contracts on IOTA.
Basic Usage
iota move [OPTIONS] [SUBCOMMAND]
Global Options
--path <PATH> or -p <PATH> - Path to the package directory (defaults to current directory)
--client.config <PATH> - Custom config file
--client.env <ENV> - Network environment to use
Build Configuration Options
All Move commands support standard Move build options:
--dev - Compile in development mode
--test - Compile in test mode
--generate-docs - Generate documentation
--generate-abis - Generate ABIs
--install-dir <PATH> - Installation directory for compiled packages
--force - Force recompilation
--fetch-deps-only - Only fetch dependencies
--skip-fetch-latest-git-deps - Skip fetching latest git dependencies
Commands
build
Compile a Move package:
iota move build [OPTIONS]
Options
--dump-bytecode-as-base64 - Output bytecode as base64 (requires network connection)
--with-unpublished-dependencies - Include unpublished dependencies
--chain-id <ID> - Build for specific chain
--ignore-chain - Ignore chain ID validation
Examples
Basic build
cd my_package
iota move build
Output: INCLUDING DEPENDENCY Iota
INCLUDING DEPENDENCY MoveStdlib
BUILDING my_package
Build with dependencies
This forces rebuilding all dependencies.
Generate documentation
iota move build --generate-docs
Documentation is generated in build/my_package/docs/.
Build for publishing
iota move build --dump-bytecode-as-base64
This prepares the package for publishing by:
Resolving on-chain addresses from Move.lock
Performing tree-shaking optimization
Outputting base64-encoded bytecode
Build Artifacts
Successful builds create:
my_package/
├── Move.toml
├── sources/
└── build/
├── my_package/
│ ├── bytecode_modules/ # Compiled bytecode
│ ├── source_maps/ # Debug info
│ ├── sources/ # Processed source
│ └── docs/ # Generated docs
└── BuildInfo.yaml # Build metadata
test
Run Move unit tests:
iota move test [OPTIONS] [FILTER]
Options
<FILTER> - Filter tests by name (regex pattern)
--num-threads <N> - Number of threads for parallel execution
--gas-limit <AMOUNT> - Gas limit per test
--list - List tests without running
--coverage - Collect coverage information
Examples
Run all tests
Output: INCLUDING DEPENDENCY Iota
INCLUDING DEPENDENCY MoveStdlib
BUILDING my_package
Running Move unit tests
[ PASS ] 0x0::my_module::test_transfer
[ PASS ] 0x0::my_module::test_balance
Test result: OK. Total tests: 2; passed: 2; failed: 0
Run specific tests
# Run tests matching pattern
iota move test "test_transfer"
# Run all tests in a module
iota move test "my_module::"
Parallel testing
iota move test --num-threads 4
Test Output
Tests can have several outcomes:
[ PASS ] - Test passed
[ FAIL ] - Test failed with assertion error
[ TIMEOUT ] - Test exceeded gas limit
[ ERROR ] - Test encountered execution error
new
Create a new Move package:
Example
This creates:
my_package/
├── Move.toml
└── sources/
└── my_package.move
Move.toml
[ package ]
name = "my_package"
version = "0.0.1"
edition = "2024.beta"
[ dependencies ]
Iota = { git = "https://github.com/iotaledger/iota.git" , subdir = "crates/iota-framework/packages/iota-framework" , rev = "framework/mainnet" }
[ addresses ]
my_package = "0x0"
coverage
Generate code coverage reports:
iota move coverage [OPTIONS]
Options
--module <NAME> - Module to analyze
--summary - Show summary statistics
--output-csv <PATH> - Export to CSV
Example
Run tests with coverage
iota move test --coverage
View coverage report
iota move coverage --summary
Output: Module 0x0::my_module
├── % covered: 87.5
├── uncovered locations:
│ ├── my_module.move:42
│ └── my_module.move:58
Export coverage
iota move coverage --output-csv coverage.csv
disassemble
Disassemble compiled bytecode:
iota move disassemble [OPTIONS]
Options
--package <NAME> - Package name
--module <NAME> - Module to disassemble
Example
iota move disassemble --module my_module
Output:
// Move bytecode v6
module 0.my_module {
struct Coin {
value: u64
}
public transfer(Arg0: Coin, Arg1: address) {
L0:
0: MoveLoc[0](Arg1: address)
1: MoveLoc[1](Arg0: Coin)
2: TransferObjects([1], 0)
3: Ret
}
}
manage-package
Manage package configurations and dependencies:
iota move manage-package [OPTIONS] [SUBCOMMAND]
Subcommands
add - Add a dependency
remove - Remove a dependency
upgrade - Upgrade dependencies
Examples
# Add dependency
iota move manage-package add \
--name SomePackage \
--git https://github.com/org/package \
--rev main
# Remove dependency
iota move manage-package remove --name SomePackage
# Upgrade all dependencies
iota move manage-package upgrade
migrate
Migrate packages between protocol versions:
iota move migrate [OPTIONS]
Publishing Packages
Publish a Move package to the network:
iota client publish [OPTIONS] [PACKAGE_PATH]
Options
--skip-dependency-verification - Skip verifying dependencies
--with-unpublished-dependencies - Publish transitive dependencies
--gas <ID>... - Gas payment coins
--gas-budget <AMOUNT> - Gas budget
Examples
Basic publish
cd my_package
iota client publish --gas-budget 100000000
Output: INCLUDING DEPENDENCY Iota
INCLUDING DEPENDENCY MoveStdlib
BUILDING my_package
Successfully verified dependencies on-chain against source.
Transaction Digest: 5KzKVq7qP2xH8FwkQJqxhPNBjkFVjM3xZoJpP5KwqAkH
╭───────────────────────────────────────────────────────────╮
│ Object Changes │
├───────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ├─ ID: 0xabc...123 │
│ │ Owner: Immutable │
│ │ Type: 0x2::package::UpgradeCap │
│ ├─ ID: 0xdef...456 │
│ Owner: Account(0x789...) │
│ Type: 0x2::package::Package │
╰───────────────────────────────────────────────────────────╯
Save the Package ID and UpgradeCap ID for future upgrades.
Publish with unpublished dependencies
iota client publish \
--with-unpublished-dependencies \
--gas-budget 200000000
This publishes any dependencies that haven’t been published yet.
Skip dependency verification
iota client publish \
--skip-dependency-verification \
--gas-budget 100000000
Only use this during development. Production packages should always verify dependencies.
Upgrading Packages
Upgrade a published package:
iota client upgrade [OPTIONS] [PACKAGE_PATH]
Options
--upgrade-capability <ID> - UpgradeCap object ID (required)
--verify-compatibility - Check upgrade compatibility
--skip-dependency-verification - Skip verifying dependencies
--with-unpublished-dependencies - Upgrade transitive dependencies
--gas <ID>... - Gas payment
--gas-budget <AMOUNT> - Gas budget
Example
Modify your package
Make changes to your Move code in sources/.
Upgrade the package
iota client upgrade \
--upgrade-capability 0xabc...123 \
--verify-compatibility \
--gas-budget 100000000
Output: INCLUDING DEPENDENCY Iota
INCLUDING DEPENDENCY MoveStdlib
BUILDING my_package
Successfully verified dependencies on-chain against source.
Compatibility verification passed!
Transaction Digest: 7NpQvR8sT3yK9LqDpM4jVfXhZcBwNrYkWxGsHcKqPaJm
Upgrade Compatibility
The --verify-compatibility flag checks:
No public function signatures changed
No struct fields removed or reordered
No resource storage layout changes
All new code follows upgrade rules
Dependency Management
Move.toml Configuration
Dependencies are declared in Move.toml:
[ dependencies ]
# IOTA framework (required)
Iota = {
git = "https://github.com/iotaledger/iota.git" ,
subdir = "crates/iota-framework/packages/iota-framework" ,
rev = "framework/mainnet"
}
# Local dependency
MyLibrary = { local = "../my_library" }
# Git dependency with specific revision
SomePackage = {
git = "https://github.com/org/package" ,
rev = "v1.0.0"
}
# Published on-chain dependency
PublishedPackage = {
address = "0x1234567890abcdef"
}
Move.lock File
The Move.lock file tracks resolved dependencies:
[ move ]
version = 2
manifest_digest = "..."
deps_digest = "..."
[[ move . package ]]
name = "Iota"
source = { git = "..." , rev = "..." , subdir = "..." }
[[ move . package ]]
name = "MoveStdlib"
source = { git = "..." , rev = "..." , subdir = "..." }
Commit Move.lock to version control for reproducible builds.
Source Verification
Verify on-chain packages match local source:
iota client verify-source [OPTIONS] [PACKAGE_PATH]
Options
--verify-deps - Also verify dependencies
--skip-source - Only verify dependencies
--address-override <ADDRESS> - Override package address
Example
iota client verify-source . --verify-deps
Output:
Successfully verified source against on-chain bytecode
Dependencies verified:
- Iota: OK
- MoveStdlib: OK
Best Practices
Development Workflow
Create package
iota move new my_package
cd my_package
Write code and tests
Add your Move code in sources/ and tests with #[test] annotations.
Build and test
iota move build
iota move test
Test on local network
# Start local network
iota start --force-regenesis
# In another terminal, publish
iota client publish --gas-budget 100000000
Verify and publish to testnet
# Switch to testnet
iota client switch --env testnet
# Get test tokens
iota client faucet
# Publish
iota client publish --gas-budget 100000000
Testing Tips
Write comprehensive tests :
#[test]
fun test_transfer () {
// Test normal case
}
#[test]
#[expected_failure(abort_code = EInsufficientBalance)]
fun test_transfer_insufficient_balance () {
// Test error case
}
Use test-only functions :
#[test_only]
public fun create_for_testing (ctx: & mut TxContext ): MyObject {
// Test helper
}
Test with realistic gas limits :
iota move test --gas-limit 100000000
Security Checklist
Troubleshooting
Build Errors
Error : Failed to resolve dependencies
# Clear build cache
rm -rf build/
# Rebuild
iota move build
Error : Address resolution failed
Check that Move.toml has correct address mappings:
[ addresses ]
my_package = "0x0" # Use 0x0 for unpublished packages
Test Failures
Error : Test exceeded gas limit
Increase gas limit:
iota move test --gas-limit 200000000
Error : Module not found
Ensure dependencies are built:
iota move build
iota move test
Publishing Issues
Error : Dependency verification failed
Dependencies must be published to the same network:
# Publish dependencies first, or use:
iota client publish --with-unpublished-dependencies
Error : Insufficient gas
Increase gas budget:
iota client publish --gas-budget 200000000
Next Steps
Testing Guide Learn advanced testing techniques
Transaction Builder Build complex transactions with PTB