Move Scripts Tutorial
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 endless_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 endless_framework::endless_account;
use endless_framework::endless_coin;
use endless_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<endless_coin::EndlessCoin>(src_addr);
if (balance < desired_balance) {
endless_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 Endless CLI.
Make a new directory for your work:
mkdir testing cd testingSet up the Endless CLI and create an account:
endless init --network devnetYou 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:--- profiles: default: private_key: "0xbd944102bf5b5dfafa7fe865d8fa719da6a1f0eafa3cd600f93385482d2c37a4" public_key: "0x47673ec83bb254cc9a8bfdb31846daacd0c96fe41f81855462f5fc5306312b1b" account: cb265645385819f3dbe71aac266e319e7f77aed252cacf2930b68102828bf615 rest_url: "https://api.devnet.endlesslabs.com" faucet_url: "https://faucet.devnet.endlesslabs.com"From this same directory, initialize a new Move project:
endless move init --name run_scriptCreate a
my_script.movefile containing the example script above in asources/subdirectory of yourtesting/directory. Also, create amy_module.movefile as seen in the example below:module addr::my_module { public entry fun do_nothing() { } }This results in the following file structure:
testing/ Move.toml sources/ my_script.move my_module.moveCompile the script:
$ endless move compile --named-addresses addr=cb265645385819f3dbe71aac266e319e7f77aed252cacf2930b68102828bf615 Compiling, may take a little while to download git dependencies... INCLUDING DEPENDENCY EndlessFramework INCLUDING DEPENDENCY EndlessStdlib INCLUDING DEPENDENCY MoveStdlib BUILDING run_script { "Result": [ "cb265645385819f3dbe71aac266e319e7f77aed252cacf2930b68102828bf615::my_module" ] }Note how we use the
--named-addressesargument. 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:
$ endless 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": "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 endless 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 Endless CLI in Endless Developer Discussions.
Last updated