This is a demo of running Move language programs on Solana.
It specifies minimum feature requirements, outlines a minimal workflow for building, deploying and running Move programs, demos comparable existing workflows on Sui and Solana, describes implementation details and a roadmap.
- Requirements
- Which toolset should Solana-Move integrate with?
- Running the Solana-Move demo
solana-move
commands discussion- Calling Move programs from the client
- Handling on-chain bytecode dependencies
- An interim storage model
- Proposed roadmap
- Running the Sui example demo
- Running the Solana example demo
We want to aim to demo the following:
- Build contracts, with dependencies (source, local bytecode, on-chain bytecode)
- Test contracts on rbpf
- Deploy and re-deploy contracts to a localnet
- Call contracts with arguments and return values from Rust client code
- Call contracts with arguments and return values from the CLI
Note that for now we are not demoing on-chain storage.
We can do this in two phases, with the first phase MVP being
- Build contracts, no dependencies
- Test contracts on rbpf
- Deploy and re-deploy contracts to a localnet
- Call contracts with arguments and return values from Rust client code
This MVP forgoes the ability to use dependencies, which will entail locating the corresponding omve bytecode for rbpf programs; and to call programs directly from the CLI, which will require the same, plus introspection and reflection on the interface of the program.
There are two features demonstrated here that are feasible with Move but not with plain Solana:
- Calling arbitrary programs from the CLI, introspecting the called program to get argument types
- Calling dependencies without access to any of their source code, again by using the bytecode.
Since our project is a mashup of Solana, Move, and Sui, there are already 4 main CLI tools involved.
cargo
- The Rust build tool. Solana uses a cargo subcommand,cargo build-bpf
, as well ascargo test
etc.solana
- Used for deploying to Solana, wallets, etc.sui
- All interaction with Move and Suimove
- Move build tools, not typically used directly with Sui
These tools perhaps each have their own different designs and "feels".
I suggest that since we are a Solana project we should attempt to integrate with
and match the solana
experience. Ultimately we might want any new
CLI commands to part of solana
CLI, and to integrate Move features with
existing solana
commands.
For an initial demo I suggest we can do everything necessary with a combination of
the solana
and move
commands.
Beyond that we might work in our own solana-move
CLI, inside the
external-crates/move/solana
subdirectory of Solana's sui fork.
We can consider this a prototype tool with the intent of moving the functionality
elsewhere once proven. Working on the CLI in Solana's sui
fork will avoid
having to work in the main Solana codebase for now, and avoid the scrutiny
of mainline Solana pull requests.
This is aspirational - not all of this works now but is what we are working toward.
You'll need the move
command from Solana's sui
repo,
built with Solana support. This can be done with
cargo build --manifest-path=external-crates/move/Cargo.toml -p move-cli --features=solana-backend
or optionally installed with
cargo install --manifest-path=external-crates/move/Cargo.toml -p move-cli --features=solana-backend
First install the Solana tools following
https://docs.solanalabs.com/cli/install
e.g. the stable toolchain
sh -c "$(curl -sSfL https://release.solana.com/v1.18.9/install)"
Run the test validator:
solana-test-validator
Run
solana config set -u localhost
Otherwise all commands will need a --url localhost
argument.
solana-keygen new
solana airdrop 10
Change to the solana-move
directory and build
cd solana-move
move build --arch=solana
This creates the build
directory containing:
solana/demo/
demo.so
BuildInfo.yml
bytecode_modules/
demo.mv
dependencies/...
source_maps/...
sources/...
...
Note this is mostly the same as the Sui move build,
but there is an rbf dylib, demo.so,
and it's in an arch-specific solana
directory.
move test
Create a re-usable program-keypair.json
.
This contais the address of and signing key to deploy and redeploy.
solana-keygen new -o program-keypair.json
solana program deploy target/sbf-solana-solana/release/demo.so --program-id program-keypair.json
todo
solana-move call --program <address> --module demo --function main --args 10
Compare to: sui move build
, move build
, cargo build-bpf
- Locate and download bytecode for dependencies
- Find move-native, optionally embedded directly in binary
Compare to: sui move test
, move test
, cargo test
Compare to: sui client publish
, solana program publish
Compare to: sui client call
- Parse arguments as move types
- Build solana transactions
todo
I am assuming we want to be able to depend on programs that we don't have the source to. This is something Solana programs can't do - programs must at least publish some interface glue to understand the custom calling and serialization conventions of each program.
A scheme:
- In addition to deploying the rbpf program, we also deploy the bytecode to a separate storage location
- The bytecode storage location is derivable from the rbpf storage location
- The
move-to-solana
/move-cli
etc crates know how to derive this location, deploy it / download it as part of the deploy, build, and call processes. - TODO: what about transitive bytecode dependencies?
At the momement, actually storing data is out of scope for the demo, but I think it's worth saying something about how the storage model is intended to work in the short term.
Firstly, we don't expect it to be secure for now, just to work.
The major facets of how storage is expected to work are:
- Contracts are statically compiled together. That is, programs don't actually call other programs; when I compile a move program that calls another, I download the bytecode for the callee and compile it into the caller.
- There is a dedicated storage program, written in Rust, that all move programs call to write persistent data, and that program "owns" all move-language data.
This obviously has lots of problems, but seems feasible to accomplish within the constraints we have currently.
There are a few main thrusts of work here:
- Creating
solana-move-sdk
crate that can parse move values and prepare solana transactions - Creating the
solana-move
CLI, and especially the solana-move-specificsolana-move call
command (other commands will be identical tomove
andsolana
commands at first. - Deploying and retrieving bytecode for byte-code based dependencies and introspectio.n
- Starting a release process and releasing tools people can try out.
- Moving the storage model forward.
- Create a client SDK crate, perhaps
solana-move-sdk
(vs.solana-sdk
)- This will depend on both existing Solana and Move crates
- Add APIs for parsing move values
- Add APIs for preparing Move transactions
- Write the demo
solana-demo-client
using thesolana-move-sdk
andsolana-client
SDKs, calling the demo program.
- Create
solana-move
crate inexternal-crates/move/solana/
- Set up arg parsing with clap for the commands in this demo
- Include the compiled move-native library directly into the
solana-move
binary - Set up binary releases of
solana-move
that people can test - Make
solana-move build
andsolana-move test
behave likemove build
andmove test
. The Move libraries are reusable so this shouldn't have much code duplication. - Write
solana-move deploy
- crib off ofsolana program deploy
, or just shell out tosolana program deploy
. - Teach
solana-move deploy
to deploy both rbpf and the original bytecode - Create
solana-move call
usingsolana-move-client
- Download and introspect bytecode to get argument types
- Storage model
- Reduce size of compiled output
- Function sections
- LTO
This shows how the Sui workflow works for the features we want to demo with Move on Solana.
First install the Sui tools following
https://docs.sui.io/guides/developer/getting-started/sui-install
You'll need both the sui
and sui-test-validator
.
One option is to install sui
from source, and run sui-test-validator
from the source directory:
git clone https://github.com/MystenLabs/sui.git
cd sui
git checkout origin/testnet -b testnet
# This will put `sui` in your `.cargo/bin` directory for use later
cargo install --path crates/sui
# Run the validator
RUST_LOG=off,sui_node=info cargo run -p sui-test-validator
Configure sui for the local network per instructions:
sui client new-env --alias local --rpc http://127.0.0.1:9000
FIXME: the above doesn't actually work if sui is not alreday configured - you'll have to walk through the interactive setup, providing the same configuration.
sui client faucet && sui client gas
Change to the sui
directory and build
cd sui
sui move build
This creates a build
directory with the contents:
demo/
BuildInfo.yml
bytecode_modules/
demo.mv
dependencies/...
source_maps/...
sources/...
sui move test
sui client publish --gas-budget 10000000
sui client call --package <package-id> --module demo --function main --args 10 --gas-budget 10000000
The package ID will be output by the previous publish
command.
This shows how the Solana workflow works for the features we want to demo with Move on Solana.
First install the Solana tools following
https://docs.solanalabs.com/cli/install
e.g. the stable toolchain
sh -c "$(curl -sSfL https://release.solana.com/v1.18.9/install)"
Run the test validator:
solana-test-validator
Run
solana config set -u localhost
Otherwise all commands will need a --url localhost
argument.
solana-keygen new
solana airdrop 10
Change to the solana
directory:
cd solana
Build the program:
cargo build-bpf
This creates a target
directory with the contents:
sbf-solana-solana/release/
demo.so
cargo test
Create a re-usable program-keypair.json
.
This contais the address of and signing key to deploy and redeploy.
solana-keygen new -o program-keypair.json
solana program deploy target/sbf-solana-solana/release/demo.so --program-id program-keypair.json
todo - this needs to be done from code