Modules and Build System
This section treats with the basic functionality of the module and build system for Move.
Packages
A folder with a Move.toml
and compilable move code is a package. Packages may define external dependencies, which can be local or store at a remote repository. All Move clients used herein will automatically fetch and compile dependencies. When using movement
, we will also define package addresses in the Move.toml
.
[package]
name = "hello_world"
version = "0.0.0"
[dependencies]
# MoveNursery = { git = "https://github.com/move-language/move.git", subdir = "language/move-stdlib/nursery", rev = "main" }
MovementFramework = { git = "https://github.com/movemntdev/movement-subnet.git", subdir = "vm/aptos-vm/aptos-move/aptos-framework", rev = "main" }
[addresses]
std = "0x1"
hello_blockchain = "_"
Program types
Move has two different types of program: modules and scripts. As a general rule, you should use scripts for short proofs of concept or as an entrypoint, see Script Based Design. You can define multiple scripts and modules in the same file.
Modules
Modules are great for code reuse. They can be reference and linked. A module takes the following form.
#![allow(unused)] fn main() { module <address>::<identifier> { (<use> | <friend> | <type> | <function> | <constant>)* } }
When attempting to use logic in a module, you must specify the member function that you wish to call.
Scripts
Scripts are a slightly easier to use alternative to modules. They take the following form.
#![allow(unused)] fn main() { script { <use>* <constants>* fun <identifier><[type parameters: constraint]*>([identifier: type]*) <function_body> } }
Scripts can only have one function in their body.
Within the context of movement
, we will not be using scripts--instead preferring the module construct.
Building
When developing modules in Move you will need to publish the module before being able to run. The exception to this rule is when using movement
to run unit tests. movement move publish
will handle both the building and publication of modules in your current working directory. If you simply want to build the module to inspect its bytecode run movement move build
.
Below is an example bash script for publishing and running a function in a module end-to-end using the Movement CLI drawn from 💻 hello_blockchain
.
#!/bin/bash -e
# Function to echo text as cyan with emoji
function begin() {
echo -e "🔹 \033[36m$1\033[0m"
}
# Function to echo text as green with increased font-weight and emoji
function finish() {
echo -e "✅ \033[1;32m$1\033[0m"
}
begin "Funding account for hello_blockchain deployment and call..."
movement account fund-with-faucet --account default
finish "Funded account for hello_blockchain deployment and call!"
begin "Publishing hello_blockchain module..."
echo "y" | movement move publish --named-addresses hello_blockchain=default
finish "Published hello_blockchain module!"
begin "Setting hello_blockchain message to 'hello!'..."
echo "y" | movement move run --function-id default::message::set_message --args string:hello!
finish "Set hello_blockchain message to 'hello'!"
begin "Querying resources for account..."
movement account list --query resources --account default
finish "Queryed resourced for account!"
named_addresses
The Move build system enables the usage of named addresses to simplify addressing schemes. These will be replaced at compile time whether they are in the adrress position in a module <my_address_name>::my_module
or marked with an @<my_address_name>
elsewhere.
In your Move.toml
, you may specify these addresses as below.
[addresses]
std = "0x1"
<my_address_name> = "_"
You may then specify them when compiling using --<my_address_name>=<my_value>
.
Additional complexities that emerge when using named addresses are well documented in Diem's original documentation of the Move language.
💻 resource_roulette
dev-addresses
Resource roulette currently has a value in the [addresses]
block that is better suited to [dev-addresses]
. Find it an test the module.