Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor moveos_stdlib::move_module and add example of issue coin without code #1107

Merged
merged 8 commits into from
Nov 4, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -21,4 +21,10 @@ crate::natives::gas_parameter::native::define_gas_parameters_for_natives!(GasPar
[.replace_identifiers.per_byte, "replace_identifiers.per_byte", (5 + 1) * MUL],
[.replace_bytes_constant.base, "replace_bytes_constant.base", (5 + 1) * MUL],
[.replace_bytes_constant.per_byte, "replace_bytes_constant.per_byte", (5 + 1) * MUL],
[.replace_u8_constant.base, "replace_u8_constant.base", (5 + 1) * MUL],
[.replace_u8_constant.per_byte, "replace_u8_constant.per_byte", (5 + 1) * MUL],
[.replace_u64_constant.base, "replace_u64_constant.base", (5 + 1) * MUL],
[.replace_u64_constant.per_byte, "replace_u64_constant.per_byte", (5 + 1) * MUL],
[.replace_u256_constant.base, "replace_u256_constant.base", (5 + 1) * MUL],
[.replace_u256_constant.per_byte, "replace_u256_constant.per_byte", (5 + 1) * MUL],
]);
17 changes: 15 additions & 2 deletions crates/testsuite/features/cmd.feature
Original file line number Diff line number Diff line change
@@ -159,8 +159,8 @@ Feature: Rooch CLI integration tests

Then stop the server

@serial
Scenario: coins example
@serial
Scenario: coins example
Given a server for coins
Then cmd: "account create"
Then cmd: "move publish -p ../../examples/coins --sender-account {default} --named-addresses coins={default}"
@@ -170,3 +170,16 @@ Feature: Rooch CLI integration tests

Then stop the server

@serial
Scenario: Issue a coin through entry function
Given a server for issue_coin
Then cmd: "move publish -p ../../examples/module_template/ --sender-account {default} --named-addresses rooch_examples={default}"
Then cmd: "move run --function {default}::coin_factory::register_template --sender-account {default}"
Then assert: "{{$.move[-1].execution_info.status.type}} == executed"
Then cmd: "move run --function {default}::coin_factory::issue_fixed_supply_coin --args string:my_coin --args string:"My first coin" --args string:MyCoin --args 1010101u256 --args 8u8 --sender-account {default}"
Then assert: "{{$.move[-1].execution_info.status.type}} == executed"

# check module `my_coin` is published, the name `my_coin` is the first arg in the last `move run` cmd.
Then cmd: "move run --function {default}::my_coin::faucet --sender-account {default}"
Then assert: "{{$.move[-1].execution_info.status.type}} == executed"
Then stop the server
3 changes: 2 additions & 1 deletion examples/coins/sources/fixed_supply_coin.move
Original file line number Diff line number Diff line change
@@ -20,14 +20,15 @@ module coins::fixed_supply_coin {
}

const TOTAL_SUPPLY: u256 = 210_000_000_000u256;
const DECIMALS: u8 = 1u8;


