Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move hello world example built from source
Browse files Browse the repository at this point in the history
ksolana committed Jun 15, 2024
1 parent 09c1f80 commit f2f458d
Showing 9 changed files with 216 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "hello"
version = "1.0.0"

[addresses]
hello = "0xba31"

[dependencies]
MoveStdlib = { local = "../../../../../crates/move-stdlib", addr_subst = { "std" = "0x1" } }
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
## This is a hello world style example

The test
- Builds the .move files in this project to create a binary in `build` directory
- Deploys a program `build/hello.so` to a running validator
- Invokes the program using a client app
- Checks that the output matches expected output.

Prerequisites:
- Run `yarn install`
- Sufficient account balance in your `~/.config/solana/id.json` account
- A running local validator

To run this test
- Start a local solana validator.
- Run `yarn build` to build move program.
- Run `yarn test` from this directory to deploy and test the program.
- Run `yarn deploy` to deploy the program. Note that `yarn test` deploys program separately regardless of `yarn deploy`.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash
# Script to build move project using the move-cli
# It also builds move-cli if not built already

# A POSIX variable
OPTIND=1 # Reset in case getopts has been used previously in the shell.

# Initialize our own variables:
output_file=""
verbose=""
rebuild=""
OPTSTRING=":h?:v:r"

while getopts ${OPTSTRING} opt; do
case "$opt" in
h|\?)
exit 0
;;
v) verbose="-vv --message-format=json"
;;
r) rebuild="1"
esac
done

shift $((OPTIND-1))

[ "${1:-}" = "--" ] && shift

echo "verbose='$verbose', output_file='$output_file', rebuild='$rebuild', Leftovers: $@"

if [ -n "${rebuild}" ]; then
echo "Rebuilding the move cli"
cargo build -p move-cli --bin move --features solana-backend $verbose
fi

../../../../../target/debug/move build --arch solana -p sources/hello.move -v

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"program_id": "DozgQiYtGbdyniV2T74xMdmjZJvYDzoRFFqw7UR5MwPK",
"accounts": [
{
"key": "524HMdYYBy6TAn4dK5vCcjiTmT2sxV6Xoue5EXrz22Ca",
"owner": "BPFLoaderUpgradeab1e11111111111111111111111",
"is_signer": false,
"is_writable": true,
"lamports": 1000,
"data": [0, 0, 0, 3]
}
],
"instruction_data": [
11, 0, 0, 0, 0, 0, 0, 0,
104, 101, 108, 108, 111, 95, 95, 109, 97, 105, 110]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"scripts": {
"test": "pnpm ts-mocha -p ./tsconfig.json -t 1000000 ./tests/test.ts",
"build": "./cicd.sh",
"deploy": "pnpm ts-mocha -p ./tsconfig.json -t 1000000 ./tests/deploy.ts"
},
"dependencies": {
"@solana/web3.js": "^1.47.3"
},
"devDependencies": {
"@types/bn.js": "^5.1.0",
"@types/chai": "^4.3.1",
"@types/mocha": "^9.1.1",
"chai": "^4.3.4",
"mocha": "^9.0.3",
"solana-bankrun": "^0.3.0",
"ts-mocha": "^10.0.0",
"typescript": "^4.3.5"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// input ../input.json
// use-stdlib
// log 0000000000000000000000000000000000000000000000000000000000000001::string::String { bytes: [72, 101, 108, 108, 111, 32, 83, 111, 108, 97, 110, 97], }

module 0x10::debug {
native public fun print<T>(x: &T);
}

module hello::hello {
use 0x10::debug;
use 0x1::string;

public entry fun main() : u64 {
let rv = 0;
let s = string::utf8(b"Hello Solana");
debug::print(&s);
rv
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { describe } from 'node:test';
import { assert } from 'chai';
import {deployProgramShell, parseProgramID} from './validator_utils';

describe("deploy-solana", async () => {
const programPath = 'build/solana/hello.so';
const programIdLog = await deployProgramShell(programPath);
const programId = parseProgramID(programIdLog);
it("Deploy hello!", async () => {
if (programId) {
assert(programId.length == 45);
console.log('Program deployed with', programId);
return 0;
}
return -1;
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { describe, test } from 'node:test';
import { assert } from 'chai';
import {deployProgramShell, parseProgramID} from './validator_utils';

import {
Connection,
Keypair,
PublicKey,
sendAndConfirmTransaction,
Transaction,
TransactionInstruction,
} from '@solana/web3.js';

function createKeypairFromFile(path: string): Keypair {
return Keypair.fromSecretKey(
Buffer.from(JSON.parse(require('fs').readFileSync(path, "utf-8")))
)
};

function getInstructionData(path: string): Buffer {
// instruction_data (See: sui/external-crates/move/solana/move-mv-llvm-compiler/docs/Entrypoint.md)
let j = JSON.parse(require('fs').readFileSync(path, "utf-8"));
return j['instruction_data'];
}

async function deployProgram(programPath: string) : Promise<string> {
const programIdLog = await deployProgramShell(programPath);
const programId = await parseProgramID(programIdLog);
if (programId) {
return programId;
}
return null;
}

describe("hello-solana", async () => {
// Loading these from local files for development
const connection = new Connection(`http://localhost:8899`, 'confirmed');
const payer = createKeypairFromFile(require('os').homedir() + '/.config/solana/id.json');
// PublicKey of the deployed program.
const programPath = 'build/solana/hello.so';
const instructionData = getInstructionData('input.json');

it("Say hello!", async () => {
const programIdStr = await deployProgram(programPath);
const programId = new PublicKey(programIdStr);
// Set up transaction instructions first.
let ix = new TransactionInstruction({
keys: [
{pubkey: payer.publicKey, isSigner: true, isWritable: true}
],
programId,
data: instructionData,
});

// Send the transaction over RPC
let signature = await sendAndConfirmTransaction(
connection,
new Transaction().add(ix), // Add our instruction (you can add more than one)
[payer]
);

let transaction = await connection.getTransaction(signature, {commitment: "confirmed"});
assert(transaction?.meta?.logMessages[0].startsWith(`Program ${programId}`));
// 'Hello Solana' as bytes
assert(transaction?.meta?.logMessages[1] === 'Program log: 0000000000000000000000000000000000000000000000000000000000000001::string::String { bytes: [72, 101, 108, 108, 111, 32, 83, 111, 108, 97, 110, 97], }');
assert(transaction?.meta?.logMessages[2] === `Program ${programId} consumed 5331 of 200000 compute units`);
assert(transaction?.meta?.logMessages[3] === `Program ${programId} success`);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"types": ["mocha", "chai"],
"typeRoots": ["./node_modules/@types"],
"lib": ["es2015"],
"module": "commonjs",
"target": "es6",
"esModuleInterop": true
}
}

0 comments on commit f2f458d

Please sign in to comment.