(
hash: H256,
keystore: KeystorePtr,
@@ -167,6 +183,7 @@ where
.await
}
+/// Whether the mem pool reaches the threshold for purchasing cores.
async fn reach_txpool_threshold(
parachain: &P,
transaction_pool: Arc,
@@ -232,6 +249,7 @@ where
Some((is_place_order, order_type))
}
+/// Whether the xcm transaction event of the relay chain is received.
async fn relay_chain_xcm_event(
relay_chain_interface: impl RelayChainInterface + Clone,
para_id: ParaId,
@@ -247,6 +265,7 @@ async fn relay_chain_xcm_event(
return Some((can_order, OrderType::XCMEvent));
}
+/// Get the transactions in the ready queue in the mem pool
async fn get_txs(transaction_pool: Arc) -> Vec
where
Block: BlockT,
@@ -262,6 +281,7 @@ where
return back_txs;
}
+/// The main processing logic of purchasing core.
async fn handle_new_best_parachain_head(
validation_data: PersistedValidationData,
height: RelayBlockNumber,
diff --git a/node/src/submit_order.rs b/node/src/submit_order.rs
index 1db9ef9..eb639e4 100644
--- a/node/src/submit_order.rs
+++ b/node/src/submit_order.rs
@@ -13,6 +13,11 @@
// You should have received a copy of the GNU General Public License
// along with Magnet. If not, see .
+
+//! The code here is implemented, constructing a transaction from the parachain and sending it to the relay chain to purchase core.
+//!
+//! Subxt is used here to construct and submit the transaction.
+//!
use crate::metadata;
use cumulus_primitives_core::{
relay_chain::BlockId, relay_chain::BlockNumber as RelayBlockNumber, ParaId,
@@ -52,7 +57,9 @@ impl From for MultiSignature {
}
}
pub struct SignerKeystore {
+ /// Account ID
account_id: T::AccountId,
+ /// Keystore of node
keystore: KeystorePtr,
}
impl SignerKeystore
@@ -87,6 +94,8 @@ where
self.account_id.clone().into()
}
+ /// Use aura's key to sign
+ /// TODO:Modify to other keys, or load the key in some way.
fn sign(&self, signer_payload: &[u8]) -> T::Signature {
let pub_key =
self.keystore.sr25519_public_keys(sp_consensus_aura::sr25519::AuthorityPair::ID)[0];
@@ -101,6 +110,7 @@ where
}
}
+/// Construct the transaction and sign it, and then submit the transaction through the rpc interface.
pub async fn build_rpc_for_submit_order(
url: &str,
para_id: ParaId,
From 384e6075f7ab616dbf0d0168e19aee6ecfd04955 Mon Sep 17 00:00:00 2001
From: sulijia <984115358@qq.com>
Date: Wed, 15 May 2024 17:35:13 +0800
Subject: [PATCH 04/14] Add comments about order for primitives
---
primitives/order/src/inherent_client.rs | 6 ++++++
primitives/order/src/lib.rs | 20 ++++++++++++++++++++
primitives/order/src/well_known_keys.rs | 4 ++++
3 files changed, 30 insertions(+)
diff --git a/primitives/order/src/inherent_client.rs b/primitives/order/src/inherent_client.rs
index 5c688e8..84dd5d7 100644
--- a/primitives/order/src/inherent_client.rs
+++ b/primitives/order/src/inherent_client.rs
@@ -21,6 +21,8 @@ use {
cumulus_relay_chain_interface::{PHash, RelayChainInterface},
};
+/// Collect the relevant relay chain state in form of a proof
+/// for putting it into the order inherent.
async fn collect_relay_storage_proof(
relay_chain_interface: &impl RelayChainInterface,
relay_parent: PHash,
@@ -43,6 +45,9 @@ async fn collect_relay_storage_proof(
}
impl OrderInherentData {
+ /// Create the [`OrderInherentData`] at the given `relay_parent`.
+ ///
+ /// Returns `None` if the creation failed.
pub async fn create_at(
relay_parent: PHash,
relay_chain_interface: &impl RelayChainInterface,
@@ -64,6 +69,7 @@ impl OrderInherentData {
}
}
+// Implementation of InherentDataProvider
#[async_trait::async_trait]
impl sp_inherents::InherentDataProvider for OrderInherentData {
async fn provide_inherent_data(
diff --git a/primitives/order/src/lib.rs b/primitives/order/src/lib.rs
index f1ce467..87505dd 100644
--- a/primitives/order/src/lib.rs
+++ b/primitives/order/src/lib.rs
@@ -14,6 +14,11 @@
// You should have received a copy of the GNU General Public License
// along with Magnet. If not, see .
+//! # Order Inherent Primitives
+//!
+//! This crate defines those primitives that should be taken into account when building
+//! the order pallet inherent
+//!
#![cfg_attr(not(feature = "std"), no_std)]
use cumulus_primitives_core::{
relay_chain::BlockNumber as RelayBlockNumber, relay_chain::Hash as PHash, ParaId,
@@ -31,10 +36,15 @@ use {scale_info::TypeInfo, sp_inherents::InherentIdentifier};
#[derive(Encode, Decode, sp_core::RuntimeDebug, Clone, PartialEq, TypeInfo)]
pub struct OrderInherentData {
+ /// Proof of relaychain storage.
pub relay_storage_proof: sp_trie::StorageProof,
+ /// Validation data.
pub validation_data: Option,
+ /// Parachain ID.
pub para_id: ParaId,
+ /// Sequence number of order.
pub sequence_number: u64,
+ /// Author of order.
pub author_pub: Option,
}
@@ -51,15 +61,25 @@ pub enum OrderStatus {
#[derive(Clone)]
pub struct OrderRecord {
+ /// Hash of relaychain block.
pub relay_parent: Option,
+ /// Relaychain block height.
pub relay_height: RelayBlockNumber,
+ /// Hash of relaychain block,block number is special.
pub relay_base: PHash,
+ /// Relaychain block height,block number is special.
pub relay_base_height: RelayBlockNumber,
+ /// Order status
pub order_status: OrderStatus,
+ /// Validation data.
pub validation_data: Option,
+ /// Parachain ID.
pub para_id: ParaId,
+ /// Sequence number of order.
pub sequence_number: u64,
+ /// Author of order.
pub author_pub: Option,
+ /// Backup transactions hash.
pub txs: Vec,
}
diff --git a/primitives/order/src/well_known_keys.rs b/primitives/order/src/well_known_keys.rs
index 09ea087..d591e3b 100644
--- a/primitives/order/src/well_known_keys.rs
+++ b/primitives/order/src/well_known_keys.rs
@@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Magnet. If not, see .
+//! Keys of well known.
#![cfg_attr(not(feature = "std"), no_std)]
use cumulus_primitives_core::relay_chain::CoreIndex;
@@ -27,6 +28,7 @@ use {
pub const PARAS_PARA_LIFECYCLES: &[u8] =
&hex_literal::hex!["cd710b30bd2eab0352ddcc26417aa194281e0bfde17b36573208a06cb5cfba6b"];
+// Paras pallet storage ParaLifecycles
pub fn paras_para_lifecycles(para_id: ParaId) -> Vec {
para_id.using_encoded(|para_id: &[u8]| {
PARAS_PARA_LIFECYCLES
@@ -38,6 +40,7 @@ pub fn paras_para_lifecycles(para_id: ParaId) -> Vec {
})
}
+/// System pallet
pub const SYSTEM_BLOCKHASH: &[u8] = &hex_literal::hex![
"26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746b4def25cfda6ef3a00000000"
];
@@ -63,6 +66,7 @@ pub const ACTIVE_CONFIG: &[u8] =
pub const CORE_DESCRIPTORS: &[u8] =
&hex_literal::hex!["638595eebaa445ce03a13547bece90e704e6ac775a3245623103ffec2cb2c92f"];
+/// assigner coretime storage CoreDescriptors
pub fn paras_core_descriptors(core_index: CoreIndex) -> Vec {
core_index.using_encoded(|core_index: &[u8]| {
CORE_DESCRIPTORS.iter().chain(twox_256(core_index).iter()).cloned().collect()
From ab41e92a8a1f929159ceb800960cdf4c0fe15132 Mon Sep 17 00:00:00 2001
From: toints
Date: Thu, 23 May 2024 16:53:08 +0800
Subject: [PATCH 05/14] feat: Move pallet included
This commit introduces Move pallet integration for magnet node.
Supported features:
- Move pallet itself with extrinsics;
- RPC calls;
- Runtime API crate included.
---
Cargo.toml | 14 +
node/Cargo.toml | 1 +
node/src/chain_spec.rs | 5 +
node/src/rpc/mod.rs | 5 +-
pallets/move-vm/Cargo.toml | 44 +
pallets/move-vm/Dockerfile | 18 +
pallets/move-vm/LICENSE | 21 +
pallets/move-vm/README.md | 94 +
.../doc/assets/pallet-move_substrate_move.png | Bin 0 -> 92168 bytes
.../polkadot.js_buy_coin_balances_after.png | Bin 0 -> 121825 bytes
.../polkadot.js_buy_coin_balances_before.png | Bin 0 -> 121415 bytes
.../assets/polkadot.js_execute_script_buy.png | Bin 0 -> 399260 bytes
.../polkadot.js_execute_script_init.png | Bin 0 -> 404368 bytes
.../polkadot.js_multisign_alice_initiates.png | Bin 0 -> 477573 bytes
...polkadot.js_multisign_bob_inits_module.png | Bin 0 -> 391670 bytes
...adot.js_multisign_bob_publishes_module.png | Bin 0 -> 559863 bytes
.../polkadot.js_multisign_eve_finalises.png | Bin 0 -> 479919 bytes
.../assets/polkadot.js_multisign_events.png | Bin 0 -> 248820 bytes
.../doc/assets/polkadot.js_publish_module.png | Bin 0 -> 570774 bytes
.../doc/assets/polkadot.js_update_stdlib.png | Bin 0 -> 53861 bytes
.../assets/uml-full-picture-no-details.png | Bin 0 -> 7568 bytes
.../assets/uml-full-picture-no-details.txt | 15 +
.../move-vm/doc/assets/uml-full-picture.png | Bin 0 -> 68700 bytes
.../move-vm/doc/assets/uml-full-picture.txt | 66 +
.../doc/assets/uml-move-lang-crates.png | Bin 0 -> 17649 bytes
.../doc/assets/uml-move-lang-crates.txt | 18 +
.../move-vm/doc/assets/uml-move-pallet.png | Bin 0 -> 20233 bytes
.../move-vm/doc/assets/uml-move-pallet.txt | 26 +
.../assets/uml-move-vm-runtime-dep-tree.png | Bin 0 -> 28287 bytes
.../assets/uml-move-vm-runtime-dep-tree.txt | 26 +
.../uml-pallet-move-full-architecture-m2.png | Bin 0 -> 37404 bytes
.../uml-pallet-move-full-architecture-m2.txt | 48 +
.../web3 foundation_grants_badge_black.png | Bin 0 -> 20436 bytes
pallets/move-vm/doc/design.md | 251 +
pallets/move-vm/doc/final-design.md | 185 +
pallets/move-vm/doc/gas-handling.md | 53 +
.../move-vm/doc/milestone-deliverables/M1.md | 27 +
.../move-vm/doc/milestone-deliverables/M2.md | 43 +
.../doc/milestone-deliverables/README.md | 8 +
.../m1-testing-guide.md | 132 +
pallets/move-vm/doc/stdlib-doc.md | 47 +
pallets/move-vm/doc/tech_guide.md | 189 +
pallets/move-vm/doc/tutorial-multi-signer.md | 43 +
pallets/move-vm/doc/tutorial.md | 252 +
pallets/move-vm/pallet/Cargo.toml | 87 +
pallets/move-vm/pallet/build.rs | 40 +
pallets/move-vm/pallet/src/api.rs | 46 +
.../assets/move-projects/balance/Move.toml | 11 +
.../balance/sources/Scripts.move | 35 +
.../base58_smove_build/Move.toml | 10 +
.../base58_smove_build/sources/BobBase58.move | 5 +
.../assets/move-projects/basic_coin/Move.toml | 10 +
.../basic_coin/sources/BasicCoin.move | 68 +
.../basic_coin/sources/GetCoin.move | 15 +
.../move-projects/car-wash-example/Move.toml | 12 +
.../move-projects/car-wash-example/build.sh | 9 +
.../build/car-wash-example/BuildInfo.yaml | 24 +
.../bundles/car-wash-example.mvb | Bin 0 -> 735 bytes
.../bytecode_modules/CarWash.mv | Bin 0 -> 732 bytes
.../dependencies/MoveStdlib/acl.mv | Bin 0 -> 454 bytes
.../dependencies/MoveStdlib/ascii.mv | Bin 0 -> 791 bytes
.../dependencies/MoveStdlib/bcs.mv | Bin 0 -> 92 bytes
.../dependencies/MoveStdlib/bit_vector.mv | Bin 0 -> 811 bytes
.../dependencies/MoveStdlib/error.mv | Bin 0 -> 626 bytes
.../dependencies/MoveStdlib/fixed_point32.mv | Bin 0 -> 904 bytes
.../dependencies/MoveStdlib/hash.mv | Bin 0 -> 106 bytes
.../dependencies/MoveStdlib/option.mv | Bin 0 -> 1137 bytes
.../dependencies/MoveStdlib/signer.mv | Bin 0 -> 130 bytes
.../dependencies/MoveStdlib/string.mv | Bin 0 -> 923 bytes
.../dependencies/MoveStdlib/type_name.mv | Bin 0 -> 217 bytes
.../dependencies/MoveStdlib/vector.mv | Bin 0 -> 1041 bytes
.../dependencies/SubstrateStdlib/balance.mv | Bin 0 -> 144 bytes
.../SubstrateStdlib/substrate_hash.mv | Bin 0 -> 196 bytes
.../bytecode_scripts/buy_coin.mv | Bin 0 -> 99 bytes
.../bytecode_scripts/initial_coin_minting.mv | Bin 0 -> 107 bytes
.../bytecode_scripts/register_new_user.mv | Bin 0 -> 104 bytes
.../bytecode_scripts/wash_car.mv | Bin 0 -> 95 bytes
.../script_transactions/buy_coin.mvt | Bin 0 -> 137 bytes
.../initial_coin_minting.mvt | Bin 0 -> 143 bytes
.../script_transactions/register_new_user.mvt | Bin 0 -> 140 bytes
.../script_transactions/wash_car.mvt | Bin 0 -> 131 bytes
.../car-wash-example/source_maps/CarWash.mvsm | Bin 0 -> 6161 bytes
.../source_maps/buy_coin.mvsm | Bin 0 -> 354 bytes
.../dependencies/MoveStdlib/acl.mvsm | Bin 0 -> 2768 bytes
.../dependencies/MoveStdlib/ascii.mvsm | Bin 0 -> 6217 bytes
.../dependencies/MoveStdlib/bcs.mvsm | Bin 0 -> 220 bytes
.../dependencies/MoveStdlib/bit_vector.mvsm | Bin 0 -> 9494 bytes
.../dependencies/MoveStdlib/error.mvsm | Bin 0 -> 3273 bytes
.../MoveStdlib/fixed_point32.mvsm | Bin 0 -> 9445 bytes
.../dependencies/MoveStdlib/hash.mvsm | Bin 0 -> 267 bytes
.../dependencies/MoveStdlib/option.mvsm | Bin 0 -> 9781 bytes
.../dependencies/MoveStdlib/signer.mvsm | Bin 0 -> 389 bytes
.../dependencies/MoveStdlib/string.mvsm | Bin 0 -> 7215 bytes
.../dependencies/MoveStdlib/type_name.mvsm | Bin 0 -> 614 bytes
.../dependencies/MoveStdlib/vector.mvsm | Bin 0 -> 11192 bytes
.../dependencies/SubstrateStdlib/balance.mvsm | Bin 0 -> 466 bytes
.../SubstrateStdlib/substrate_hash.mvsm | Bin 0 -> 655 bytes
.../source_maps/initial_coin_minting.mvsm | Bin 0 -> 266 bytes
.../source_maps/register_new_user.mvsm | Bin 0 -> 266 bytes
.../source_maps/wash_car.mvsm | Bin 0 -> 266 bytes
.../car-wash-example/sources/CarWash.move | 97 +
.../car-wash-example/sources/buy_coin.move | 31 +
.../sources/dependencies/MoveStdlib/acl.move | 46 +
.../dependencies/MoveStdlib/ascii.move | 148 +
.../sources/dependencies/MoveStdlib/bcs.move | 17 +
.../dependencies/MoveStdlib/bit_vector.move | 161 +
.../dependencies/MoveStdlib/error.move | 81 +
.../MoveStdlib/fixed_point32.move | 294 +
.../sources/dependencies/MoveStdlib/hash.move | 8 +
.../dependencies/MoveStdlib/option.move | 260 +
.../dependencies/MoveStdlib/signer.move | 21 +
.../dependencies/MoveStdlib/string.move | 94 +
.../dependencies/MoveStdlib/type_name.move | 28 +
.../dependencies/MoveStdlib/vector.move | 217 +
.../dependencies/SubstrateStdlib/balance.move | 23 +
.../SubstrateStdlib/substrate_hash.move | 30 +
.../sources/initial_coin_minting.move | 31 +
.../sources/register_new_user.move | 31 +
.../car-wash-example/sources/wash_car.move | 31 +
.../move-projects/car-wash-example/hints.md | 37 +
.../car-wash-example/sources/CarWash.move | 97 +
.../car-wash-example/sources/Scripts.move | 31 +
.../move-projects/developer-bundle/Move.toml | 11 +
.../developer-bundle/sources/CarWash.move | 97 +
.../developer-bundle/sources/Dorm.move | 70 +
.../developer-bundle/sources/EmptyBob.move | 4 +
.../assets/move-projects/gas-costs/Move.toml | 11 +
.../assets/move-projects/gas-costs/build.sh | 12 +
.../gas-costs/sources/LongScript.move | 10009 ++++++++++++++++
.../gas-costs/sources/ModuleNotModule.move | 32 +
.../gas-costs/sources/ShortScripts.move | 18 +
.../gas-costs/sources/TheModule.move | 8 +
.../move-projects/get-resource/Move.toml | 10 +
.../get-resource/sources/Count.move | 7 +
.../get-resource/sources/Counter.move | 41 +
.../get-resource/sources/CreateCounter.move | 7 +
.../move-projects/move-basics/Move.toml | 11 +
.../move-basics/sources/Empty.move | 4 +
.../move-basics/sources/EmptyBob.move | 4 +
.../move-basics/sources/Prohibited.move | 4 +
.../move-basics/sources/Scripts.move | 39 +
.../move-projects/multiple-signers/Move.toml | 12 +
.../move-projects/multiple-signers/build.sh | 14 +
.../move-projects/multiple-signers/hints.md | 23 +
.../multiple-signers/sources/Dorm.move | 70 +
.../multiple-signers/sources/Scripts.move | 15 +
.../move-projects/prohibited-bundle/Move.toml | 9 +
.../sources/Prohibited1.move | 4 +
.../sources/Prohibited2.move | 4 +
.../move-projects/signer-scripts/Move.toml | 9 +
.../signer-scripts/sources/General.move | 78 +
.../signer-scripts/sources/Generics.move | 53 +
.../signer-scripts/sources/HelperModule.move | 23 +
.../signer-scripts/sources/Vectors.move | 64 +
.../assets/move-projects/smove-build-all.sh | 54 +
.../assets/move-projects/smove-clean-all.sh | 27 +
.../testing-move-stdlib/Move.toml | 8 +
.../testing-move-stdlib/README.md | 5 +
.../testing-move-stdlib/sources/ascii.move | 148 +
.../testing-move-stdlib/sources/bcs.move | 17 +
.../sources/bit_vector.move | 161 +
.../testing-move-stdlib/sources/error.move | 81 +
.../sources/fixed_point32.move | 294 +
.../testing-move-stdlib/sources/hash.move | 8 +
.../testing-move-stdlib/sources/option.move | 260 +
.../testing-move-stdlib/sources/signer.move | 21 +
.../testing-move-stdlib/sources/string.move | 94 +
.../sources/type_name.move | 28 +
.../sources/unit_test.move | 12 +
.../testing-move-stdlib/sources/vector.move | 217 +
.../testing-substrate-stdlib/Move.toml | 8 +
.../testing-substrate-stdlib/README.md | 7 +
.../sources/balance.move | 25 +
.../using_stdlib_natives/Move.toml | 10 +
.../sources/DependsOnVector.move | 16 +
.../using_stdlib_natives/sources/Vector.move | 22 +
pallets/move-vm/pallet/src/balance.rs | 252 +
pallets/move-vm/pallet/src/benchmarking.rs | 315 +
pallets/move-vm/pallet/src/lib.rs | 1141 ++
pallets/move-vm/pallet/src/mock.rs | 191 +
pallets/move-vm/pallet/src/mock_utils.rs | 112 +
pallets/move-vm/pallet/src/result.rs | 272 +
pallets/move-vm/pallet/src/signer.rs | 253 +
pallets/move-vm/pallet/src/storage.rs | 49 +
pallets/move-vm/pallet/src/tests.rs | 12 +
pallets/move-vm/pallet/src/tests/address.rs | 77 +
pallets/move-vm/pallet/src/tests/balance.rs | 313 +
pallets/move-vm/pallet/src/tests/example.rs | 73 +
pallets/move-vm/pallet/src/tests/execute.rs | 231 +
pallets/move-vm/pallet/src/tests/gas_costs.rs | 112 +
pallets/move-vm/pallet/src/tests/modules.rs | 70 +
pallets/move-vm/pallet/src/tests/publish.rs | 269 +
pallets/move-vm/pallet/src/tests/signer.rs | 690 ++
.../move-vm/pallet/src/tests/update_stdlib.rs | 91 +
pallets/move-vm/pallet/src/weights.rs | 105 +
pallets/move-vm/rpc/.gitignore | 10 +
pallets/move-vm/rpc/Cargo.toml | 30 +
pallets/move-vm/rpc/src/lib.rs | 225 +
runtime/Cargo.toml | 16 +-
runtime/src/lib.rs | 51 +-
200 files changed, 21069 insertions(+), 8 deletions(-)
create mode 100644 pallets/move-vm/Cargo.toml
create mode 100644 pallets/move-vm/Dockerfile
create mode 100644 pallets/move-vm/LICENSE
create mode 100644 pallets/move-vm/README.md
create mode 100644 pallets/move-vm/doc/assets/pallet-move_substrate_move.png
create mode 100644 pallets/move-vm/doc/assets/polkadot.js_buy_coin_balances_after.png
create mode 100644 pallets/move-vm/doc/assets/polkadot.js_buy_coin_balances_before.png
create mode 100644 pallets/move-vm/doc/assets/polkadot.js_execute_script_buy.png
create mode 100644 pallets/move-vm/doc/assets/polkadot.js_execute_script_init.png
create mode 100644 pallets/move-vm/doc/assets/polkadot.js_multisign_alice_initiates.png
create mode 100644 pallets/move-vm/doc/assets/polkadot.js_multisign_bob_inits_module.png
create mode 100644 pallets/move-vm/doc/assets/polkadot.js_multisign_bob_publishes_module.png
create mode 100644 pallets/move-vm/doc/assets/polkadot.js_multisign_eve_finalises.png
create mode 100644 pallets/move-vm/doc/assets/polkadot.js_multisign_events.png
create mode 100644 pallets/move-vm/doc/assets/polkadot.js_publish_module.png
create mode 100644 pallets/move-vm/doc/assets/polkadot.js_update_stdlib.png
create mode 100644 pallets/move-vm/doc/assets/uml-full-picture-no-details.png
create mode 100644 pallets/move-vm/doc/assets/uml-full-picture-no-details.txt
create mode 100644 pallets/move-vm/doc/assets/uml-full-picture.png
create mode 100644 pallets/move-vm/doc/assets/uml-full-picture.txt
create mode 100644 pallets/move-vm/doc/assets/uml-move-lang-crates.png
create mode 100644 pallets/move-vm/doc/assets/uml-move-lang-crates.txt
create mode 100644 pallets/move-vm/doc/assets/uml-move-pallet.png
create mode 100644 pallets/move-vm/doc/assets/uml-move-pallet.txt
create mode 100644 pallets/move-vm/doc/assets/uml-move-vm-runtime-dep-tree.png
create mode 100644 pallets/move-vm/doc/assets/uml-move-vm-runtime-dep-tree.txt
create mode 100644 pallets/move-vm/doc/assets/uml-pallet-move-full-architecture-m2.png
create mode 100644 pallets/move-vm/doc/assets/uml-pallet-move-full-architecture-m2.txt
create mode 100644 pallets/move-vm/doc/assets/web3 foundation_grants_badge_black.png
create mode 100644 pallets/move-vm/doc/design.md
create mode 100644 pallets/move-vm/doc/final-design.md
create mode 100644 pallets/move-vm/doc/gas-handling.md
create mode 100644 pallets/move-vm/doc/milestone-deliverables/M1.md
create mode 100644 pallets/move-vm/doc/milestone-deliverables/M2.md
create mode 100644 pallets/move-vm/doc/milestone-deliverables/README.md
create mode 100644 pallets/move-vm/doc/milestone-deliverables/m1-testing-guide.md
create mode 100644 pallets/move-vm/doc/stdlib-doc.md
create mode 100644 pallets/move-vm/doc/tech_guide.md
create mode 100644 pallets/move-vm/doc/tutorial-multi-signer.md
create mode 100644 pallets/move-vm/doc/tutorial.md
create mode 100644 pallets/move-vm/pallet/Cargo.toml
create mode 100644 pallets/move-vm/pallet/build.rs
create mode 100644 pallets/move-vm/pallet/src/api.rs
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/balance/Move.toml
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/balance/sources/Scripts.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/base58_smove_build/Move.toml
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/base58_smove_build/sources/BobBase58.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/basic_coin/Move.toml
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/basic_coin/sources/BasicCoin.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/basic_coin/sources/GetCoin.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/Move.toml
create mode 100755 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build.sh
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/BuildInfo.yaml
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bundles/car-wash-example.mvb
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/CarWash.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/dependencies/MoveStdlib/acl.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/dependencies/MoveStdlib/ascii.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/dependencies/MoveStdlib/bcs.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/dependencies/MoveStdlib/bit_vector.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/dependencies/MoveStdlib/error.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/dependencies/MoveStdlib/fixed_point32.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/dependencies/MoveStdlib/hash.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/dependencies/MoveStdlib/option.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/dependencies/MoveStdlib/signer.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/dependencies/MoveStdlib/string.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/dependencies/MoveStdlib/type_name.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/dependencies/MoveStdlib/vector.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/dependencies/SubstrateStdlib/balance.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/dependencies/SubstrateStdlib/substrate_hash.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_scripts/buy_coin.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_scripts/initial_coin_minting.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_scripts/register_new_user.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/bytecode_scripts/wash_car.mv
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/script_transactions/buy_coin.mvt
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/script_transactions/initial_coin_minting.mvt
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/script_transactions/register_new_user.mvt
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/script_transactions/wash_car.mvt
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/CarWash.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/buy_coin.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/dependencies/MoveStdlib/acl.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/dependencies/MoveStdlib/ascii.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/dependencies/MoveStdlib/bcs.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/dependencies/MoveStdlib/bit_vector.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/dependencies/MoveStdlib/error.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/dependencies/MoveStdlib/fixed_point32.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/dependencies/MoveStdlib/hash.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/dependencies/MoveStdlib/option.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/dependencies/MoveStdlib/signer.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/dependencies/MoveStdlib/string.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/dependencies/MoveStdlib/type_name.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/dependencies/MoveStdlib/vector.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/dependencies/SubstrateStdlib/balance.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/dependencies/SubstrateStdlib/substrate_hash.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/initial_coin_minting.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/register_new_user.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/source_maps/wash_car.mvsm
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/CarWash.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/buy_coin.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/dependencies/MoveStdlib/acl.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/dependencies/MoveStdlib/ascii.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/dependencies/MoveStdlib/bcs.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/dependencies/MoveStdlib/bit_vector.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/dependencies/MoveStdlib/error.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/dependencies/MoveStdlib/fixed_point32.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/dependencies/MoveStdlib/hash.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/dependencies/MoveStdlib/option.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/dependencies/MoveStdlib/signer.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/dependencies/MoveStdlib/string.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/dependencies/MoveStdlib/type_name.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/dependencies/MoveStdlib/vector.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/dependencies/SubstrateStdlib/balance.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/dependencies/SubstrateStdlib/substrate_hash.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/initial_coin_minting.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/register_new_user.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/build/car-wash-example/sources/wash_car.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/hints.md
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/sources/CarWash.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/car-wash-example/sources/Scripts.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/developer-bundle/Move.toml
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/developer-bundle/sources/CarWash.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/developer-bundle/sources/Dorm.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/developer-bundle/sources/EmptyBob.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/gas-costs/Move.toml
create mode 100755 pallets/move-vm/pallet/src/assets/move-projects/gas-costs/build.sh
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/gas-costs/sources/LongScript.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/gas-costs/sources/ModuleNotModule.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/gas-costs/sources/ShortScripts.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/gas-costs/sources/TheModule.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/get-resource/Move.toml
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/get-resource/sources/Count.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/get-resource/sources/Counter.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/get-resource/sources/CreateCounter.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/move-basics/Move.toml
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/move-basics/sources/Empty.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/move-basics/sources/EmptyBob.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/move-basics/sources/Prohibited.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/move-basics/sources/Scripts.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/multiple-signers/Move.toml
create mode 100755 pallets/move-vm/pallet/src/assets/move-projects/multiple-signers/build.sh
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/multiple-signers/hints.md
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/multiple-signers/sources/Dorm.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/multiple-signers/sources/Scripts.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/prohibited-bundle/Move.toml
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/prohibited-bundle/sources/Prohibited1.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/prohibited-bundle/sources/Prohibited2.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/signer-scripts/Move.toml
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/signer-scripts/sources/General.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/signer-scripts/sources/Generics.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/signer-scripts/sources/HelperModule.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/signer-scripts/sources/Vectors.move
create mode 100755 pallets/move-vm/pallet/src/assets/move-projects/smove-build-all.sh
create mode 100755 pallets/move-vm/pallet/src/assets/move-projects/smove-clean-all.sh
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-move-stdlib/Move.toml
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-move-stdlib/README.md
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-move-stdlib/sources/ascii.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-move-stdlib/sources/bcs.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-move-stdlib/sources/bit_vector.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-move-stdlib/sources/error.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-move-stdlib/sources/fixed_point32.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-move-stdlib/sources/hash.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-move-stdlib/sources/option.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-move-stdlib/sources/signer.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-move-stdlib/sources/string.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-move-stdlib/sources/type_name.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-move-stdlib/sources/unit_test.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-move-stdlib/sources/vector.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-substrate-stdlib/Move.toml
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-substrate-stdlib/README.md
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/testing-substrate-stdlib/sources/balance.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/using_stdlib_natives/Move.toml
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/using_stdlib_natives/sources/DependsOnVector.move
create mode 100644 pallets/move-vm/pallet/src/assets/move-projects/using_stdlib_natives/sources/Vector.move
create mode 100644 pallets/move-vm/pallet/src/balance.rs
create mode 100644 pallets/move-vm/pallet/src/benchmarking.rs
create mode 100644 pallets/move-vm/pallet/src/lib.rs
create mode 100644 pallets/move-vm/pallet/src/mock.rs
create mode 100644 pallets/move-vm/pallet/src/mock_utils.rs
create mode 100644 pallets/move-vm/pallet/src/result.rs
create mode 100644 pallets/move-vm/pallet/src/signer.rs
create mode 100644 pallets/move-vm/pallet/src/storage.rs
create mode 100644 pallets/move-vm/pallet/src/tests.rs
create mode 100644 pallets/move-vm/pallet/src/tests/address.rs
create mode 100644 pallets/move-vm/pallet/src/tests/balance.rs
create mode 100644 pallets/move-vm/pallet/src/tests/example.rs
create mode 100644 pallets/move-vm/pallet/src/tests/execute.rs
create mode 100644 pallets/move-vm/pallet/src/tests/gas_costs.rs
create mode 100644 pallets/move-vm/pallet/src/tests/modules.rs
create mode 100644 pallets/move-vm/pallet/src/tests/publish.rs
create mode 100644 pallets/move-vm/pallet/src/tests/signer.rs
create mode 100644 pallets/move-vm/pallet/src/tests/update_stdlib.rs
create mode 100644 pallets/move-vm/pallet/src/weights.rs
create mode 100644 pallets/move-vm/rpc/.gitignore
create mode 100644 pallets/move-vm/rpc/Cargo.toml
create mode 100644 pallets/move-vm/rpc/src/lib.rs
diff --git a/Cargo.toml b/Cargo.toml
index 1dcf507..2f025da 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -28,6 +28,8 @@ members = [
"pallets/assurance",
"pallets/liquidation",
"pallets/assets-bridge",
+ "pallets/move-vm/pallet",
+ "pallets/move-vm/rpc"
]
resolver = "2"
@@ -64,6 +66,11 @@ subxt = {version = "0.33.0"}
subxt-signer = {version = "0.33.0"}
tracing = "0.1.37"
url = "2.4.0"
+anyhow = { version = "1.0", default-features = false }
+blake2 = { version = "0.10", default-features = false }
+hashbrown = { version = "0.14", default-features = false }
+rand = { version = "0.8", default-features = false }
+termcolor = "1.1.3"
# Substrate Client
sc-basic-authorship = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.7.0" }
@@ -223,3 +230,10 @@ pallet-evm-precompile-sha3fips = { version = "2.0.0-dev", git = "https://github.
pallet-evm-precompile-simple = { version = "2.0.0-dev", git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.7.0", default-features = false }
pallet-hotfix-sufficients = { version = "1.0.0", git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.7.0", default-features = false }
precompile-utils = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.7.0", default-features = false }
+
+# Eiger crates
+bcs = { git = "https://github.com/eigerco/bcs.git", branch = "master", default-features = false }
+move-core-types = { git = "https://github.com/eigerco/substrate-move.git", branch = "main", default-features = false }
+move-stdlib = { git = "https://github.com/eigerco/substrate-move.git", branch = "main", default-features = false }
+move-vm-backend = { git = "https://github.com/eigerco/substrate-move.git", branch = "main", default-features = false }
+move-vm-backend-common = { git = "https://github.com/eigerco/substrate-move.git", branch = "main", default-features = false }
diff --git a/node/Cargo.toml b/node/Cargo.toml
index 13560cd..0bb36e5 100644
--- a/node/Cargo.toml
+++ b/node/Cargo.toml
@@ -33,6 +33,7 @@ magnet-primitives-order = { path = "../primitives/order"}
magnet-client-consensus-aura = {path ="../client/consensus/aura"}
pallet-pot-rpc = { path = "../pallets/pot/rpc" }
mp-system = { path = "../primitives/system"}
+pallet-move-rpc = { path = "../pallets/move-vm/rpc" }
# Substrate
frame-benchmarking = { workspace = true }
diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs
index 2527bc8..ef7bdc2 100644
--- a/node/src/chain_spec.rs
+++ b/node/src/chain_spec.rs
@@ -282,5 +282,10 @@ fn testnet_genesis(
},
"evm": { "accounts": evm_accounts },
+ //Move VM
+ "moveModule": {
+ "changeDefaultMoveStdlibBundleTo": Option::>::None,
+ "changeDefaultSubstrateStdlibBundleTo": Option::>::None,
+ }
})
}
diff --git a/node/src/rpc/mod.rs b/node/src/rpc/mod.rs
index de58c75..b1cb868 100644
--- a/node/src/rpc/mod.rs
+++ b/node/src/rpc/mod.rs
@@ -73,6 +73,7 @@ where
C::Api: fp_rpc::ConvertTransactionRuntimeApi,
C::Api: fp_rpc::EthereumRuntimeRPCApi,
C::Api: pallet_pot_rpc::PotRPCApi,
+ C::Api: pallet_move_rpc::MoveRuntimeApi,
C: HeaderBackend + HeaderMetadata + 'static,
C: BlockchainEvents + AuxStore + UsageProvider + StorageProvider,
BE: Backend + 'static,
@@ -81,6 +82,7 @@ where
CIDP: CreateInherentDataProviders + Send + 'static,
CT: fp_rpc::ConvertTransaction<::Extrinsic> + Send + Sync + 'static,
{
+ use pallet_move_rpc::{MoveApiServer, MovePallet};
use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
use sc_consensus_manual_seal::rpc::{ManualSeal, ManualSealApiServer};
use substrate_frame_rpc_system::{System, SystemApiServer};
@@ -90,7 +92,8 @@ where
io.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?;
io.merge(TransactionPayment::new(client.clone()).into_rpc())?;
- io.merge(pallet_pot_rpc::Pot::new(client).into_rpc())?;
+ io.merge(pallet_pot_rpc::Pot::new(client.clone()).into_rpc())?;
+ io.merge(MovePallet::new(client.clone()).into_rpc())?;
if let Some(command_sink) = command_sink {
io.merge(
diff --git a/pallets/move-vm/Cargo.toml b/pallets/move-vm/Cargo.toml
new file mode 100644
index 0000000..9cd9e72
--- /dev/null
+++ b/pallets/move-vm/Cargo.toml
@@ -0,0 +1,44 @@
+[workspace]
+members = [
+ "pallet",
+ "rpc",
+]
+resolver = "2"
+
+[workspace.package]
+edition = "2021"
+authors = ["Eiger "]
+readme = "README.md"
+repository = "https://github.com/eigerco/substrate-movevm-pallet"
+
+[workspace.dependencies]
+# crates.io
+anyhow = { workspace = true, default-features = false }
+bcs = { workspace = true, default-features = false }
+blake2 = { workspace = true, default-features = false }
+codec = { package = "parity-scale-codec", workspace = true, default-features = false, features = ["derive"] }
+hashbrown = { workspace = true, default-features = false }
+hex = { workspace = true, default-features = false }
+jsonrpsee = { workspace = true, default-features = false, features = ["server", "macros", "client-core"] }
+log = { workspace = true, default-features = false }
+rand = { workspace = true, default-features = false }
+scale-info = { workspace = true, default-features = false, features = ["derive"] }
+serde = { workspace = true, default-features = false, features = ["derive"] }
+
+# Polkadot crates
+frame-benchmarking = { workspace = true, default-features = false }
+frame-support = { workspace = true, default-features = false }
+frame-system = { workspace = true, default-features = false }
+pallet-balances = { workspace = true, default-features = false }
+sp-api = { workspace = true, default-features = false }
+sp-blockchain = { workspace = true, default-features = false }
+sp-core = { workspace = true, default-features = false }
+sp-io = { workspace = true, default-features = false }
+sp-runtime = { workspace = true, default-features = false }
+sp-std = { workspace = true, default-features = false }
+
+# Eiger crates
+move-core-types = { workspace = true, features = ["address32"], default-features = false }
+move-stdlib = { workspace = true, features = ["stdlib-bytecode"], default-features = false }
+move-vm-backend = { workspace = true, default-features = false }
+move-vm-backend-common = { workspace = true, default-features = false }
diff --git a/pallets/move-vm/Dockerfile b/pallets/move-vm/Dockerfile
new file mode 100644
index 0000000..8e60b5f
--- /dev/null
+++ b/pallets/move-vm/Dockerfile
@@ -0,0 +1,18 @@
+# syntax=docker/dockerfile:1
+FROM ubuntu:22.04 as builder
+WORKDIR /root
+RUN apt-get update && apt-get upgrade -y && apt-get install -y build-essential protobuf-compiler make gcc g++ curl clang git
+RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.73.0
+ENV PATH=/root/.cargo/bin:$PATH
+WORKDIR /usr/src/move
+RUN git clone https://github.com/eigerco/substrate-move.git
+RUN git clone https://github.com/eigerco/pallet-move.git
+RUN git clone https://github.com/eigerco/substrate-node-template-move-vm-test.git --branch pallet-move
+RUN ./substrate-move/scripts/dev_setup.sh -bypt && cargo install --git https://github.com/eigerco/smove
+RUN cd substrate-node-template-move-vm-test && cargo b -r --features runtime-benchmarks
+
+FROM ubuntu:22.04
+RUN apt-get update && apt-get upgrade -y && rm -rf /var/lib/apt/lists/*
+COPY --from=builder /usr/src/move/substrate-node-template-move-vm-test/target/release/node-template /usr/local/bin/node-template
+EXPOSE 9333 9944 30333
+CMD ["node-template", "--dev"]
diff --git a/pallets/move-vm/LICENSE b/pallets/move-vm/LICENSE
new file mode 100644
index 0000000..d6f97f0
--- /dev/null
+++ b/pallets/move-vm/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Eiger
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/pallets/move-vm/README.md b/pallets/move-vm/README.md
new file mode 100644
index 0000000..edde641
--- /dev/null
+++ b/pallets/move-vm/README.md
@@ -0,0 +1,94 @@
+# Move Pallet
+
+A pallet for substrate based blockchains to enable the usage of smart contracts written in the Move-language.
+
+![Pallet Move connects the Move language with Substrate](doc/assets/pallet-move_substrate_move.png)
+
+
+## Overview
+
+Smart contracts can directly be implemented and executed as Move scripts or modularized in Move modules. Therefor, the pallet supports publishing of Move modules and the execution of Move scripts to achieve this functionality. In the case of larger projects, the pallet provides the publishing of a bundle (multiple Move modules).
+
+For the execution of Move scripts and the publication of Move modules, the Move source code has to be compiled and serialized into bytecode. For this purpose, the tool [`smove`][smove] is provided. The tool also provides further helpful features for developing and working with the Move language and this pallet.
+
+### Requirements
+
+- [Substrate developer environment](https://docs.substrate.io/install/)
+- [smove][smove] is a package manager for Move language in Substrate. Follow the instructions in its repo to install it.
+- [cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html)
+- Docker (not mandatory)
+
+
+## Move Example
+
+A basic sample of the Move module and the Move script is shown below.
+
+```move
+module DeveloperBob::CarWash {
+ /// Buys `count` washing coin(s) for the car wash. Therfor, `COIN_PRICE`*`count` will be withdrawn from the user's account.
+ public fun buy_coin(user: &signer, count: u8) acquires Balance {
+ // ...
+ }
+}
+```
+
+More details about the module above in [our tutorial][tutorial]. For this example, the module got published and the following script only needs to be executed.
+
+```move
+script {
+ use DeveloperBob::CarWash;
+
+ fun buy_coin(account: signer, count: u8) {
+ CarWash::buy_coin(&account, count);
+ }
+}
+```
+
+For a general overview and further details of the Move language, have a look at the [Move Book][move-book].
+
+
+## Tutorial
+
+To dive quickly into the topic, explore our [simple tutorial][tutorial].
+
+
+## Tech Guide
+
+There is a [tech-guide](doc/tech_guide.md) available, where you can find advanced topics like pallet configuration, Docker, and benchmarking.
+
+Read the [design document](doc/final-design.md) to learn more about the pallet API and how it works.
+
+### Template Node
+
+Use [these instructions](doc/tech_guide.md#quickstart-guide-for-the-template-node) to setup the template-node with Move pallet integrated.
+
+### Testing
+
+Verify that everything works fine by running the pallet's unit tests with all features enabled:
+```sh
+cargo test --verbose --features build-move-projects-for-test
+```
+
+You can find further details about testing possibilities [in the tech-guide](doc/tech_guide.md#testing).
+
+
+## Important Note
+
+_The MoveVM pallet is a good starting point for potential parachains that want to support Move._
+_There are more potential improvements to be made._
+_Still, those are yet to be defined and properly implemented within a future parachain project - since it's hard to predict what exactly the parachain might need or not need._
+_The current solution is general and parachain-agnostic._
+_The MoveVM is taken from the Move language repository - any possible safety issues are inherited from that repo._
+_Therefore, the Substrate MoveVM fork ([substrate-move][substrate-move]) should get all upstream changes from that repository._
+_The first parachain adapters should do additional testing to ensure the robustness of the solution._
+
+## License
+
+[MIT](LICENSE) License.
+
+![](doc/assets/web3 foundation_grants_badge_black.png)
+
+[move-book]: https://move-language.github.io/move/introduction.html
+[substrate-move]: https://github.com/eigerco/substrate-move
+[smove]: https://github.com/eigerco/smove
+[tutorial]: doc/tutorial.md
diff --git a/pallets/move-vm/doc/assets/pallet-move_substrate_move.png b/pallets/move-vm/doc/assets/pallet-move_substrate_move.png
new file mode 100644
index 0000000000000000000000000000000000000000..4ff983986906b3190de1b07252865250627937cb
GIT binary patch
literal 92168
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