Overview
This tutorial will guide you through the process of building, publishing, and interacting with your own Move modules on the Initia blockchain. Specifically, we'll work with the read_write
module from the initia-tutorials
repository. Here's how to get started:
Tutorial
Step 1: Clone initia-tutorials
First, clone the initia-tutorials
repository, which contains the read_write
module we'll be using.
Copy git clone git@github.com:initia-labs/initia-tutorials.git
Step 2: Build a Module
Before building the module, you need to update the module owner's address to your own address in the Move.toml
configuration file located in ./initia-tutorials/move/read_write
.
How to Get Your HEX Address:
Use the following command to parse your Initia address into bytes format, which is your HEX address.
CLI initia.js
Copy > initiad keys parse [addr]
example output:
Copy bytes: F64D24B10B0CE93CD428DF3AB9228ADB18B93CFE
human: init
Copy import { AccAddress } from '@initia/initia.js' ;
console .log ( AccAddress .toHex ( '[addr]' ));
// 0x7b23641ee96425a5dbe9953bdd949da7f6c5fcb0
Now, modify the Move.toml
file to include your HEX address:
Copy [package]
name = "read_write"
version = "0.0.0"
[dependencies]
InitiaStdlib = { git = "https://github.com/initia-labs/movevm.git" , subdir = "precompile/modules/initia_stdlib" , rev = "main" }
[addresses]
std = "0x1"
your_address = "{insert your hex address here}"
Build the module using either CLI or builder.js:
CLI builder.js
Copy > initiad move build --path ./initia-tutorials/move/read_write
Copy import { MoveBuilder } from '@initia/builder.js' ;
const path =
'${path_to_initia_tutorials}/move/read_write' ;
async function buildModule () {
const builder = new MoveBuilder (path , {});
await builder .build ();
}
buildModule ();
Step 3: Publish a Module
After building your module, the next step is to publish it to the Initia blockchain.
CLI initia.js
Copy > initiad move deploy \
--path ./initia-tutorials/move/read_write \
--upgrade-policy COMPATIBLE \
--from test-account \
--gas auto --gas-adjustment 1.5 \
--gas-prices 0.15uinit \
--node [rpc-url]:[rpc-port] \
--chain-id [chain-id]
Copy import { LCDClient , MnemonicKey , MsgPublish , Wallet } from '@initia/initia.js' ;
import { MoveBuilder } from '@initia/builder.js' ;
import * as fs from 'fs' ;
const path =
'${path_to_initia_tutorials}/move/read_write' ;
async function publishModule () {
const lcd = new LCDClient ( 'https://stone-rest.initia.tech' , {
gasPrices : '0.15uinit' ,
gasAdjustment : '1.5' ,
});
const builder = new MoveBuilder (path , {});
await builder .build ();
const key = new MnemonicKey ({
mnemonic :
'beauty sniff protect ...' ,
});
const wallet = new Wallet (lcd , key);
const codeBytes = fs .readFileSync (
` ${ path } /build/read_write/bytecode_modules/read_write.mv`
);
// const codeBytes = await builder.get('read_write'); // or you can get with MoveBuilder
const msgs = [
new MsgPublish ( key .accAddress , [ codeBytes .toString ( 'base64' )] , 1 ) ,
];
// sign tx
const signedTx = await wallet .createAndSignTx ({ msgs });
// send(broadcast) tx
lcd . tx .broadcastSync (signedTx) .then (res => console .log (res));
// {
// height: 0,
// txhash: '162AA29DE237BD060EFEFFA862DBD07ECD1C562EBFDD965AD6C34DF856B53DC2',
// raw_log: '[]'
// }
}
publishModule ();
About the upgrade policy:
Performs a compatibility check during upgrades, ensuring no public function changes or resource layout modifications.
Marks the modules as immutable, preventing any future upgrades.
Step 4: Interact with Your Published Module
After publishing, you can interact with your module through various Move scripts or direct calls from client applications.
CLI initia.js
Copy > initiad query move view [addr] read_write read \
--node [rpc-url]:[rpc-port]
data: '"initial content"'
> initiad tx move execute [addr] read_write write \
--args "string:new_string" \
--from [key-name] \
--gas auto --gas-adjustment 1.5 --gas-prices 0.15uinit \
--node [rpc-url]:[rpc-port] --chain-id [chain-id]
> initiad query move view [addr] read_write read \
--node [rpc-url]:[rpc-port]
data: '"new_string"'
Copy import {
bcs ,
LCDClient ,
MnemonicKey ,
MsgExecute ,
Wallet ,
} from '@initia/initia.js' ;
async function setNewContent () {
const lcd = new LCDClient ( '[rest-url]' , {
gasPrices : '0.15uinit' ,
gasAdjustment : '1.5' ,
});
const key = new MnemonicKey ({
mnemonic : 'beauty sniff protect ...' ,
});
const wallet = new Wallet (lcd , key);
await lcd .move
.viewFunction ( key .accAddress , 'read_write' , 'read' )
.then (res => console .log ( 'before write:' , res));
const msgs = [
new MsgExecute (
key .accAddress ,
key .accAddress ,
'read_write' ,
'write' ,
[] ,
[ bcs .string () .serialize ( 'new_string' ) .toBase64 ()]
) ,
];
// sign tx
const signedTx = await wallet .createAndSignTx ({ msgs });
// send(broadcast) tx
await lcd . tx .broadcastSync (signedTx) .then (res => console .log (res));
// {
// height: 0,
// txhash: '162AA29DE237BD060EFEFFA862DBD07ECD1C562EBFDD965AD6C34DF856B53DC2',
// raw_log: '[]'
// }
await lcd .move
.viewFunction ( key .accAddress , 'read_write' , 'read' )
.then (res => console .log ( 'after write:' , res));
}
setNewContent ();
Last updated 7 months ago