Let's say I have a Move script like this:
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);
let balance = coin::balance<aptos_coin::AptosCoin>(src_addr);
if (balance < desired_balance) {
aptos_account::transfer(src, dest, desired_balance - balance);
};
addr::my_module::do_nothing();
}
}
This is calling functions on the aptos_coin.move module, which is deployed on chain. What it does isn't so important for this question, but in short, it checks that the balance of the destination account is less than desired_balance
, and if so, tops it up to desired_balance
.
Notice also how it calls a function in a Move module I've defined:
module addr::my_module {
public entry fun do_nothing() { }
}
Where do I put these files? Do I need a Move.toml
? How do I run my script with the CLI?
Let's run through how to execute a Move script with a step by step example, this should answer all your questions.
Make a new directory to work from:
mkdir testing
cd testing
Setup the Aptos CLI:
aptos init
The CLI will ask you which network you want to work with (e.g. devnet
, testnet
, mainnet
). It will also ask you for your private key (which looks like this: 0xf1adc8d01c1a890f17efc6b08f92179e6008d43026dd56b71e7b0d9b453536be
), or it can generate a new one for you, as part of setting up your account.
From here, initialize a new Move project:
aptos move init --name my_script
Now you need to make a file for your script. So, take the script you created above, and put it in sources/
, e.g. like this:
testing/
Move.toml
sources/
top_up.move
In other words, top_up.move
should contain the script you included in the question.
Now do the same thing with the Move module, leaving you with this:
testing/
Move.toml
sources/
top_up.move
my_module.move
Now you can compile the script:
$ aptos move compile --named-addresses addr=81e2e2499407693c81fe65c86405ca70df529438339d9da7a6fc2520142b591e
Compiling, may take a little while to download git dependencies...
INCLUDING DEPENDENCY AptosFramework
INCLUDING DEPENDENCY AptosStdlib
INCLUDING DEPENDENCY MoveStdlib
BUILDING my_script
{
"Result": []
}
Note how I use the --named-addresses
argument. This is necessary because in your code, you refer to this named address called addr
. The compiler needs to know what this refers to. Instead of using this CLI argument, you could put something like this in your Move.toml
:
[addresses]
addr = "b078d693856a65401d492f99ca0d6a29a0c5c0e371bc2521570a86e40d95f823"
Finally you can run the compiled script:
$ aptos move run-script --compiled-script-path build/my_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": "0x655f839a45c5f14ba92590c321f97c3c3f9aba334b9152e994fb715d5648db4b",
"gas_used": 178,
"gas_unit_price": 100,
"sender": "81e2e2499407693c81fe65c86405ca70df529438339d9da7a6fc2520142b591e",
"sequence_number": 53,
"success": true,
"timestamp_us": 1669811892262502,
"version": 370133122,
"vm_status": "Executed successfully"
}
}
Note that the path of the compiled script is under build/my_script/
, not build/top_up/
. This is because it uses the name of the project contained in Move.toml
, which is my_script
from when we ran aptos move init --name my_script
.
So to answer one of your questions, yes you need a Move.toml
, you can't currently just execute a script file on its own with the CLI. The compiler needs this determine what Aptos framework to use for example.
See the code used in this answer here: https://github.com/banool/move-examples/tree/main/run_script.
See also how to do this with the Rust SDK instead of the CLI: How do I execute a Move script on Aptos using the Rust SDK?.
P.S. There is a more streamlined way to execute a script. 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 do both steps with a single CLI command. Note however that there are some major footguns with this approach, see https://github.com/aptos-labs/aptos-core/issues/5733. So I'd recommend using the previous two-step approach for now.