Move Scripts
This tutorial explains how to write and execute a Move script. You can use Move scripts to execute a series of commands across published Move module interfaces.
For more information about scripts, see the Move scripts docs
Example use case
The following example calls functions on the aptos_coin.move module to confirm the balance of the destination account is less than desired_balance
, and if so, tops it up to desired_balance
.
script {
use std::signer;
use aptos_framework::aptos_account;
use aptos_framework::aptos_coin;
use aptos_framework::coin;
fun main(src: &signer, dest: address, desired_balance: u64) {
let src_addr = signer::address_of(src);
addr::my_module::do_nothing();
let balance = coin::balance<aptos_coin::AptosCoin>(src_addr);
if (balance < desired_balance) {
aptos_account::transfer(src, dest, desired_balance - balance);
};
}
}
Execution
Now that you know what you would like to accomplish, you need to determine:
- Where do I put these files?
- What do I name them?
- Do I need a
Move.toml
? - How do I run my script with the CLI?
Let us run through how to execute a Move script with a step-by-step example using the Aptos CLI.
-
Make a new directory for your work:
Terminalmkdir testing cd testing
-
Set up the Aptos CLI and create an account:
Terminalaptos init --network devnet
You may reuse an existing private key (which looks like this:
0xbd944102bf5b5dfafa7fe865d8fa719da6a1f0eafa3cd600f93385482d2c37a4
), or it can generate a new one for you, as part of setting up your account. Letβs say your account looks like the example below:Terminal--- profiles: default: private_key: "0xbd944102bf5b5dfafa7fe865d8fa719da6a1f0eafa3cd600f93385482d2c37a4" public_key: "0x47673ec83bb254cc9a8bfdb31846daacd0c96fe41f81855462f5fc5306312b1b" account: cb265645385819f3dbe71aac266e319e7f77aed252cacf2930b68102828bf615 rest_url: "https://api.devnet.aptoslabs.com" faucet_url: "https://faucet.devnet.aptoslabs.com"
-
From this same directory, initialize a new Move project:
Terminalaptos move init --name run_script
-
Create a
my_script.move
file containing the example script above in asources/
subdirectory of yourtesting/
directory. Also, create amy_module.move
file as seen in the example below:module addr::my_module { public entry fun do_nothing() { } }
This results in the following file structure:
- Move.toml
- my_script.move
- my_module.move
-
Compile the script:
Terminal$ aptos move compile --named-addresses addr=cb265645385819f3dbe71aac266e319e7f77aed252cacf2930b68102828bf615 Compiling, may take a little while to download git dependencies... INCLUDING DEPENDENCY AptosFramework INCLUDING DEPENDENCY AptosStdlib INCLUDING DEPENDENCY MoveStdlib BUILDING run_script { "Result": [ "cb265645385819f3dbe71aac266e319e7f77aed252cacf2930b68102828bf615::my_module" ] }
Note how we use the
--named-addresses
argument. This is necessary because in the code we refer to this named address calledaddr
. The compiler needs to know what this refers to. Instead of using this CLI argument, you could put something like this in yourMove.toml
:[addresses] addr = "cb265645385819f3dbe71aac266e319e7f77aed252cacf2930b68102828bf615"
-
Run the compiled script:
Terminal$ aptos move run-script --compiled-script-path build/run_script/bytecode_scripts/main.mv --args address:b078d693856a65401d492f99ca0d6a29a0c5c0e371bc2521570a86e40d95f823 --args u64:5 Do you want to submit a transaction for a range of [17000 - 25500] Octas at a gas unit price of 100 Octas? [yes/no] > yes { "Result": { "transaction_hash": "0xa6ca6275c73f82638b88a830015ab81734a533aebd36cc4647b48ff342434cdf", "gas_used": 3, "gas_unit_price": 100, "sender": "cb265645385819f3dbe71aac266e319e7f77aed252cacf2930b68102828bf615", "sequence_number": 4, "success": true, "timestamp_us": 1683030933803632, "version": 3347495, "vm_status": "Executed successfully" } }
Note that the path of the compiled script is under build/run_script/
, not build/my_script/
. This is because it uses the name of the project contained in Move.toml
, which is run_script
from when we ran aptos move init --name run_script
.
See the code used for this document. The full example explains how to use a Move script that relies on a user-created Move module as well.
See also how to do this with the Rust SDK instead of the Aptos CLI in Aptos Developer Discussions.
Advanced
You may execute a script in a more streamlined fashion; instead of running aptos move compile
and then aptos move run-script --compiled-script-path
separately, you can just do this:
$ aptos move run-script --script-path sources/my_script.move --args address:b078d693856a65401d492f99ca0d6a29a0c5c0e371bc2521570a86e40d95f823 --args u64:5
This will conduct both steps with a single CLI command yet has issues. For this reason, we recommend using the previous two-step approach for now.