fun init(ctx: &mut Context) {
coin::register_extend<FSC>(
ctx,
string::utf8(b"Fixed Supply Coin"),
string::utf8(b"FSC"),
1,
DECIMALS,
);
let coins_signer = signer::module_signer<FSC>();
// Mint the total supply of coins, and store it to the treasury
21 changes: 21 additions & 0 deletions examples/module_template/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "module_template"
version = "0.0.1"

[dependencies]
#MoveStdlib = { git = "https://github.com/rooch-network/rooch.git", subdir = "moveos/moveos-stdlib/move-stdlib", rev = "main" }
#MoveosStdlib = { git = "https://github.com/rooch-network/rooch.git", subdir = "moveos/moveos-stdlib/moveos-stdlib", rev = "main" }
#RoochFramework = { git = "https://github.com/rooch-network/rooch.git", subdir = "crates/rooch-framework", rev = "main" }

MoveStdlib = { local = "../../moveos/moveos-stdlib/move-stdlib" }
MoveosStdlib = { local = "../../moveos/moveos-stdlib/moveos-stdlib" }
RoochFramework = { local = "../../crates/rooch-framework" }

[addresses]
rooch_examples = "_"
std = "0x1"
moveos_std = "0x2"
rooch_framework = "0x3"

[dev-addresses]
rooch_examples = "0x42"
82 changes: 82 additions & 0 deletions examples/module_template/sources/coin_factory.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0

module rooch_examples::coin_factory {
use std::string::{Self, String};
use std::vector;
use moveos_std::signer;
use moveos_std::table::{Self, Table};
use moveos_std::account_storage;
use moveos_std::context::Context;
use moveos_std::move_module;

const TEMPLATE_MODULE_ADDRESS: address = @0xdeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadead;
const TEMPLATE_MODULE_IDENTIFIER: vector<u8> = b"coin_module_identifier_placeholder";
const TEMPLATE_COIN_STRUCT_IDENTIFIER_PLACEHOLDER: vector<u8> = b"COIN_STRUCT_IDENTIFIER_PLACEHOLDER";
const TEMPLATE_COIN_NAME_PLACEHOLDER: vector<u8> = b"COIN_NAME_PLACEHOLDER";
const TEMPLATE_COIN_SYMBOL_PLACEHOLDER: vector<u8> = b"COIN_SYMBOL_PLACEHOLDER";
const TEMPLATE_COIN_SUPPLY_PLACEHOLDER: u256 = 123_321_123_456u256;
const TEMPLATE_COIN_DECIMALS: u8 = 222u8;

struct TemplateStore has key, store {
templates: Table<String, vector<u8>>,
}

fun init(ctx: &mut Context) {
let module_signer = signer::module_signer<TemplateStore>();
let templates = table::new<String, vector<u8>>(ctx);
account_storage::global_move_to(ctx, &module_signer, TemplateStore { templates });
}

public entry fun register_template(ctx: &mut Context) {
let name = string::utf8(b"fixed_supply_coin");
let template_bytes = x"a11ceb0b060000000b010012021220033250048201140596017e079402e50208f904800106f9057b0af4060e0c82077d0dff070200000101020202030204020503060307030800090c00000a0800030b0000040f0c0100010810080007110001080101170700000c000100000d020100051204050002130708010804140a08010808150c0d010806160e01010c0118101100071912010108051a01130100071b140d0108081c0215010c081616010108021d1701010803060409050b060b080b090b0a0b0b0b0c0b0d0602070802060c000107080202050b0501080001060c010501080102070802050107090001080401070b03010900010800020708040f010b0501090003070802050b05010900030b050108000b030108040c010a02010806040708020806080602010c020708020f010b03010804020708040b0501090003070802060c090022636f696e5f6d6f64756c655f6964656e7469666965725f706c616365686f6c64657206737472696e670f6163636f756e745f73746f7261676507636f6e74657874066f626a656374067369676e6572126163636f756e745f636f696e5f73746f726504636f696e0a636f696e5f73746f726522434f494e5f5354525543545f4944454e5449464945525f504c414345484f4c44455208547265617375727907436f6e746578740666617563657404696e69740b64756d6d795f6669656c64064f626a65637409436f696e53746f726504436f696e0a616464726573735f6f6611676c6f62616c5f626f72726f775f6d75740a626f72726f775f6d7574087769746864726177076465706f73697406537472696e6704757466380f72656769737465725f657874656e640d6d6f64756c655f7369676e65720b6d696e745f657874656e64116372656174655f636f696e5f73746f72650e676c6f62616c5f6d6f76655f746fdeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadead0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030201de0f20800283b61c0000000000000000000000000000000000000000000000000000000520deadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadead0a021615434f494e5f4e414d455f504c414345484f4c4445520a021817434f494e5f53594d424f4c5f504c414345484f4c4445520002010e01010201080b030108040001040003100b0111020c020a00070238000f0038014a102700000000000000000000000000000000000000000000000000000000000038020c030b000b020b03380302010000000f1a0a0007031107070411070700380438050c030a00070138060c010a0038070c020d0238010b0138080b000e030b021201380902010000";

let template_store = account_storage::global_borrow_mut<TemplateStore>(ctx, @rooch_examples);
table::add(&mut template_store.templates, name, template_bytes);
Comment on lines +33 to +36
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put in the init()?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an example, I think it doesn't matter. My first thought is to make the name and temple_bytes as function parameters. But the template bytes is too long, which putted here maybe more clear.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example will auto-deploy to the devnet, and we can integrate it into the Dashboard.

#1109

}

public entry fun issue_fixed_supply_coin(ctx: &mut Context, account: &signer,
module_name: String, coin_name: String,
coin_symbol: String, total_supply: u256, decimals: u8
) {
let template_store = account_storage::global_borrow_mut<TemplateStore>(ctx, @rooch_examples);
let template_bytes = *table::borrow(&template_store.templates, string::utf8(b"fixed_supply_coin"));
let template_module = move_module::new(template_bytes);

let sender = signer::address_of(account);
let modules = vector::singleton(template_module);
let modules = move_module::binding_module_address(modules, TEMPLATE_MODULE_ADDRESS, sender);
let modules = move_module::replace_module_identiner(
modules,
vector::singleton(string::utf8(TEMPLATE_MODULE_IDENTIFIER)),
vector::singleton(module_name)
);
let modules = move_module::replace_struct_identifier(
modules,
vector::singleton(string::utf8(TEMPLATE_COIN_STRUCT_IDENTIFIER_PLACEHOLDER)),
vector::singleton(coin_symbol)
);

let old_strings = vector::singleton(string::utf8(TEMPLATE_COIN_NAME_PLACEHOLDER));
vector::push_back(&mut old_strings, string::utf8(TEMPLATE_COIN_SYMBOL_PLACEHOLDER));
let new_strings = vector::singleton(coin_name);
vector::push_back(&mut new_strings, coin_symbol);
let modules = move_module::replace_constant_string(
modules,
old_strings,
new_strings
);

let new_supply = vector::singleton(total_supply);
let old_supply = vector::singleton(TEMPLATE_COIN_SUPPLY_PLACEHOLDER);
let modules = move_module::replace_constant_u256(modules, old_supply, new_supply);

let new_decimal = vector::singleton(decimals);
let old_decimal = vector::singleton(TEMPLATE_COIN_DECIMALS);
let modules = move_module::replace_constant_u8(modules, old_decimal, new_decimal);

// publish modules
account_storage::publish_modules(ctx, account, modules);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0

module 0xdeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadead::coin_module_identifier_placeholder {

use std::string;
use moveos_std::signer;
use moveos_std::account_storage;
use moveos_std::context::Context;
use moveos_std::object::{Self, Object};
use rooch_framework::coin;
use rooch_framework::coin_store::{Self, CoinStore};
use rooch_framework::account_coin_store;


struct COIN_STRUCT_IDENTIFIER_PLACEHOLDER has key, store {}

struct Treasury has key {
coin_store: Object<CoinStore>
}

const TOTAL_SUPPLY: u256 = 123_321_123_456u256;
const DECIMALS: u8 = 222u8;


fun init(ctx: &mut Context) {
coin::register_extend<COIN_STRUCT_IDENTIFIER_PLACEHOLDER>(
ctx,
string::utf8(b"COIN_NAME_PLACEHOLDER"),
string::utf8(b"COIN_SYMBOL_PLACEHOLDER"),
DECIMALS,
);
let coins_signer = signer::module_signer<COIN_STRUCT_IDENTIFIER_PLACEHOLDER>();
// Mint the total supply of coins, and store it to the treasury
let coin = coin::mint_extend<COIN_STRUCT_IDENTIFIER_PLACEHOLDER>(ctx, TOTAL_SUPPLY);
let coin_store_ref = coin_store::create_coin_store<COIN_STRUCT_IDENTIFIER_PLACEHOLDER>(ctx);
coin_store::deposit(object::borrow_mut(&mut coin_store_ref), coin);
account_storage::global_move_to(ctx, &coins_signer, Treasury { coin_store: coin_store_ref });
}

/// Provide a faucet to give out coins to users
/// In a real world scenario, the coins should be given out in the application business logic.
public entry fun faucet(ctx: &mut Context, account: &signer) {
let account_addr = signer::address_of(account);
let treasury = account_storage::global_borrow_mut<Treasury>(ctx, @0xdeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadeadead);
let coin = coin_store::withdraw<COIN_STRUCT_IDENTIFIER_PLACEHOLDER>(object::borrow_mut(&mut treasury.coin_store), 10000);
account_coin_store::deposit(ctx, account_addr, coin);
}
}
131 changes: 131 additions & 0 deletions moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md
Original file line number Diff line number Diff line change
@@ -9,17 +9,27 @@
- [Struct `MoveModule`](#0x2_move_module_MoveModule)
- [Constants](#@Constants_0)
- [Function `new`](#0x2_move_module_new)
- [Function `new_batch`](#0x2_move_module_new_batch)
- [Function `into_byte_codes_batch`](#0x2_move_module_into_byte_codes_batch)
- [Function `module_name`](#0x2_move_module_module_name)
- [Function `sort_and_verify_modules`](#0x2_move_module_sort_and_verify_modules)
- [Function `check_comatibility`](#0x2_move_module_check_comatibility)
- [Function `binding_module_address`](#0x2_move_module_binding_module_address)
- [Function `replace_module_identiner`](#0x2_move_module_replace_module_identiner)
- [Function `replace_struct_identifier`](#0x2_move_module_replace_struct_identifier)
- [Function `replace_constant_string`](#0x2_move_module_replace_constant_string)
- [Function `replace_constant_address`](#0x2_move_module_replace_constant_address)
- [Function `replace_constant_u8`](#0x2_move_module_replace_constant_u8)
- [Function `replace_constant_u64`](#0x2_move_module_replace_constant_u64)
- [Function `replace_constant_u256`](#0x2_move_module_replace_constant_u256)
- [Function `request_init_functions`](#0x2_move_module_request_init_functions)
- [Function `replace_address_identifiers`](#0x2_move_module_replace_address_identifiers)
- [Function `replace_identifiers`](#0x2_move_module_replace_identifiers)
- [Function `replace_addresses_constant`](#0x2_move_module_replace_addresses_constant)
- [Function `replace_bytes_constant`](#0x2_move_module_replace_bytes_constant)
- [Function `replace_u8_constant`](#0x2_move_module_replace_u8_constant)
- [Function `replace_u64_constant`](#0x2_move_module_replace_u64_constant)
- [Function `replace_u256_constant`](#0x2_move_module_replace_u256_constant)


<pre><code><b>use</b> <a href="">0x1::error</a>;
@@ -96,6 +106,28 @@ Module verification error



<a name="0x2_move_module_new_batch"></a>

## Function `new_batch`



<pre><code><b>public</b> <b>fun</b> <a href="move_module.md#0x2_move_module_new_batch">new_batch</a>(byte_codes_batch: <a href="">vector</a>&lt;<a href="">vector</a>&lt;u8&gt;&gt;): <a href="">vector</a>&lt;<a href="move_module.md#0x2_move_module_MoveModule">move_module::MoveModule</a>&gt;
</code></pre>



<a name="0x2_move_module_into_byte_codes_batch"></a>

## Function `into_byte_codes_batch`



<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="move_module.md#0x2_move_module_into_byte_codes_batch">into_byte_codes_batch</a>(modules: <a href="">vector</a>&lt;<a href="move_module.md#0x2_move_module_MoveModule">move_module::MoveModule</a>&gt;): <a href="">vector</a>&lt;<a href="">vector</a>&lt;u8&gt;&gt;
</code></pre>



<a name="0x2_move_module_module_name"></a>

## Function `module_name`
@@ -173,6 +205,66 @@ Replace given struct's identifier to the new ones



<a name="0x2_move_module_replace_constant_string"></a>

## Function `replace_constant_string`

Replace given string constant to the new ones


<pre><code><b>public</b> <b>fun</b> <a href="move_module.md#0x2_move_module_replace_constant_string">replace_constant_string</a>(modules: <a href="">vector</a>&lt;<a href="move_module.md#0x2_move_module_MoveModule">move_module::MoveModule</a>&gt;, old_strings: <a href="">vector</a>&lt;<a href="_String">string::String</a>&gt;, new_strings: <a href="">vector</a>&lt;<a href="_String">string::String</a>&gt;): <a href="">vector</a>&lt;<a href="move_module.md#0x2_move_module_MoveModule">move_module::MoveModule</a>&gt;
</code></pre>



<a name="0x2_move_module_replace_constant_address"></a>

## Function `replace_constant_address`

Replace given address constant to the new ones


<pre><code><b>public</b> <b>fun</b> <a href="move_module.md#0x2_move_module_replace_constant_address">replace_constant_address</a>(modules: <a href="">vector</a>&lt;<a href="move_module.md#0x2_move_module_MoveModule">move_module::MoveModule</a>&gt;, old_addresses: <a href="">vector</a>&lt;<b>address</b>&gt;, new_addresses: <a href="">vector</a>&lt;<b>address</b>&gt;): <a href="">vector</a>&lt;<a href="move_module.md#0x2_move_module_MoveModule">move_module::MoveModule</a>&gt;
</code></pre>



<a name="0x2_move_module_replace_constant_u8"></a>

## Function `replace_constant_u8`

Replace given u8 constant to the new ones


<pre><code><b>public</b> <b>fun</b> <a href="move_module.md#0x2_move_module_replace_constant_u8">replace_constant_u8</a>(modules: <a href="">vector</a>&lt;<a href="move_module.md#0x2_move_module_MoveModule">move_module::MoveModule</a>&gt;, old_u8s: <a href="">vector</a>&lt;u8&gt;, new_u8s: <a href="">vector</a>&lt;u8&gt;): <a href="">vector</a>&lt;<a href="move_module.md#0x2_move_module_MoveModule">move_module::MoveModule</a>&gt;
</code></pre>



<a name="0x2_move_module_replace_constant_u64"></a>

## Function `replace_constant_u64`

Replace given u64 constant to the new ones


<pre><code><b>public</b> <b>fun</b> <a href="move_module.md#0x2_move_module_replace_constant_u64">replace_constant_u64</a>(modules: <a href="">vector</a>&lt;<a href="move_module.md#0x2_move_module_MoveModule">move_module::MoveModule</a>&gt;, old_u64s: <a href="">vector</a>&lt;u64&gt;, new_u64s: <a href="">vector</a>&lt;u64&gt;): <a href="">vector</a>&lt;<a href="move_module.md#0x2_move_module_MoveModule">move_module::MoveModule</a>&gt;
</code></pre>



<a name="0x2_move_module_replace_constant_u256"></a>

## Function `replace_constant_u256`

Replace given u256 constant to the new ones


<pre><code><b>public</b> <b>fun</b> <a href="move_module.md#0x2_move_module_replace_constant_u256">replace_constant_u256</a>(modules: <a href="">vector</a>&lt;<a href="move_module.md#0x2_move_module_MoveModule">move_module::MoveModule</a>&gt;, old_u256s: <a href="">vector</a>&lt;u256&gt;, new_u256s: <a href="">vector</a>&lt;u256&gt;): <a href="">vector</a>&lt;<a href="move_module.md#0x2_move_module_MoveModule">move_module::MoveModule</a>&gt;
</code></pre>



<a name="0x2_move_module_request_init_functions"></a>

## Function `request_init_functions`
@@ -235,3 +327,42 @@ Native function to replace constant bytes in module binary where the length of

<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="move_module.md#0x2_move_module_replace_bytes_constant">replace_bytes_constant</a>(bytes: <a href="">vector</a>&lt;<a href="">vector</a>&lt;u8&gt;&gt;, old_bytes: <a href="">vector</a>&lt;<a href="">vector</a>&lt;u8&gt;&gt;, new_bytes: <a href="">vector</a>&lt;<a href="">vector</a>&lt;u8&gt;&gt;): <a href="">vector</a>&lt;<a href="">vector</a>&lt;u8&gt;&gt;
</code></pre>



<a name="0x2_move_module_replace_u8_constant"></a>

## Function `replace_u8_constant`

Native function to replace constant u8 in module binary where the length of
<code>old_u8s</code> must equal to that of <code>new_u8s</code>.


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="move_module.md#0x2_move_module_replace_u8_constant">replace_u8_constant</a>(bytes: <a href="">vector</a>&lt;<a href="">vector</a>&lt;u8&gt;&gt;, old_u8s: <a href="">vector</a>&lt;u8&gt;, new_u8s: <a href="">vector</a>&lt;u8&gt;): <a href="">vector</a>&lt;<a href="">vector</a>&lt;u8&gt;&gt;
</code></pre>



<a name="0x2_move_module_replace_u64_constant"></a>

## Function `replace_u64_constant`

Native function to replace constant u64 in module binary where the length of
<code>old_u64s</code> must equal to that of <code>new_u64s</code>.


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="move_module.md#0x2_move_module_replace_u64_constant">replace_u64_constant</a>(bytes: <a href="">vector</a>&lt;<a href="">vector</a>&lt;u8&gt;&gt;, old_u64s: <a href="">vector</a>&lt;u64&gt;, new_u64s: <a href="">vector</a>&lt;u64&gt;): <a href="">vector</a>&lt;<a href="">vector</a>&lt;u8&gt;&gt;
</code></pre>



<a name="0x2_move_module_replace_u256_constant"></a>

## Function `replace_u256_constant`

Native function to replace constant u256 in module binary where the length of
<code>old_u256s</code> must equal to that of <code>new_u256s</code>.


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="move_module.md#0x2_move_module_replace_u256_constant">replace_u256_constant</a>(bytes: <a href="">vector</a>&lt;<a href="">vector</a>&lt;u8&gt;&gt;, old_u256s: <a href="">vector</a>&lt;u256&gt;, new_u256s: <a href="">vector</a>&lt;u256&gt;): <a href="">vector</a>&lt;<a href="">vector</a>&lt;u8&gt;&gt;
</code></pre>
293 changes: 177 additions & 116 deletions moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move

Large diffs are not rendered by default.

461 changes: 283 additions & 178 deletions moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs

Large diffs are not rendered by default.