diff --git a/Cargo.lock b/Cargo.lock index 03dae2f621..705c0cf9af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10157,6 +10157,26 @@ dependencies = [ "test-case", ] +[[package]] +name = "starcoin-asset-mapping" +version = "2.0.1" +dependencies = [ + "anyhow", + "bcs-ext", + "forkable-jellyfish-merkle", + "starcoin-cached-packages", + "starcoin-chain", + "starcoin-config", + "starcoin-consensus", + "starcoin-crypto", + "starcoin-logger", + "starcoin-state-api", + "starcoin-transaction-builder", + "starcoin-types", + "starcoin-vm-types", + "test-helper", +] + [[package]] name = "starcoin-block-relayer" version = "2.0.1" @@ -10597,14 +10617,17 @@ version = "2.0.1" dependencies = [ "anyhow", "bcs-ext", + "forkable-jellyfish-merkle", "hex", "log 0.4.22", "move-transactional-test-runner", "once_cell", "serde", "serde_json", + "sha3", "starcoin-abi-resolver", "starcoin-abi-types", + "starcoin-cached-packages", "starcoin-config", "starcoin-consensus", "starcoin-crypto", @@ -10617,6 +10640,7 @@ dependencies = [ "starcoin-transaction-builder", "starcoin-types", "starcoin-vm-runtime", + "starcoin-vm-runtime-types", "starcoin-vm-types", "stdlib", "stest", diff --git a/Cargo.toml b/Cargo.toml index 5ee2c26fed..7f60cc5d60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -121,6 +121,7 @@ members = [ "cmd/db-exporter", "cmd/genesis-nft-miner", "flexidag", + "asset-mapping", ] default-members = [ @@ -236,6 +237,7 @@ default-members = [ "cmd/miner_client/api", "cmd/db-exporter", "flexidag", + "asset-mapping", ] [workspace.lints.clippy] @@ -511,6 +513,7 @@ starcoin-account-api = { path = "account/api" } starcoin-account-provider = { path = "account/provider" } starcoin-account-service = { path = "account/service" } starcoin-accumulator = { path = "commons/accumulator", package = "starcoin-accumulator" } +starcoin-asset-mapping = { path = "asset-mapping" } starcoin-block-relayer = { path = "block-relayer" } starcoin-chain = { path = "chain" } starcoin-chain-api = { path = "chain/api" } @@ -525,7 +528,7 @@ starcoin-crypto = { git = "https://github.com/starcoinorg/starcoin-crypto", rev starcoin-decrypt = { path = "commons/decrypt" } starcoin-dev = { path = "vm/dev" } starcoin-executor = { path = "executor" } -starcoin-framework = { path = "vm/framework" } +starcoin-framework = { path = "vm/framework", features = ["testing"] } starcoin-sdk-builder = { path = "vm/starcoin-sdk-builder" } starcoin-genesis = { path = "genesis" } starcoin-logger = { path = "commons/logger" } diff --git a/asset-mapping/Cargo.toml b/asset-mapping/Cargo.toml new file mode 100644 index 0000000000..927efd14a1 --- /dev/null +++ b/asset-mapping/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "starcoin-asset-mapping" +version = "2.0.1" +authors = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +publish = { workspace = true } +repository = { workspace = true } +rust-version = { workspace = true } + +[dependencies] +anyhow = { workspace = true } +bcs-ext = { workspace = true } +forkable-jellyfish-merkle = { workspace = true } +starcoin-transaction-builder = { workspace = true } +starcoin-chain = { workspace = true } +starcoin-config = { workspace = true } +starcoin-consensus = { workspace = true } +starcoin-crypto = { workspace = true } +starcoin-cached-packages = { workspace = true } +starcoin-logger = { workspace = true } +starcoin-state-api = { workspace = true } +starcoin-types = { workspace = true } +starcoin-vm-types = { workspace = true } +test-helper = { workspace = true } \ No newline at end of file diff --git a/asset-mapping/src/lib.rs b/asset-mapping/src/lib.rs new file mode 100644 index 0000000000..cc6e52f54f --- /dev/null +++ b/asset-mapping/src/lib.rs @@ -0,0 +1,276 @@ +#[cfg(test)] +mod basic_tests { + use std::str::FromStr; + + use anyhow::Result; + use starcoin_crypto::{hash::PlainCryptoHash, HashValue}; + + use forkable_jellyfish_merkle::{blob::Blob, node_type::SparseMerkleLeafNode, RawKey}; + use starcoin_cached_packages::starcoin_framework_sdk_builder::{ + asset_mapping_assign_to_account_test, asset_mapping_assign_to_account_with_proof, + }; + use starcoin_cached_packages::starcoin_stdlib::{ + starcoin_account_create_account, transfer_scripts_peer_to_peer_v2, + }; + use starcoin_config::{ChainNetwork, G_TEST_CONFIG}; + use starcoin_state_api::ChainStateReader; + use starcoin_types::{ + account_address::AccountAddress, account_config::CORE_CODE_ADDRESS, identifier::Identifier, + language_storage::StructTag, + }; + use starcoin_vm_types::account_config::{stc_struct_tag, CoinStoreResource}; + use starcoin_vm_types::{ + access_path::AccessPath, + account_config::{genesis_address, stc_type_tag}, + genesis_config::ChainId, + state_store::state_key::StateKey, + state_view::StateReaderExt, + }; + use test_helper::executor::{ + association_execute_should_success, prepare_customized_genesis, prepare_genesis, + }; + + #[test] + fn test_get_chain_id_after_genesis_with_proof_verify() -> Result<()> { + let (chain_state, _) = prepare_genesis(); + let chain_id_struct_tag = StructTag { + address: CORE_CODE_ADDRESS, + module: Identifier::new("chain_id").unwrap(), + name: Identifier::new("ChainId").unwrap(), + type_args: vec![], + }; + + let path_statekey = StateKey::resource(&CORE_CODE_ADDRESS, &chain_id_struct_tag)?; + + // Print 0x1 version resource + let resource_value = bcs_ext::from_bytes::( + &chain_state.get_resource(CORE_CODE_ADDRESS, &chain_id_struct_tag)?, + )?; + println!( + "test_get_chain_id_after_genesis_with_proof_verify | path: {:?}, state_value : {:?}", + chain_id_struct_tag, resource_value + ); + assert_eq!(resource_value.id(), 0xff, "not expect chain id"); + + // Get proof and verify proof + let mut state_proof = chain_state.get_with_proof(&path_statekey)?; + let proof_path = AccessPath::resource_access_path(genesis_address(), chain_id_struct_tag); + state_proof.verify(chain_state.state_root(), proof_path.clone())?; + + state_proof.state.as_mut().unwrap()[0] = 0xFE; + assert!(state_proof + .verify(chain_state.state_root(), proof_path) + .is_err()); + Ok(()) + } + + #[test] + fn test_sha3_256_diffrent_with_crypto_macro() -> Result<()> { + starcoin_logger::init_for_test(); + + let element_key_hash = HashValue::from_hex_literal( + "0x4cc8bd9df94b37c233555d9a3bba0a712c3c709f047486d1e624b2bcd3b83266", + )?; + let blob_hash = HashValue::from_hex_literal( + "0x4f2b59b9af93b435e0a33b6ab7a8a90e471dba936be2bc2937629b7782b8ebd0", + )?; + + let leaf_node = SparseMerkleLeafNode::new(element_key_hash, blob_hash); + + let smt_hash = leaf_node.crypto_hash(); + println!( + "test_sha3_256_diffrent_with_crypto_macro | SparseMerkleLeafNode crypto hash: {:?}", + SparseMerkleLeafNode::new(element_key_hash, blob_hash).crypto_hash() + ); + + let ser = bcs_ext::to_bytes(&leaf_node)?; + const STARCOIN_HASH_PREFIX: &[u8] = b"STARCOIN::SparseMerkleLeafNode"; + let hash_vec = [ + HashValue::sha3_256_of(STARCOIN_HASH_PREFIX).as_slice(), + ser.as_slice(), + ] + .concat(); + + let move_hash = HashValue::sha3_256_of(&hash_vec[..]); + println!( + "test_sha3_256_diffrent_with_crypto_macro | sha3 crypto {:?}", + move_hash, + ); + assert_eq!(move_hash, smt_hash, "Failed to get the same hash"); + + let check_blob_hash = Blob::from(Vec::from([255])).crypto_hash(); + assert_eq!( + check_blob_hash, blob_hash, + "Check not equal with crypto_hash from Blob" + ); + + Ok(()) + } + + #[test] + fn test_asset_mapping_for_specified_coin_type() -> Result<()> { + starcoin_logger::init_for_test(); + let (_chain_state, _net) = prepare_genesis(); + let stc_store_tag = StructTag { + address: CORE_CODE_ADDRESS, + module: Identifier::new("coin").unwrap(), + name: Identifier::new("CoinStore").unwrap(), + type_args: vec![stc_type_tag()], + }; + + let access_path = AccessPath::resource_access_path(genesis_address(), stc_store_tag); + let (account_address, data_path) = access_path.into_inner(); + + println!( + "test_asset_mapping_for_specified_coin_type | account {:?}, data_path: {:?}, data_path key hash: {:?}", + account_address, + data_path.encode_key()?, + data_path.key_hash() + ); + Ok(()) + } + + #[test] + fn test_simple_asset_mapping_without_proof() -> Result<()> { + starcoin_logger::init_for_test(); + + let (chain_state, net) = prepare_genesis(); + + // Build alice and transfer STC to alice + let amount = 1000000000; + let alice = AccountAddress::from_str("0xd0c5a06ae6100ce115cad1600fe59e96").unwrap(); + + association_execute_should_success( + &net, + &chain_state, + transfer_scripts_peer_to_peer_v2(stc_type_tag(), alice, amount), + )?; + + // Check alice's balance + assert_eq!( + chain_state.get_balance(alice)?, + amount, + "alice balance not expect" + ); + + association_execute_should_success( + &net, + &chain_state, + asset_mapping_assign_to_account_test( + alice, + "0x1::STC::STC".as_bytes().to_vec(), + amount as u64, + ), + )?; + + assert_eq!( + chain_state.get_balance(alice)?, + amount * 2, + "alice balance not expect after asset-mapping" + ); + + Ok(()) + } + + #[test] + fn test_asset_mapping_whole_process() -> Result<()> { + starcoin_logger::init_for_test(); + + // let _block_gas_limit: u64 = 10000000; + let initial_balance: u128 = 100000000000; // 1000 STC + let alice = AccountAddress::from_str("0xd0c5a06ae6100ce115cad1600fe59e96").unwrap(); + + // Create a source BlockChain + let (proof_root_hash, proof_path_hash, proof_value_hash, proof_siblings) = { + let (chain_state_1, net_1) = prepare_genesis(); + + association_execute_should_success( + &net_1, + &chain_state_1, + transfer_scripts_peer_to_peer_v2(stc_type_tag(), alice, initial_balance), + )?; + + // Check balance is initial_balance + let balance = chain_state_1.get_balance(alice)?; + assert_eq!(balance, initial_balance); + + let state_proof = chain_state_1.get_with_proof(&StateKey::resource( + &alice, + &CoinStoreResource::struct_tag_for_token(stc_struct_tag()), + )?)?; + + ( + chain_state_1.state_root(), + state_proof.proof.account_proof.leaf().unwrap().0, + state_proof.proof.account_proof.leaf().unwrap().1, + state_proof.proof.account_proof.siblings, + ) + }; + + println!( + "test_asset_mapping_whole_process | proof_root_hash: {:?}, proof_path_hash: {:?}, proof_value_hash: {:?}, proof_siblings: {:?}", + proof_root_hash, proof_path_hash, proof_value_hash, proof_siblings, + ); + + // Create a new blockchain and verify proof + { + let custom_chain_id = ChainId::new(100); + let mut genesis_config = G_TEST_CONFIG.clone(); + genesis_config.asset_mapping_root_hash = proof_root_hash; + + let net = ChainNetwork::new_custom( + "asset_mapping_test".parse()?, + custom_chain_id, + genesis_config, + )?; + + let chain_state_2 = prepare_customized_genesis(&net); + + let mut proof_encoded_siblings: Vec = Vec::new(); + proof_siblings.iter().for_each(|hash| { + proof_encoded_siblings.extend_from_slice(hash.as_ref()); + proof_encoded_siblings.push(0x7c); + }); + + // Create account + association_execute_should_success( + &net, + &chain_state_2, + starcoin_account_create_account(alice), + )?; + + assert_eq!(chain_state_2.get_balance(alice)?, 0); + + // Asset mapping for alice + association_execute_should_success( + &net, + &chain_state_2, + asset_mapping_assign_to_account_with_proof( + alice, + "0x1::STC::STC".as_bytes().to_vec(), + proof_path_hash.to_vec(), + proof_value_hash.to_vec(), + proof_encoded_siblings, + initial_balance as u64, + ), + )?; + + assert_eq!(chain_state_2.get_balance(alice)?, initial_balance); + } + + Ok(()) + } + + #[test] + fn test_hash_hello() -> Result<()> { + // 0x3338be694f50c5f338814986cdf0686453a888b84f424d792af4b9202398f392 + let hello_hash = HashValue::sha3_256_of("hello".as_bytes()); + println!("test_hash_hello | {:?}", hello_hash); + assert_eq!( + hello_hash.to_hex_literal(), + "0x3338be694f50c5f338814986cdf0686453a888b84f424d792af4b9202398f392", + "not expect hash" + ); + Ok(()) + } +} diff --git a/cmd/airdrop/src/main.rs b/cmd/airdrop/src/main.rs index 4b056f4aa2..99d24a0d58 100644 --- a/cmd/airdrop/src/main.rs +++ b/cmd/airdrop/src/main.rs @@ -20,7 +20,7 @@ use starcoin_types::language_storage::ModuleId; use starcoin_types::transaction::authenticator::AccountPrivateKey; use starcoin_types::transaction::{EntryFunction, RawUserTransaction}; use starcoin_vm_types::account_config::auto_accept_token::AutoAcceptToken; -use starcoin_vm_types::account_config::{stc_type_tag, BalanceResource, G_STC_TOKEN_CODE}; +use starcoin_vm_types::account_config::{stc_type_tag, CoinStoreResource, G_STC_TOKEN_CODE}; use starcoin_vm_types::language_storage::{StructTag, TypeTag}; use starcoin_vm_types::state_store::state_key::StateKey; use starcoin_vm_types::token::token_code::TokenCode; @@ -80,7 +80,7 @@ async fn is_accept_token( let balance = client .get_resource( address, - BalanceResource::struct_tag_for_token(token_type).into(), + CoinStoreResource::struct_tag_for_token(token_type).into(), None, ) .await diff --git a/cmd/starcoin/src/account/show_cmd.rs b/cmd/starcoin/src/account/show_cmd.rs index f771a9db0c..26ce3429b4 100644 --- a/cmd/starcoin/src/account/show_cmd.rs +++ b/cmd/starcoin/src/account/show_cmd.rs @@ -11,7 +11,7 @@ use starcoin_crypto::ValidCryptoMaterialStringExt; use starcoin_rpc_client::StateRootOption; use starcoin_state_api::{ChainStateReader, StateReaderExt}; use starcoin_vm_types::account_address::AccountAddress; -use starcoin_vm_types::account_config::BalanceResource; +use starcoin_vm_types::account_config::CoinStoreResource; use starcoin_vm_types::token::token_code::TokenCode; use std::collections::HashMap; @@ -74,11 +74,11 @@ impl CommandAction for ShowCommand { .resources .into_iter() .filter_map(|(resource_type, resource)| { - if let Some(token_code) = BalanceResource::token_code(&resource_type.0) { + if let Some(token_code) = CoinStoreResource::token_code(&resource_type.0) { let balance = resource - .decode::() + .decode::() .ok() - .map(|balance| balance.token()); + .map(|balance| balance.coin() as u128); Some((token_code, balance.unwrap_or(0))) } else { None diff --git a/config/example/barnard/genesis_config.json b/config/example/barnard/genesis_config.json index 79e39e530a..37f92ecdcb 100644 --- a/config/example/barnard/genesis_config.json +++ b/config/example/barnard/genesis_config.json @@ -1785,5 +1785,6 @@ }, "time_service_type": "RealTimeService", "transaction_timeout": 86400, - "dag_effective_height": 18446744073709551615 + "dag_effective_height": 18446744073709551615, + "asset_mapping_root_hash": "0x00000000000000000000000000000000" } \ No newline at end of file diff --git a/config/example/main/genesis_config.json b/config/example/main/genesis_config.json index a0dd3291e6..fa16d9d1a0 100644 --- a/config/example/main/genesis_config.json +++ b/config/example/main/genesis_config.json @@ -1789,5 +1789,6 @@ }, "time_service_type": "RealTimeService", "transaction_timeout": 86400, - "dag_effective_height": 18446744073709551615 + "dag_effective_height": 18446744073709551615, + "asset_mapping_root_hash": "0x00000000000000000000000000000000" } \ No newline at end of file diff --git a/config/example/proxima/genesis_config.json b/config/example/proxima/genesis_config.json index df152c3a8b..f75e3172a2 100644 --- a/config/example/proxima/genesis_config.json +++ b/config/example/proxima/genesis_config.json @@ -1913,5 +1913,6 @@ }, "time_service_type": "RealTimeService", "transaction_timeout": 86400, - "dag_effective_height": 0 + "dag_effective_height": 18446744073709551615, + "asset_mapping_root_hash": "0x00000000000000000000000000000000" } \ No newline at end of file diff --git a/config/example/vega/genesis_config.json b/config/example/vega/genesis_config.json index 0d9827ad05..ae56004496 100644 --- a/config/example/vega/genesis_config.json +++ b/config/example/vega/genesis_config.json @@ -1789,5 +1789,6 @@ }, "time_service_type": "RealTimeService", "transaction_timeout": 86400, - "dag_effective_height": 0 + "dag_effective_height": 0, + "asset_mapping_root_hash": "0x00000000000000000000000000000000" } \ No newline at end of file diff --git a/config/src/genesis_config.rs b/config/src/genesis_config.rs index 802ac5f449..4f2aba7a7f 100644 --- a/config/src/genesis_config.rs +++ b/config/src/genesis_config.rs @@ -650,6 +650,9 @@ pub struct GenesisConfig { /// Flexidag effective height pub dag_effective_height: u64, + + /// Asset mapping proof root hash + pub asset_mapping_root_hash: HashValue, } impl GenesisConfig { @@ -799,6 +802,7 @@ pub static G_DAG_TEST_CONFIG: Lazy = Lazy::new(|| { }, transaction_timeout: ONE_DAY, dag_effective_height: 0, + asset_mapping_root_hash: HashValue::zero(), } }); @@ -854,6 +858,7 @@ pub static G_TEST_CONFIG: Lazy = Lazy::new(|| { }, transaction_timeout: ONE_DAY, dag_effective_height: u64::MAX, + asset_mapping_root_hash: HashValue::zero(), } }); @@ -912,6 +917,7 @@ pub static G_DEV_CONFIG: Lazy = Lazy::new(|| { }, transaction_timeout: ONE_DAY, dag_effective_height: 0, + asset_mapping_root_hash: HashValue::zero(), } }); @@ -975,6 +981,7 @@ pub static G_HALLEY_CONFIG: Lazy = Lazy::new(|| { }, transaction_timeout: ONE_DAY, dag_effective_height: 0, + asset_mapping_root_hash: HashValue::zero(), } }); @@ -1034,6 +1041,7 @@ pub static G_PROXIMA_CONFIG: Lazy = Lazy::new(|| { }, transaction_timeout: ONE_DAY, dag_effective_height: u64::MAX, + asset_mapping_root_hash: HashValue::zero(), } }); @@ -1092,6 +1100,7 @@ pub static G_BARNARD_CONFIG: Lazy = Lazy::new(|| { }, transaction_timeout: ONE_DAY, dag_effective_height: u64::MAX, + asset_mapping_root_hash: HashValue::zero(), } }); @@ -1164,6 +1173,8 @@ pub static G_MAIN_CONFIG: Lazy = Lazy::new(|| { }, transaction_timeout: ONE_DAY, dag_effective_height: u64::MAX, + // TODO(BobOng): [asset-mapping] To confirm the asset mapping proof root hash + asset_mapping_root_hash: HashValue::zero(), } }); @@ -1218,6 +1229,7 @@ pub static G_VEGA_CONFIG: Lazy = Lazy::new(|| { }, transaction_timeout: ONE_DAY, dag_effective_height: 0, + asset_mapping_root_hash: HashValue::zero(), } }); diff --git a/executor/Cargo.toml b/executor/Cargo.toml index 58ef99ad84..c191aa0b44 100644 --- a/executor/Cargo.toml +++ b/executor/Cargo.toml @@ -27,11 +27,15 @@ starcoin-transaction-builder = { workspace = true } starcoin-state-tree = { workspace = true } starcoin-statedb = { workspace = true } starcoin-vm-runtime = { workspace = true } +starcoin-vm-runtime-types = { workspace = true } +starcoin-cached-packages = { workspace = true } stdlib = { workspace = true } stest = { workspace = true } tempfile = { workspace = true } test-helper = { workspace = true } move-transactional-test-runner = { workspace = true } +forkable-jellyfish-merkle = { workspace = true } +sha3 = { workspace = true } [features] default = [] diff --git a/executor/tests/executor_test.rs b/executor/tests/executor_test.rs index cbb07528ae..b79eee27b8 100644 --- a/executor/tests/executor_test.rs +++ b/executor/tests/executor_test.rs @@ -1,51 +1,61 @@ // Copyright (c) The Starcoin Core Contributors // SPDX-License-Identifier: Apache-2.0 -use anyhow::anyhow; -use anyhow::Result; +use anyhow::{anyhow, Result}; +use starcoin_cached_packages::starcoin_framework_sdk_builder::starcoin_account_create_account; + use starcoin_config::{BuiltinNetworkID, ChainNetwork}; use starcoin_executor::validate_transaction; use starcoin_logger::prelude::*; +use starcoin_state_api::StateReaderExt; + use starcoin_transaction_builder::{ - build_batch_payload_same_amount, build_transfer_txn, encode_transfer_script_by_token_code, - raw_peer_to_peer_txn, DEFAULT_EXPIRATION_TIME, DEFAULT_MAX_GAS_AMOUNT, + build_batch_payload_same_amount, build_transfer_txn, empty_test_metadata, + encode_transfer_script_by_token_code, raw_peer_to_peer_txn, DEFAULT_EXPIRATION_TIME, + DEFAULT_MAX_GAS_AMOUNT, }; -use starcoin_types::account::peer_to_peer_txn; -use starcoin_types::identifier::Identifier; -use starcoin_types::language_storage::ModuleId; -use starcoin_types::transaction::{EntryFunction, RawUserTransaction, TransactionArgument}; -use starcoin_types::{ - account_config, block_metadata::BlockMetadata, transaction::Transaction, - transaction::TransactionPayload, transaction::TransactionStatus, +use starcoin_vm_runtime::{ + data_cache::AsMoveResolver, + move_vm_ext::ResourceGroupResolver, + starcoin_vm::{chunk_block_transactions, StarcoinVM}, +}; +use starcoin_vm_types::{ + account_config::{ + core_code_address, fungible_store, genesis_address, AccountResource, FungibleStoreResource, + }, + genesis_config::ChainId, + on_chain_config::{ConsensusConfig, OnChainConfig}, + state_store::{state_key::StateKey, state_value::StateValue, TStateView}, + token::stc::{stc_type_tag, STCUnit}, + transaction::Package, + vm_status::{KeptVMStatus, StatusCode}, }; -use starcoin_vm_types::account_config::genesis_address; -use starcoin_vm_types::account_config::AccountResource; -use starcoin_vm_types::genesis_config::ChainId; -use starcoin_vm_types::on_chain_config::{ConsensusConfig, OnChainConfig}; -use starcoin_vm_types::state_store::TStateView; -use starcoin_vm_types::token::stc::{stc_type_tag, STCUnit}; -use starcoin_vm_types::vm_status::KeptVMStatus; -use starcoin_vm_types::{transaction::Package, vm_status::StatusCode}; use test_helper::executor::{ account_execute, account_execute_should_success, association_execute_should_success, - blockmeta_execute, build_raw_txn, current_block_number, prepare_customized_genesis, - TEST_MODULE, TEST_MODULE_1, TEST_MODULE_2, + blockmeta_execute, build_raw_txn, compile_modules_with_address, current_block_number, + execute_and_apply, get_balance, get_sequence_number, prepare_customized_genesis, + prepare_genesis, TEST_MODULE, TEST_MODULE_1, TEST_MODULE_2, }; -// use test_helper::Account; -use starcoin_state_api::StateReaderExt; -use starcoin_types::account::Account; -use starcoin_types::account_config::G_STC_TOKEN_CODE; -use starcoin_vm_runtime::starcoin_vm::{chunk_block_transactions, StarcoinVM}; -use starcoin_vm_types::account_config::core_code_address; -use starcoin_vm_types::state_store::state_key::StateKey; -use starcoin_vm_types::state_store::state_value::StateValue; -use test_helper::executor::{ - compile_modules_with_address, execute_and_apply, get_balance, get_sequence_number, - prepare_genesis, -}; use test_helper::txn::create_account_txn_sent_as_association; +use starcoin_types::{ + account::{peer_to_peer_txn, Account}, + account_address::AccountAddress, + account_config, + account_config::G_STC_TOKEN_CODE, + block_metadata::BlockMetadata, + identifier::Identifier, + language_storage::{ModuleId, StructTag}, + transaction::{ + EntryFunction, RawUserTransaction, Transaction, TransactionArgument, TransactionPayload, + TransactionStatus, + }, +}; +use starcoin_vm_runtime_types::{ + resolver::TResourceGroupView, resource_group_adapter::ResourceGroupAdapter, +}; + #[derive(Default)] pub struct NullStateView; @@ -1134,3 +1144,100 @@ fn test_chunk_block_transactions() -> Result<()> { Ok(()) } + +#[test] +fn test_genesis_writeset_for_object() -> Result<()> { + starcoin_logger::init_for_test(); + + let (chain_statedb, _network) = prepare_genesis(); + let state_key = StateKey::resource_group( + &genesis_address(), + &StructTag { + address: genesis_address(), + module: Identifier::new("object").unwrap(), + name: Identifier::new("ObjectGroup").unwrap(), + type_args: vec![], + }, + ); + let object_core_tag = StructTag { + address: genesis_address(), + module: Identifier::new("object").unwrap(), + name: Identifier::new("ObjectCore").unwrap(), + type_args: vec![], + }; + let resource_group_adapter = chain_statedb.as_move_resolver(); + assert!(resource_group_adapter + .resource_exists_in_group(&state_key, &object_core_tag) + .unwrap()); + Ok(()) +} + +#[test] +fn empty_scripts_test_metadata() { + starcoin_logger::init_for_test(); + + let (chain_state, net) = prepare_genesis(); + + //let _ = genesis_execute_should_sucess(&chain_state, &net, empty_test_metadata()); + let _ = association_execute_should_success(&net, &chain_state, empty_test_metadata()); +} + +#[test] +fn test_create_new_account_and_check_primary_fungible_store() -> Result<()> { + starcoin_logger::init_for_test(); + + let (chain_state, net) = prepare_genesis(); + let test_addr = AccountAddress::from_hex_literal("0xd0c5a06ae6100ce115cad1600fe59e96").unwrap(); + let store_addr = + AccountAddress::from_hex_literal("0x786d516a2228196dff48bf39a4b085f0").unwrap(); + + association_execute_should_success( + &net, + &chain_state, + starcoin_account_create_account(test_addr), + )?; + + let primary_store_address = fungible_store::primary_store(&test_addr, &AccountAddress::ONE); + assert_eq!(primary_store_address, store_addr, "store address not equal"); + + let object_group_tag = StructTag { + address: genesis_address(), + module: Identifier::new("object").unwrap(), + name: Identifier::new("ObjectGroup").unwrap(), + type_args: vec![], + }; + let fungible_store_tag = FungibleStoreResource::struct_tag_for_resource(); + + let resource_group_adapter = ResourceGroupAdapter::new( + None, + &chain_state, + /*LATEST_GAS_FEATURE_VERSION*/ 13, + false, + ); + + assert!( + resource_group_adapter.resource_exists_in_group( + &StateKey::resource_group(&store_addr, &object_group_tag,), + &fungible_store_tag, + )?, + "should exist" + ); + + // Get resrouce from group + let readed_bytes = resource_group_adapter + .get_resource_from_group( + &StateKey::resource_group(&store_addr, &object_group_tag), + &fungible_store_tag, + None, + ) + .unwrap(); + assert!(readed_bytes.is_some(), "Except not none"); + + assert_eq!( + bcs_ext::from_bytes::(&readed_bytes.unwrap())?.balance() as u128, + 0, + "balance should be 0" + ); + + Ok(()) +} diff --git a/genesis/generated/barnard/genesis b/genesis/generated/barnard/genesis index c797991f5e..a724de8b79 100644 Binary files a/genesis/generated/barnard/genesis and b/genesis/generated/barnard/genesis differ diff --git a/genesis/generated/halley/genesis b/genesis/generated/halley/genesis index 12ebe68c97..de82d32b01 100644 Binary files a/genesis/generated/halley/genesis and b/genesis/generated/halley/genesis differ diff --git a/genesis/generated/main/genesis b/genesis/generated/main/genesis index 194a0c1d52..be5c4fdaa8 100644 Binary files a/genesis/generated/main/genesis and b/genesis/generated/main/genesis differ diff --git a/genesis/generated/proxima/genesis b/genesis/generated/proxima/genesis index 5014aa9efa..03c7e66562 100644 Binary files a/genesis/generated/proxima/genesis and b/genesis/generated/proxima/genesis differ diff --git a/genesis/generated/vega/genesis b/genesis/generated/vega/genesis index 9f11c1b37f..f2b47c2a2a 100644 Binary files a/genesis/generated/vega/genesis and b/genesis/generated/vega/genesis differ diff --git a/state/statedb/src/lib.rs b/state/statedb/src/lib.rs index 28ba9563ba..687ef3383b 100644 --- a/state/statedb/src/lib.rs +++ b/state/statedb/src/lib.rs @@ -139,6 +139,7 @@ impl AccountStateObject { } pub fn set(&self, data_path: DataPath, value: Vec) { + let _human_str = format!("{}", data_path); match data_path { DataPath::Code(module_name) => { if self.code_tree.lock().is_none() { @@ -167,6 +168,7 @@ impl AccountStateObject { let struct_tag = data_path .as_struct_tag() .expect("DataPath must been struct tag at here."); + eprintln!("remove resource {}", struct_tag); self.resource_tree.lock().remove(struct_tag); Ok(()) } diff --git a/test-helper/src/executor.rs b/test-helper/src/executor.rs index 77a24fe118..928fa28290 100644 --- a/test-helper/src/executor.rs +++ b/test-helper/src/executor.rs @@ -190,6 +190,16 @@ pub fn account_execute_should_success( user_execute_should_success(*account.address(), account.private_key(), state, payload) } +pub fn genesis_execute_should_sucess( + state: &ChainStateDB, + net: &ChainNetwork, + payload: TransactionPayload, +) -> Result { + let txn = build_raw_txn(genesis_address(), state, payload, None); + let txn = net.genesis_config().clone().sign_with_genesis(txn)?; + execute_signed_txn_should_success(state, txn) +} + pub fn account_execute_with_output( account: &Account, state: &ChainStateDB, diff --git a/vm/e2e-tests/src/account.rs b/vm/e2e-tests/src/account.rs index 14af3d577a..527ed8d052 100644 --- a/vm/e2e-tests/src/account.rs +++ b/vm/e2e-tests/src/account.rs @@ -10,7 +10,7 @@ use starcoin_crypto::ed25519::{Ed25519PrivateKey, Ed25519PublicKey}; use starcoin_crypto::keygen::KeyGen; use starcoin_vm_types::access_path::AccessPath; use starcoin_vm_types::account_address::AccountAddress; -use starcoin_vm_types::account_config::{genesis_address, AccountResource, BalanceResource}; +use starcoin_vm_types::account_config::{genesis_address, AccountResource, CoinStoreResource}; use starcoin_vm_types::event::{EventHandle, EventKey}; use starcoin_vm_types::genesis_config::ChainId; use starcoin_vm_types::language_storage::StructTag; @@ -135,7 +135,7 @@ impl Account { pub fn make_coin_store_access_path(&self) -> AccessPath { // TODO(BobOng): // self.make_access_path(CoinStoreResource::struct_tag()) - self.make_access_path(BalanceResource::struct_tag()) + self.make_access_path(CoinStoreResource::struct_tag()) } // TODO: plug in the account type @@ -619,7 +619,7 @@ impl AccountData { .simple_serialize(&CoinStore::layout()) .unwrap(); write_set.push(( - StateKey::resource_typed::(self.address()).unwrap(), + StateKey::resource_typed::(self.address()).unwrap(), WriteOp::legacy_modification(balance.into()), )); diff --git a/vm/e2e-tests/src/account_universe.rs b/vm/e2e-tests/src/account_universe.rs index 9cd85969b7..4432a58ae2 100644 --- a/vm/e2e-tests/src/account_universe.rs +++ b/vm/e2e-tests/src/account_universe.rs @@ -421,7 +421,7 @@ pub fn assert_accounts_match( ); prop_assert_eq!( account.balance() as u128, - coin_store_resource.token(), + coin_store_resource.coin() as u128, "account {} should have correct balance", idx ); diff --git a/vm/e2e-tests/src/executor.rs b/vm/e2e-tests/src/executor.rs index 79c3b173bd..01c24ec540 100644 --- a/vm/e2e-tests/src/executor.rs +++ b/vm/e2e-tests/src/executor.rs @@ -20,7 +20,7 @@ use starcoin_vm_runtime::VMExecutor; use starcoin_vm_types::{ account_address::AccountAddress, account_config::block::NewBlockEvent, - account_config::{AccountResource, BalanceResource, CORE_CODE_ADDRESS}, + account_config::{AccountResource, CoinStoreResource, CORE_CODE_ADDRESS}, block_metadata::BlockMetadata, errors::Location, genesis_config::ChainId, @@ -297,7 +297,7 @@ impl FakeExecutor { } /// Reads the CoinStore resource value for an account from this executor's data store. - pub fn read_coin_store_resource(&self, account: &Account) -> Option { + pub fn read_coin_store_resource(&self, account: &Account) -> Option { self.read_coin_store_resource_at_address(account.address()) } @@ -306,7 +306,7 @@ impl FakeExecutor { pub fn read_coin_store_resource_at_address( &self, addr: &AccountAddress, - ) -> Option { + ) -> Option { self.read_resource(addr) } diff --git a/vm/framework/cached-packages/src/starcoin_framework_sdk_builder.rs b/vm/framework/cached-packages/src/starcoin_framework_sdk_builder.rs index 56082b2e16..cc950c8adf 100644 --- a/vm/framework/cached-packages/src/starcoin_framework_sdk_builder.rs +++ b/vm/framework/cached-packages/src/starcoin_framework_sdk_builder.rs @@ -150,6 +150,21 @@ pub enum EntryFunctionCall { cap_update_table: Vec, }, + AssetMappingAssignToAccountTest { + receiver: AccountAddress, + old_token_str: Vec, + amount: u64, + }, + + AssetMappingAssignToAccountWithProof { + receiper: AccountAddress, + old_token_str: Vec, + proof_path_hash: Vec, + proof_value_hash: Vec, + proof_siblings: Vec, + amount: u64, + }, + CoinCreateCoinConversionMap {}, /// Create STC pairing by passing `StarcoinCoin`. @@ -289,6 +304,8 @@ pub enum EntryFunctionCall { EmptyScriptsEmptyScript {}, + EmptyScriptsTestMetadata {}, + /// Withdraw an `amount` of coin `CoinType` from `account` and burn it. ManagedCoinBurn { coin_type: TypeTag, @@ -518,6 +535,7 @@ pub enum EntryFunctionCall { transaction_timeout: u64, dag_effective_height: u64, features: Vec, + asset_mapping_proof_root: Vec, }, /// Batch transfer token to others. @@ -642,6 +660,26 @@ impl EntryFunctionCall { new_public_key_bytes, cap_update_table, ), + AssetMappingAssignToAccountTest { + receiver, + old_token_str, + amount, + } => asset_mapping_assign_to_account_test(receiver, old_token_str, amount), + AssetMappingAssignToAccountWithProof { + receiper, + old_token_str, + proof_path_hash, + proof_value_hash, + proof_siblings, + amount, + } => asset_mapping_assign_to_account_with_proof( + receiper, + old_token_str, + proof_path_hash, + proof_value_hash, + proof_siblings, + amount, + ), CoinCreateCoinConversionMap {} => coin_create_coin_conversion_map(), CoinCreatePairing { coin_type } => coin_create_pairing(coin_type), CoinMigrateToFungibleStore { coin_type } => coin_migrate_to_fungible_store(coin_type), @@ -754,6 +792,7 @@ impl EntryFunctionCall { easy_gas_script_withdraw_gas_fee_entry(token_type, amount) } EmptyScriptsEmptyScript {} => empty_scripts_empty_script(), + EmptyScriptsTestMetadata {} => empty_scripts_test_metadata(), ManagedCoinBurn { coin_type, amount } => managed_coin_burn(coin_type, amount), ManagedCoinInitialize { coin_type, @@ -930,6 +969,7 @@ impl EntryFunctionCall { transaction_timeout, dag_effective_height, features, + asset_mapping_proof_root, } => stc_genesis_initialize( stdlib_version, reward_delay, @@ -963,6 +1003,7 @@ impl EntryFunctionCall { transaction_timeout, dag_effective_height, features, + asset_mapping_proof_root, ), TransferScriptsBatchPeerToPeer { token_type, @@ -1254,6 +1295,52 @@ pub fn account_rotate_authentication_key_with_rotation_capability( )) } +pub fn asset_mapping_assign_to_account_test( + receiver: AccountAddress, + old_token_str: Vec, + amount: u64, +) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), + ident_str!("asset_mapping").to_owned(), + ), + ident_str!("assign_to_account_test").to_owned(), + vec![], + vec![ + bcs::to_bytes(&receiver).unwrap(), + bcs::to_bytes(&old_token_str).unwrap(), + bcs::to_bytes(&amount).unwrap(), + ], + )) +} + +pub fn asset_mapping_assign_to_account_with_proof( + receiper: AccountAddress, + old_token_str: Vec, + proof_path_hash: Vec, + proof_value_hash: Vec, + proof_siblings: Vec, + amount: u64, +) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), + ident_str!("asset_mapping").to_owned(), + ), + ident_str!("assign_to_account_with_proof").to_owned(), + vec![], + vec![ + bcs::to_bytes(&receiper).unwrap(), + bcs::to_bytes(&old_token_str).unwrap(), + bcs::to_bytes(&proof_path_hash).unwrap(), + bcs::to_bytes(&proof_value_hash).unwrap(), + bcs::to_bytes(&proof_siblings).unwrap(), + bcs::to_bytes(&amount).unwrap(), + ], + )) +} + pub fn coin_create_coin_conversion_map() -> TransactionPayload { TransactionPayload::EntryFunction(EntryFunction::new( ModuleId::new( @@ -1640,6 +1727,18 @@ pub fn empty_scripts_empty_script() -> TransactionPayload { )) } +pub fn empty_scripts_test_metadata() -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), + ident_str!("empty_scripts").to_owned(), + ), + ident_str!("test_metadata").to_owned(), + vec![], + vec![], + )) +} + /// Withdraw an `amount` of coin `CoinType` from `account` and burn it. pub fn managed_coin_burn(coin_type: TypeTag, amount: u64) -> TransactionPayload { TransactionPayload::EntryFunction(EntryFunction::new( @@ -2192,6 +2291,7 @@ pub fn stc_genesis_initialize( transaction_timeout: u64, dag_effective_height: u64, features: Vec, + asset_mapping_proof_root: Vec, ) -> TransactionPayload { TransactionPayload::EntryFunction(EntryFunction::new( ModuleId::new( @@ -2233,6 +2333,7 @@ pub fn stc_genesis_initialize( bcs::to_bytes(&transaction_timeout).unwrap(), bcs::to_bytes(&dag_effective_height).unwrap(), bcs::to_bytes(&features).unwrap(), + bcs::to_bytes(&asset_mapping_proof_root).unwrap(), ], )) } @@ -2521,6 +2622,37 @@ mod decoder { } } + pub fn asset_mapping_assign_to_account_test( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AssetMappingAssignToAccountTest { + receiver: bcs::from_bytes(script.args().get(0)?).ok()?, + old_token_str: bcs::from_bytes(script.args().get(1)?).ok()?, + amount: bcs::from_bytes(script.args().get(2)?).ok()?, + }) + } else { + None + } + } + + pub fn asset_mapping_assign_to_account_with_proof( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AssetMappingAssignToAccountWithProof { + receiper: bcs::from_bytes(script.args().get(0)?).ok()?, + old_token_str: bcs::from_bytes(script.args().get(1)?).ok()?, + proof_path_hash: bcs::from_bytes(script.args().get(2)?).ok()?, + proof_value_hash: bcs::from_bytes(script.args().get(3)?).ok()?, + proof_siblings: bcs::from_bytes(script.args().get(4)?).ok()?, + amount: bcs::from_bytes(script.args().get(5)?).ok()?, + }) + } else { + None + } + } + pub fn coin_create_coin_conversion_map( payload: &TransactionPayload, ) -> Option { @@ -2802,6 +2934,14 @@ mod decoder { } } + pub fn empty_scripts_test_metadata(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(_script) = payload { + Some(EntryFunctionCall::EmptyScriptsTestMetadata {}) + } else { + None + } + } + pub fn managed_coin_burn(payload: &TransactionPayload) -> Option { if let TransactionPayload::EntryFunction(script) = payload { Some(EntryFunctionCall::ManagedCoinBurn { @@ -3233,6 +3373,7 @@ mod decoder { transaction_timeout: bcs::from_bytes(script.args().get(29)?).ok()?, dag_effective_height: bcs::from_bytes(script.args().get(30)?).ok()?, features: bcs::from_bytes(script.args().get(31)?).ok()?, + asset_mapping_proof_root: bcs::from_bytes(script.args().get(32)?).ok()?, }) } else { None @@ -3407,6 +3548,14 @@ static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazy + +# Module `0x1::asset_mapping` + +Asset Mapping Module +This module implements functionality for managing fungible asset mappings in the Starcoin framework. +It provides capabilities for creating stores, managing balances, and assigning assets to accounts +with proof verification. + + +- [Resource `AssetMappingStore`](#0x1_asset_mapping_AssetMappingStore) +- [Resource `AssetMappingStoreT`](#0x1_asset_mapping_AssetMappingStoreT) +- [Resource `AssetMappingPool`](#0x1_asset_mapping_AssetMappingPool) +- [Constants](#@Constants_0) +- [Function `initialize`](#0x1_asset_mapping_initialize) +- [Function `create_store_from_coin`](#0x1_asset_mapping_create_store_from_coin) +- [Function `create_store_for_coin_type`](#0x1_asset_mapping_create_store_for_coin_type) +- [Function `fungible_store_balance`](#0x1_asset_mapping_fungible_store_balance) +- [Function `assign_to_account_with_proof`](#0x1_asset_mapping_assign_to_account_with_proof) +- [Function `assign_to_account_test`](#0x1_asset_mapping_assign_to_account_test) +- [Function `assign_to_account`](#0x1_asset_mapping_assign_to_account) +- [Function `calculation_proof`](#0x1_asset_mapping_calculation_proof) + + +
use 0x1::coin;
+use 0x1::debug;
+use 0x1::error;
+use 0x1::fungible_asset;
+use 0x1::object;
+use 0x1::primary_fungible_store;
+use 0x1::signer;
+use 0x1::simple_map;
+use 0x1::starcoin_proof_verifier;
+use 0x1::stc_util;
+use 0x1::string;
+use 0x1::system_addresses;
+
+ + + + + +## Resource `AssetMappingStore` + +AssetMappingStore represents a store for mapped assets +Contains: +- extend_ref: Reference for extending object capabilities +- fungible_store: The actual store holding fungible assets +- fungible_metadata: The type of fungible assets + + +
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]
+struct AssetMappingStore has store, key
+
+ + + +
+Fields + + +
+
+extend_ref: object::ExtendRef +
+
+ +
+
+fungible_store: object::Object<fungible_asset::FungibleStore> +
+
+ +
+
+metadata: object::Object<fungible_asset::Metadata> +
+
+ +
+
+ + +
+ + + +## Resource `AssetMappingStoreT` + + + +
struct AssetMappingStoreT<T> has key
+
+ + + +
+Fields + + +
+
+coin: coin::Coin<T> +
+
+ +
+
+old_path_str: vector<u8> +
+
+ +
+
+ + +
+ + + +## Resource `AssetMappingPool` + +AssetMappingCoinType represents a mapping that from old version token types to now version asset stores +eg. 0x1::STC::STC -> 0x1::starcoin_coin::STC + + +
struct AssetMappingPool has store, key
+
+ + + +
+Fields + + +
+
+proof_root: vector<u8> +
+
+ +
+
+token_mapping: simple_map::SimpleMap<string::String, address> +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ASSET_MAPPING_OBJECT_SEED: vector<u8> = [97, 115, 115, 101, 116, 45, 109, 97, 112, 112, 105, 110, 103];
+
+ + + + + + + +
const EINVALID_ASSET_MAPPING_POOL: u64 = 104;
+
+ + + + + + + +
const EINVALID_DEPOSIT: u64 = 105;
+
+ + + + + + + +
const EINVALID_NOT_PROOF: u64 = 103;
+
+ + + + + + + +
const EINVALID_PROOF_ROOT: u64 = 102;
+
+ + + + + +Error code for invalid signer + + +
const EINVALID_SIGNER: u64 = 101;
+
+ + + + + +## Function `initialize` + +Initializes the asset mapping pool +@param framework - The framework signer +@param proof_root - Initial proof root for verification +Verifies the framework signer and creates a new AssetMappingPool + + +
public fun initialize(framework: &signer, proof_root: vector<u8>)
+
+ + + +
+Implementation + + +
public fun initialize(framework: &signer, proof_root: vector<u8>) {
+    assert!(
+        signer::address_of(framework) == system_addresses::get_starcoin_framework(),
+        error::unauthenticated(EINVALID_SIGNER)
+    );
+    move_to(framework, AssetMappingPool {
+        token_mapping: simple_map::new(),
+        proof_root,
+    });
+}
+
+ + + +
+ + + +## Function `create_store_from_coin` + +Creates a new store from a coin +@param token_issuer - The token issuer signer +@param coin - The coin to be stored +Requirements: +- Token issuer must be authorized for the given token type +- Converts coin to fungible asset and stores it + + +
public fun create_store_from_coin<T: key>(token_issuer: &signer, old_token_str: vector<u8>, coin: coin::Coin<T>)
+
+ + + +
+Implementation + + +
public fun create_store_from_coin<T: key>(
+    token_issuer: &signer,
+    old_token_str: vector<u8>,
+    coin: coin::Coin<T>
+) acquires AssetMappingPool {
+    debug::print(&string::utf8(b"asset_mapping::create_store_from_coin | entered"));
+
+    let token_issuer_addr = signer::address_of(token_issuer);
+    assert!(
+        token_issuer_addr == stc_util::token_issuer<T>(),
+        error::unauthenticated(EINVALID_SIGNER)
+    );
+
+    debug::print(&string::utf8(b"asset_mapping::create_store_from_coin | coin_to_fungible_asset"));
+
+    let fungible_asset = coin::coin_to_fungible_asset(coin);
+
+    let (
+        metadata,
+        fungible_store,
+        extend_ref
+    ) = create_store_for_coin_type<T>(token_issuer);
+
+    debug::print(&string::utf8(b"asset_mapping::create_store_from_coin | created token store"));
+    debug::print(&fungible_store);
+
+    fungible_asset::deposit(fungible_store, fungible_asset);
+
+    // Add token mapping coin type
+    let asset_coin_type =
+        borrow_global_mut<AssetMappingPool>(system_addresses::get_starcoin_framework());
+
+    let store_constructor_ref = &object::create_object(system_addresses::get_core_resource_address());
+    let store_signer = &object::generate_signer(store_constructor_ref);
+    move_to(store_signer, AssetMappingStore {
+        extend_ref,
+        fungible_store,
+        metadata,
+    });
+
+    simple_map::add(
+        &mut asset_coin_type.token_mapping,
+        string::utf8(old_token_str),
+        object::address_from_constructor_ref(store_constructor_ref),
+    );
+
+    debug::print(&string::utf8(b"asset_mapping::create_store_from_coin | exited"));
+}
+
+ + + +
+ + + +## Function `create_store_for_coin_type` + +Creates a store for a specific token type +@param framework - The framework signer +@returns (metadata, store, extend_ref): +- metadata: Token metadata object +- store: Created fungible store +- extend_ref: Extension reference for the store + + +
fun create_store_for_coin_type<T>(account: &signer): (object::Object<fungible_asset::Metadata>, object::Object<fungible_asset::FungibleStore>, object::ExtendRef)
+
+ + + +
+Implementation + + +
fun create_store_for_coin_type<T>(account: &signer): (Object<Metadata>, Object<FungibleStore>, ExtendRef) {
+    debug::print(&std::string::utf8(b"asset_mapping::create_store_for_type | entered"));
+
+    let metadata = coin::ensure_paired_metadata<T>();
+    let construct_ref = object::create_object_from_account(account);
+
+    let store = fungible_asset::create_store(&construct_ref, metadata);
+
+    // Generate extend reference
+    let extend_ref = object::generate_extend_ref(&construct_ref);
+    debug::print(&std::string::utf8(b"asset_mapping::create_store_for_type | exited"));
+
+    (metadata, store, extend_ref)
+}
+
+ + + +
+ + + +## Function `fungible_store_balance` + +Retrieves the balance for a specific token type +@returns Current balance of the token in the mapping pool + + +
fun fungible_store_balance(old_asset_str: vector<u8>): u64
+
+ + + +
+Implementation + + +
fun fungible_store_balance(old_asset_str: vector<u8>): u64 acquires AssetMappingPool, AssetMappingStore {
+    let pool = borrow_global<AssetMappingPool>(system_addresses::get_starcoin_framework());
+    let store_object_addr = simple_map::borrow(&pool.token_mapping, &string::utf8(old_asset_str));
+    let mapping_store = borrow_global<AssetMappingStore>(*store_object_addr);
+    fungible_asset::balance(mapping_store.fungible_store)
+}
+
+ + + +
+ + + +## Function `assign_to_account_with_proof` + + + +
public entry fun assign_to_account_with_proof(token_issuer: &signer, receiper: address, old_token_str: vector<u8>, proof_path_hash: vector<u8>, proof_value_hash: vector<u8>, proof_siblings: vector<u8>, amount: u64)
+
+ + + +
+Implementation + + +
public entry fun assign_to_account_with_proof(
+    token_issuer: &signer,
+    receiper: address,
+    old_token_str: vector<u8>,
+    proof_path_hash: vector<u8>,
+    proof_value_hash: vector<u8>,
+    proof_siblings: vector<u8>,
+    amount: u64
+) acquires AssetMappingPool, AssetMappingStore {
+    assert!(
+        exists<AssetMappingPool>(system_addresses::get_starcoin_framework()),
+        error::invalid_state(EINVALID_PROOF_ROOT)
+    );
+
+    // Verify that the token type of the request mapping is the passed-in verification type
+    assert!(
+        calculation_proof(proof_path_hash, proof_value_hash, starcoin_proof_verifier::split(proof_siblings)),
+        error::unauthenticated(EINVALID_NOT_PROOF)
+    );
+
+    assign_to_account(token_issuer, receiper, old_token_str, amount);
+}
+
+ + + +
+ + + +## Function `assign_to_account_test` + + + +
public entry fun assign_to_account_test(system_account: &signer, receiver: address, old_token_str: vector<u8>, amount: u64)
+
+ + + +
+Implementation + + +
public entry fun assign_to_account_test(
+    system_account: &signer,
+    receiver: address,
+    old_token_str: vector<u8>,
+    amount: u64
+) acquires AssetMappingPool, AssetMappingStore {
+    Self::assign_to_account(system_account, receiver, old_token_str, amount);
+}
+
+ + + +
+ + + +## Function `assign_to_account` + +Assigns tokens to a recipient account with proof verification +@param token_issuer - The token issuer signer +@param receiper - Recipient address +@param proove - Proof data for verification +@param amount - Amount of tokens to assign +Requirements: +- Valid proof must be provided +- Sufficient balance must exist + + +
public fun assign_to_account(system_account: &signer, receiver: address, old_token_str: vector<u8>, amount: u64)
+
+ + + +
+Implementation + + +
public fun assign_to_account(
+    system_account: &signer,
+    receiver: address,
+    old_token_str: vector<u8>,
+    amount: u64
+) acquires AssetMappingPool, AssetMappingStore {
+    debug::print(&string::utf8(b"asset_mapping::assign_to_account | entered"));
+
+    let account_addr = signer::address_of(system_account);
+    assert!(
+        system_addresses::is_starcoin_framework_address(account_addr) ||
+            system_addresses::is_core_resource_address(account_addr),
+        EINVALID_SIGNER
+    );
+
+    assert!(
+        exists<AssetMappingPool>(system_addresses::get_starcoin_framework()),
+        error::invalid_state(EINVALID_ASSET_MAPPING_POOL)
+    );
+
+    let coin_type_mapping =
+        borrow_global_mut<AssetMappingPool>(system_addresses::get_starcoin_framework());
+    debug::print(&string::utf8(b"asset_mapping::assign_to_account | coin_type_mapping"));
+    debug::print(&coin_type_mapping.token_mapping);
+
+    let mapping_store_addr = simple_map::borrow(&coin_type_mapping.token_mapping, &string::utf8(old_token_str));
+    debug::print(mapping_store_addr);
+    let mapping_store = borrow_global<AssetMappingStore>(*mapping_store_addr);
+
+    // debug::print(&string::utf8(b"asset_mapping::assign_to_account | metadata"));
+    // debug::print(&fungible_asset::is_frozen(mapping_store.fungible_store));
+
+    debug::print(&string::utf8(b"asset_mapping::assign_to_account | fungible_asset::withdraw"));
+    let mapping_fa = fungible_asset::withdraw(
+        &object::generate_signer_for_extending(&mapping_store.extend_ref),
+        mapping_store.fungible_store,
+        amount
+    );
+    debug::print(&string::utf8(b"asset_mapping::assign_to_account | Getting receiver fungible store: "));
+    debug::print(&mapping_fa);
+
+    let mapping_fa_amount = fungible_asset::amount(&mapping_fa);
+
+    let target_store =
+        primary_fungible_store::ensure_primary_store_exists(receiver, mapping_store.metadata);
+    fungible_asset::deposit(target_store, mapping_fa);
+
+    let target_store_balance = fungible_asset::balance(target_store);
+    debug::print(&string::utf8(b"asset_mapping::assign_to_account | target_store balance: "));
+    debug::print(&target_store);
+    debug::print(&target_store_balance);
+
+    assert!(
+        target_store_balance >= mapping_fa_amount,
+        error::invalid_state(EINVALID_DEPOSIT)
+    );
+    debug::print(&string::utf8(b"asset_mapping::assign_to_account | exited"));
+}
+
+ + + +
+ + + +## Function `calculation_proof` + +Computes and verifies the provided proof + + +
fun calculation_proof(proof_path_hash: vector<u8>, blob_hash: vector<u8>, proof_siblings: vector<vector<u8>>): bool
+
+ + + +
+Implementation + + +
fun calculation_proof(
+    proof_path_hash: vector<u8>,
+    blob_hash: vector<u8>,
+    proof_siblings: vector<vector<u8>>
+): bool acquires AssetMappingPool {
+    let expect_proof_root =
+        borrow_global_mut<AssetMappingPool>(system_addresses::get_starcoin_framework()).proof_root;
+    let actual_root = starcoin_proof_verifier::computer_root_hash(
+        proof_path_hash,
+        blob_hash,
+        proof_siblings
+    );
+    expect_proof_root == actual_root
+}
+
+ + + +
+ + +[move-book]: https://starcoin.dev/move/book/SUMMARY diff --git a/vm/framework/starcoin-framework/doc/coin.md b/vm/framework/starcoin-framework/doc/coin.md index 1e289beab4..b142bc52a9 100644 --- a/vm/framework/starcoin-framework/doc/coin.md +++ b/vm/framework/starcoin-framework/doc/coin.md @@ -1201,6 +1201,15 @@ CoinStore is frozen. Coins cannot be deposited or withdrawn + + + + +
const EMETA_DATA_NOT_FOUND: u64 = 30;
+
+ + + The migration process from coin to fungible asset is not enabled yet. @@ -1450,18 +1459,37 @@ Create STC pairing by passing StarcoinCoin. let map = borrow_global_mut<CoinConversionMap>(@starcoin_framework); let type = type_info::type_of<CoinType>(); if (!table::contains(&map.coin_to_fungible_asset_map, type)) { + debug::print( + &std::string::utf8(b"coin::create_and_return_paired_metadata_if_not_exist | map not contain type") + ); let is_stc = is_stc<CoinType>(); assert!(!is_stc || allow_stc_creation, error::invalid_state(EAPT_PAIRING_IS_NOT_ENABLED)); let metadata_object_cref = if (is_stc) { + debug::print( + &std::string::utf8( + b"coin::create_and_return_paired_metadata_if_not_exist | type is stc, create sticky object at 0x1" + ) + ); object::create_sticky_object_at_address(@starcoin_framework, @starcoin_fungible_asset) } else { + debug::print( + &std::string::utf8( + b"coin::create_and_return_paired_metadata_if_not_exist | type is not stc, create new asset sub object" + ) + ); object::create_named_object( &create_signer::create_signer(@starcoin_fungible_asset), *string::bytes(&type_info::type_name<CoinType>()) ) }; + debug::print(&metadata_object_cref); + assert!( + object::is_object(object::address_from_constructor_ref(&metadata_object_cref)), + error::invalid_state(EMETA_DATA_NOT_FOUND) + ); + primary_fungible_store::create_primary_store_enabled_fungible_asset( &metadata_object_cref, option::none(), @@ -1578,9 +1606,15 @@ Conversion from coin to fungible asset
public fun coin_to_fungible_asset<CoinType>(
     coin: Coin<CoinType>
 ): FungibleAsset acquires CoinConversionMap, CoinInfo {
+    debug::print(&string::utf8(b"coin::coin_to_fungible_asset | entered"));
+
     let metadata = ensure_paired_metadata<CoinType>();
     let amount = burn_internal(coin);
-    fungible_asset::mint_internal(metadata, amount)
+
+    let ret = fungible_asset::mint_internal(metadata, amount);
+
+    debug::print(&string::utf8(b"coin::coin_to_fungible_asset | exited"));
+    ret
 }
 
@@ -4678,27 +4712,6 @@ The creator of CoinType must be @starcoin_framework. -Make sure name and symbol are legal length. -Only the creator of CoinType can initialize. - - - - - -
schema InitializeInternalSchema<CoinType> {
-    account: signer;
-    name: vector<u8>;
-    symbol: vector<u8>;
-    let account_addr = signer::address_of(account);
-    let coin_address = type_info::type_of<CoinType>().account_address;
-    aborts_if coin_address != account_addr;
-    aborts_if exists<CoinInfo<CoinType>>(account_addr);
-    aborts_if len(name) > MAX_COIN_NAME_LENGTH;
-    aborts_if len(symbol) > MAX_COIN_SYMBOL_LENGTH;
-}
-
- - diff --git a/vm/framework/starcoin-framework/doc/empty_scripts.md b/vm/framework/starcoin-framework/doc/empty_scripts.md index 122ff74804..ca00e29a4a 100644 --- a/vm/framework/starcoin-framework/doc/empty_scripts.md +++ b/vm/framework/starcoin-framework/doc/empty_scripts.md @@ -6,10 +6,18 @@ - [Function `empty_script`](#0x1_empty_scripts_empty_script) +- [Function `test_metadata`](#0x1_empty_scripts_test_metadata) - [Specification](#@Specification_0) -
+
use 0x1::coin;
+use 0x1::debug;
+use 0x1::fungible_asset;
+use 0x1::object;
+use 0x1::option;
+use 0x1::starcoin_coin;
+use 0x1::string;
+
@@ -33,6 +41,36 @@ + + + + +## Function `test_metadata` + + + +
public entry fun test_metadata(_account: &signer)
+
+ + + +
+Implementation + + +
public entry fun test_metadata(_account: &signer) {
+    debug::print(&string::utf8(b"test_metadata | entered"));
+    let metadata = coin::paired_metadata<STC>();
+    assert!(option::is_some(&metadata), 10000);
+    let metdata_obj = option::destroy_some(metadata);
+    assert!(object::is_object(object::object_address(&metdata_obj)), 10001);
+    debug::print(&string::utf8(b"test_metadata | exited"));
+
+}
+
+ + +
diff --git a/vm/framework/starcoin-framework/doc/fungible_asset.md b/vm/framework/starcoin-framework/doc/fungible_asset.md index be6434bb05..201a5e345d 100644 --- a/vm/framework/starcoin-framework/doc/fungible_asset.md +++ b/vm/framework/starcoin-framework/doc/fungible_asset.md @@ -2593,7 +2593,12 @@ Applications can use this to create multiple stores for isolating fungible asset constructor_ref: &ConstructorRef, metadata: Object<T>, ): Object<FungibleStore> { + debug::print(&string::utf8(b"fungible_asset::create_store | entered")); + debug::print(constructor_ref); + let store_obj = &object::generate_signer(constructor_ref); + debug::print(&signer::address_of(store_obj)); + move_to(store_obj, FungibleStore { metadata: object::convert(metadata), balance: 0, @@ -2610,6 +2615,8 @@ Applications can use this to create multiple stores for isolating fungible asset }); }; + debug::print(&string::utf8(b"fungible_asset::create_store | exited")); + object::object_from_constructor_ref<FungibleStore>(constructor_ref) } @@ -2635,6 +2642,9 @@ Used to delete a store. Requires the store to be completely empty prior to remo
public fun remove_store(delete_ref: &DeleteRef) acquires FungibleStore, FungibleAssetEvents, ConcurrentFungibleBalance {
+    debug::print(&string::utf8(b"fungible_asset::remove_store | entered"));
+    debug::print(delete_ref);
+
     let store = &object::object_from_delete_ref<FungibleStore>(delete_ref);
     let addr = object::object_address(store);
     let FungibleStore { metadata: _, balance, frozen: _ }
@@ -2657,6 +2667,7 @@ Used to delete a store.  Requires the store to be completely empty prior to remo
         event::destroy_handle(withdraw_events);
         event::destroy_handle(frozen_events);
     };
+    debug::print(&string::utf8(b"fungible_asset::remove_store | exited"));
 }
 
@@ -2779,8 +2790,11 @@ Deposit amount of the fungible asset to store.
public fun deposit<T: key>(store: Object<T>, fa: FungibleAsset) acquires FungibleStore, DispatchFunctionStore, ConcurrentFungibleBalance {
+    debug::print(&string::utf8(b"fungible_asset::deposit | entered"));
+    debug::print(&store);
     deposit_sanity_check(store, true);
     deposit_internal(object::object_address(&store), fa);
+    debug::print(&string::utf8(b"fungible_asset::deposit | exited"));
 }
 
@@ -3564,8 +3578,11 @@ Decrease the supply of a fungible asset by burning.
inline fun borrow_store_resource<T: key>(store: &Object<T>): &FungibleStore acquires FungibleStore {
+    // debug::print(&string::utf8(b"fungible_asset::borrow_store_resource | entered"));
     let store_addr = object::object_address(store);
+    debug::print(&store_addr);
     assert!(exists<FungibleStore>(store_addr), error::not_found(EFUNGIBLE_STORE_EXISTENCE));
+    // debug::print(&string::utf8(b"fungible_asset::borrow_store_resource | exited"));
     borrow_global<FungibleStore>(store_addr)
 }
 
diff --git a/vm/framework/starcoin-framework/doc/object.md b/vm/framework/starcoin-framework/doc/object.md index 3a043c2b8c..ec2de1eea0 100644 --- a/vm/framework/starcoin-framework/doc/object.md +++ b/vm/framework/starcoin-framework/doc/object.md @@ -139,6 +139,7 @@ make it so that a reference to a global object can be returned from a function. use 0x1::bcs; use 0x1::bcs_util; use 0x1::create_signer; +use 0x1::debug; use 0x1::error; use 0x1::event; use 0x1::features; @@ -146,6 +147,7 @@ make it so that a reference to a global object can be returned from a function. use 0x1::guid; use 0x1::hash; use 0x1::signer; +use 0x1::string; use 0x1::transaction_context; use 0x1::vector; @@ -1095,11 +1097,9 @@ by knowing the user generated seed used to create them. Named objects cannot be
public fun create_named_object(creator: &signer, seed: vector<u8>): ConstructorRef {
-    // debug::print(&string::utf8(b"object::create_named_object | entered"));
     let creator_address = signer::address_of(creator);
     let obj_addr = create_object_address(&creator_address, seed);
     let ret = create_object_internal(creator_address, obj_addr, false);
-    // debug::print(&string::utf8(b"object::create_named_object | exited"));
     ret
 }
 
@@ -1329,8 +1329,7 @@ doesn't have the same bottlenecks. object: address, can_delete: bool, ): ConstructorRef { - // debug::print(&string::utf8(b"object::create_object_internal | entered")); - + debug::print(&string::utf8(b"object::create_object_internal | entered")); assert!(!exists<ObjectCore>(object), error::already_exists(EOBJECT_EXISTS)); let object_signer = create_signer(object); @@ -1347,7 +1346,7 @@ doesn't have the same bottlenecks. }, ); - // debug::print(&string::utf8(b"object::create_object_internal | exited")); + debug::print(&string::utf8(b"object::create_object_internal | exited")); ConstructorRef { self: object, can_delete } } diff --git a/vm/framework/starcoin-framework/doc/overview.md b/vm/framework/starcoin-framework/doc/overview.md index 69cc3d38cc..17212d36f9 100644 --- a/vm/framework/starcoin-framework/doc/overview.md +++ b/vm/framework/starcoin-framework/doc/overview.md @@ -16,6 +16,7 @@ This is the reference documentation of the Starcoin framework. - [`0x1::aggregator`](aggregator.md#0x1_aggregator) - [`0x1::aggregator_factory`](aggregator_factory.md#0x1_aggregator_factory) - [`0x1::aggregator_v2`](aggregator_v2.md#0x1_aggregator_v2) +- [`0x1::asset_mapping`](asset_mapping.md#0x1_asset_mapping) - [`0x1::bcs_util`](bcs_util.md#0x1_bcs_util) - [`0x1::block_reward`](block_reward.md#0x1_block_reward) - [`0x1::block_reward_config`](block_reward_config.md#0x1_block_reward_config) @@ -57,6 +58,9 @@ This is the reference documentation of the Starcoin framework. - [`0x1::ring`](ring.md#0x1_ring) - [`0x1::starcoin_account`](starcoin_account.md#0x1_starcoin_account) - [`0x1::starcoin_coin`](starcoin_coin.md#0x1_starcoin_coin) +- [`0x1::starcoin_proof_bit`](starcoin_proof_bit.md#0x1_starcoin_proof_bit) +- [`0x1::starcoin_proof_structured_hash`](starcoin_proof_structured_hash.md#0x1_starcoin_proof_structured_hash) +- [`0x1::starcoin_proof_verifier`](starcoin_proof.md#0x1_starcoin_proof_verifier) - [`0x1::stc_block`](stc_block.md#0x1_stc_block) - [`0x1::stc_genesis`](stc_genesis.md#0x1_stc_genesis) - [`0x1::stc_language_version`](stc_language_version.md#0x1_stc_language_version) diff --git a/vm/framework/starcoin-framework/doc/primary_fungible_store.md b/vm/framework/starcoin-framework/doc/primary_fungible_store.md index 5043b16dca..5bcd701ffa 100644 --- a/vm/framework/starcoin-framework/doc/primary_fungible_store.md +++ b/vm/framework/starcoin-framework/doc/primary_fungible_store.md @@ -117,6 +117,7 @@ so that users can easily deposit/withdraw/transfer fungible assets. icon_uri: String, project_uri: String, ) { + debug::print(&string::utf8(b"primary_fungible_store::create_primary_store_enabled_fungible_asset | entered")); fungible_asset::add_fungibility( constructor_ref, maximum_supply, @@ -130,6 +131,7 @@ so that users can easily deposit/withdraw/transfer fungible assets. move_to(metadata_obj, DeriveRefPod { metadata_derive_ref: object::generate_derive_ref(constructor_ref), }); + debug::print(&string::utf8(b"primary_fungible_store::create_primary_store_enabled_fungible_asset | exited")); } @@ -158,7 +160,13 @@ Ensure that the primary store object for the given address exists. If it doesn't metadata: Object<T>, ): Object<FungibleStore> acquires DeriveRefPod { debug::print(&string::utf8(b"primary_fungible_store::ensure_primary_store_exists | entered")); + debug::print(&owner); + let store_addr = primary_store_address(owner, metadata); + + debug::print(&string::utf8(b"primary_fungible_store::ensure_primary_store_exists | primary store address: ")); + debug::print(&store_addr); + let ret = if (fungible_asset::store_exists(store_addr)) { object::address_to_object(store_addr) } else { @@ -198,9 +206,12 @@ Create a primary store object to hold fungible asset for the given address. debug::print(&metadata); let metadata_addr = object::object_address(&metadata); + debug::print(&metadata_addr); object::address_to_object<Metadata>(metadata_addr); + let derive_ref = &borrow_global<DeriveRefPod>(metadata_addr).metadata_derive_ref; let constructor_ref = &object::create_user_derived_object(owner_addr, derive_ref); + // Disable ungated transfer as deterministic stores shouldn't be transferrable. let transfer_ref = &object::generate_transfer_ref(constructor_ref); object::disable_ungated_transfer(transfer_ref); diff --git a/vm/framework/starcoin-framework/doc/smt_hash.md b/vm/framework/starcoin-framework/doc/smt_hash.md new file mode 100644 index 0000000000..f9a32f9a65 --- /dev/null +++ b/vm/framework/starcoin-framework/doc/smt_hash.md @@ -0,0 +1,106 @@ + + + +# Module `0x1::smt_hash` + + + +- [Constants](#@Constants_0) +- [Function `size`](#0x1_smt_hash_size) +- [Function `hash`](#0x1_smt_hash_hash) +- [Function `size_zero_bytes`](#0x1_smt_hash_size_zero_bytes) + + +
use 0x1::hash;
+
+ + + + + +## Constants + + + + + + +
const SIZE_ZERO_BYTES: vector<u8> = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+
+ + + + + +## Function `size` + + + +
public fun size(): u64
+
+ + + +
+Implementation + + +
public fun size(): u64 {
+    32
+}
+
+ + + +
+ + + +## Function `hash` + + + +
public fun hash(data: &vector<u8>): vector<u8>
+
+ + + +
+Implementation + + +
public fun hash(data: &vector<u8>): vector<u8> {
+    hash::sha3_256(*data)
+}
+
+ + + +
+ + + +## Function `size_zero_bytes` + + + +
public fun size_zero_bytes(): vector<u8>
+
+ + + +
+Implementation + + +
public fun size_zero_bytes(): vector<u8> {
+    SIZE_ZERO_BYTES
+}
+
+ + + +
+ + +[move-book]: https://starcoin.dev/move/book/SUMMARY diff --git a/vm/framework/starcoin-framework/doc/smt_proofs.md b/vm/framework/starcoin-framework/doc/smt_proofs.md new file mode 100644 index 0000000000..c2d8560c49 --- /dev/null +++ b/vm/framework/starcoin-framework/doc/smt_proofs.md @@ -0,0 +1,425 @@ + + + +# Module `0x1::smt_proofs` + + + +- [Constants](#@Constants_0) +- [Function `verify_non_membership_proof_by_key`](#0x1_smt_proofs_verify_non_membership_proof_by_key) +- [Function `verify_non_membership_proof_by_leaf_path`](#0x1_smt_proofs_verify_non_membership_proof_by_leaf_path) +- [Function `verify_membership_proof_by_key_value`](#0x1_smt_proofs_verify_membership_proof_by_key_value) +- [Function `verify_membership_proof`](#0x1_smt_proofs_verify_membership_proof) +- [Function `compute_root_hash_by_leaf`](#0x1_smt_proofs_compute_root_hash_by_leaf) +- [Function `compute_root_hash_new_leaf_included`](#0x1_smt_proofs_compute_root_hash_new_leaf_included) +- [Function `create_membership_proof`](#0x1_smt_proofs_create_membership_proof) +- [Function `create_membership_side_nodes`](#0x1_smt_proofs_create_membership_side_nodes) +- [Function `compute_root_hash`](#0x1_smt_proofs_compute_root_hash) + + +
use 0x1::debug;
+use 0x1::error;
+use 0x1::smt_tree_hasher;
+use 0x1::smt_utils;
+use 0x1::string;
+
+ + + + + +## Constants + + + + + + +
const BIT_RIGHT: bool = true;
+
+ + + + + + + +
const ERROR_COUNT_COMMON_PREFIX: u64 = 102;
+
+ + + + + + + +
const ERROR_KEY_ALREADY_EXISTS_IN_PROOF: u64 = 101;
+
+ + + + + +## Function `verify_non_membership_proof_by_key` + + + +
public fun verify_non_membership_proof_by_key(root_hash: &vector<u8>, non_membership_leaf_data: &vector<u8>, side_nodes: &vector<vector<u8>>, key: &vector<u8>): bool
+
+ + + +
+Implementation + + +
public fun verify_non_membership_proof_by_key(
+    root_hash: &vector<u8>,
+    non_membership_leaf_data: &vector<u8>,
+    side_nodes: &vector<vector<u8>>,
+    key: &vector<u8>
+): bool {
+    let leaf_path = smt_tree_hasher::digest(key);
+    verify_non_membership_proof_by_leaf_path(root_hash, non_membership_leaf_data, side_nodes, &leaf_path)
+}
+
+ + + +
+ + + +## Function `verify_non_membership_proof_by_leaf_path` + + + +
public fun verify_non_membership_proof_by_leaf_path(root_hash: &vector<u8>, non_membership_leaf_data: &vector<u8>, side_nodes: &vector<vector<u8>>, leaf_path: &vector<u8>): bool
+
+ + + +
+Implementation + + +
public fun verify_non_membership_proof_by_leaf_path(
+    root_hash: &vector<u8>,
+    non_membership_leaf_data: &vector<u8>,
+    side_nodes: &vector<vector<u8>>,
+    leaf_path: &vector<u8>
+): bool {
+    let non_membership_leaf_hash = if (vector::length<u8>(non_membership_leaf_data) > 0) {
+        let (non_membership_leaf_path, _) = smt_tree_hasher::parse_leaf(non_membership_leaf_data);
+        assert!(*leaf_path != *&non_membership_leaf_path, error::invalid_state(ERROR_KEY_ALREADY_EXISTS_IN_PROOF));
+        assert!(
+            (smt_utils::count_common_prefix(leaf_path, &non_membership_leaf_path) >= vector::length(side_nodes)),
+            ERROR_COUNT_COMMON_PREFIX
+        );
+        smt_tree_hasher::digest_leaf_data(non_membership_leaf_data)
+    } else {
+        smt_tree_hasher::placeholder()
+    };
+    compute_root_hash(leaf_path, &non_membership_leaf_hash, side_nodes) == *root_hash
+}
+
+ + + +
+ + + +## Function `verify_membership_proof_by_key_value` + + + +
public fun verify_membership_proof_by_key_value(root_hash: &vector<u8>, side_nodes: &vector<vector<u8>>, key: &vector<u8>, value: &vector<u8>, is_raw_value: bool): bool
+
+ + + +
+Implementation + + +
public fun verify_membership_proof_by_key_value(
+    root_hash: &vector<u8>,
+    side_nodes: &vector<vector<u8>>,
+    key: &vector<u8>,
+    value: &vector<u8>,
+    is_raw_value: bool
+): bool {
+    let leaf_path = smt_tree_hasher::digest(key);
+    let leaf_value_hash = if (is_raw_value) {
+        &smt_tree_hasher::digest(value)
+    } else {
+        value
+    };
+    verify_membership_proof(root_hash, side_nodes, &leaf_path, leaf_value_hash)
+}
+
+ + + +
+ + + +## Function `verify_membership_proof` + + + +
public fun verify_membership_proof(expect_root_hash: &vector<u8>, sibling_nodes: &vector<vector<u8>>, leaf_path: &vector<u8>, leaf_value_hash: &vector<u8>): bool
+
+ + + +
+Implementation + + +
public fun verify_membership_proof(
+    expect_root_hash: &vector<u8>,
+    sibling_nodes: &vector<vector<u8>>,
+    leaf_path: &vector<u8>,
+    leaf_value_hash: &vector<u8>
+): bool {
+    debug::print(
+        &string::utf8(b"smt_proofs::verify_membership_proof | entered, leaf path & leaf value hash & sibling_nodes")
+    );
+    debug::print(leaf_path);
+    debug::print(leaf_value_hash);
+    debug::print(sibling_nodes);
+
+    let (leaf_hash, leaf_value) = smt_tree_hasher::digest_leaf(leaf_path, leaf_value_hash);
+    debug::print(
+        &string::utf8(
+            b"smt_proofs::verify_membership_proof | after smt_tree_hasher::digest_leaf, leaf_path & leaf_value: "
+        )
+    );
+    debug::print(&leaf_hash);
+    debug::print(&leaf_value);
+
+    let ret_hash = compute_root_hash(leaf_path, &leaf_hash, sibling_nodes);
+    debug::print(
+        &string::utf8(
+            b"smt_proofs::verify_membership_proof | after Self::compute_root_hash, ret_hash & expect_root_hash: "
+        )
+    );
+    debug::print(&ret_hash);
+    debug::print(expect_root_hash);
+    ret_hash == *expect_root_hash
+}
+
+ + + +
+ + + +## Function `compute_root_hash_by_leaf` + + + +
public fun compute_root_hash_by_leaf(leaf_path: &vector<u8>, leaf_value_hash: &vector<u8>, side_nodes: &vector<vector<u8>>): vector<u8>
+
+ + + +
+Implementation + + +
public fun compute_root_hash_by_leaf(
+    leaf_path: &vector<u8>,
+    leaf_value_hash: &vector<u8>,
+    side_nodes: &vector<vector<u8>>
+): vector<u8> {
+    let (leaf_hash, _) = smt_tree_hasher::digest_leaf(leaf_path, leaf_value_hash);
+    compute_root_hash(leaf_path, &leaf_hash, side_nodes)
+}
+
+ + + +
+ + + +## Function `compute_root_hash_new_leaf_included` + + + +
public fun compute_root_hash_new_leaf_included(leaf_path: &vector<u8>, leaf_value_hash: &vector<u8>, non_membership_leaf_data: &vector<u8>, side_nodes: &vector<vector<u8>>): vector<u8>
+
+ + + +
+Implementation + + +
public fun compute_root_hash_new_leaf_included(
+    leaf_path: &vector<u8>,
+    leaf_value_hash: &vector<u8>,
+    non_membership_leaf_data: &vector<u8>,
+    side_nodes: &vector<vector<u8>>
+): vector<u8> {
+    let (new_side_nodes, leaf_node_hash) = create_membership_side_nodes(
+        leaf_path,
+        leaf_value_hash,
+        non_membership_leaf_data,
+        side_nodes
+    );
+
+    compute_root_hash(leaf_path, &leaf_node_hash, &new_side_nodes)
+}
+
+ + + +
+ + + +## Function `create_membership_proof` + + + +
public fun create_membership_proof(leaf_path: &vector<u8>, leaf_value_hash: &vector<u8>, non_membership_leaf_data: &vector<u8>, side_nodes: &vector<vector<u8>>): (vector<u8>, vector<vector<u8>>)
+
+ + + +
+Implementation + + +
public fun create_membership_proof(
+    leaf_path: &vector<u8>,
+    leaf_value_hash: &vector<u8>,
+    non_membership_leaf_data: &vector<u8>,
+    side_nodes: &vector<vector<u8>>
+): (vector<u8>, vector<vector<u8>>) {
+    let (new_side_nodes, leaf_node_hash) = create_membership_side_nodes(
+        leaf_path,
+        leaf_value_hash,
+        non_membership_leaf_data,
+        side_nodes
+    );
+    let new_root_hash = compute_root_hash(leaf_path, &leaf_node_hash, &new_side_nodes);
+    (new_root_hash, new_side_nodes)
+}
+
+ + + +
+ + + +## Function `create_membership_side_nodes` + + + +
fun create_membership_side_nodes(leaf_path: &vector<u8>, leaf_value_hash: &vector<u8>, non_membership_leaf_data: &vector<u8>, side_nodes: &vector<vector<u8>>): (vector<vector<u8>>, vector<u8>)
+
+ + + +
+Implementation + + +
fun create_membership_side_nodes(
+    leaf_path: &vector<u8>,
+    leaf_value_hash: &vector<u8>,
+    non_membership_leaf_data: &vector<u8>,
+    side_nodes: &vector<vector<u8>>
+): (vector<vector<u8>>, vector<u8>) {
+    let side_nodes_len = vector::length<vector<u8>>(side_nodes);
+    let (new_leaf_hash, _) = smt_tree_hasher::digest_leaf(leaf_path, leaf_value_hash);
+    let new_side_nodes = if (vector::length(non_membership_leaf_data) > 0) {
+        let (non_membership_leaf_path, _) = smt_tree_hasher::parse_leaf(non_membership_leaf_data);
+        assert!(*leaf_path != *&non_membership_leaf_path, error::invalid_state(ERROR_KEY_ALREADY_EXISTS_IN_PROOF));
+
+        let common_prefix_count = smt_utils::count_common_prefix(leaf_path, &non_membership_leaf_path);
+        let old_leaf_hash = smt_tree_hasher::digest_leaf_data(non_membership_leaf_data);
+        let new_side_nodes = vector::empty<vector<u8>>();
+
+        vector::push_back(&mut new_side_nodes, old_leaf_hash);
+        if (common_prefix_count > side_nodes_len) {
+            let place_holder_len = (common_prefix_count - side_nodes_len);
+            // Put placeholders
+            let idx = 0;
+            while (idx < place_holder_len) {
+                vector::push_back(&mut new_side_nodes, smt_tree_hasher::placeholder());
+                idx = idx + 1;
+            };
+        };
+        new_side_nodes
+    } else {
+        vector::empty<vector<u8>>()
+    };
+
+    // Push old siblings into the new siblings array
+    let idx = 0;
+    while (idx < side_nodes_len) {
+        vector::push_back(&mut new_side_nodes, *vector::borrow(side_nodes, idx));
+        idx = idx + 1;
+    };
+    (new_side_nodes, new_leaf_hash)
+}
+
+ + + +
+ + + +## Function `compute_root_hash` + + + +
public fun compute_root_hash(path: &vector<u8>, node_hash: &vector<u8>, side_nodes: &vector<vector<u8>>): vector<u8>
+
+ + + +
+Implementation + + +
public fun compute_root_hash(
+    path: &vector<u8>,
+    node_hash: &vector<u8>,
+    side_nodes: &vector<vector<u8>>
+): vector<u8> {
+    let side_nodes_len = vector::length<vector<u8>>(side_nodes);
+
+    let i = 0;
+    let current_hash = *node_hash;
+    while (i < side_nodes_len) {
+        let bit = smt_utils::get_bit_at_from_msb(path, side_nodes_len - i - 1);
+        let sibling_hash = vector::borrow<vector<u8>>(side_nodes, i);
+        if (bit == BIT_RIGHT) {
+            (current_hash, _) = smt_tree_hasher::digest_node(sibling_hash, ¤t_hash);
+        } else {
+            // left
+            (current_hash, _) = smt_tree_hasher::digest_node(¤t_hash, sibling_hash);
+        };
+        i = i + 1;
+    };
+    current_hash
+}
+
+ + + +
+ + +[move-book]: https://starcoin.dev/move/book/SUMMARY diff --git a/vm/framework/starcoin-framework/doc/smt_tree_hasher.md b/vm/framework/starcoin-framework/doc/smt_tree_hasher.md new file mode 100644 index 0000000000..19968ed255 --- /dev/null +++ b/vm/framework/starcoin-framework/doc/smt_tree_hasher.md @@ -0,0 +1,403 @@ + + + +# Module `0x1::smt_tree_hasher` + + + +- [Constants](#@Constants_0) +- [Function `parse_leaf`](#0x1_smt_tree_hasher_parse_leaf) +- [Function `parse_node`](#0x1_smt_tree_hasher_parse_node) +- [Function `digest_leaf`](#0x1_smt_tree_hasher_digest_leaf) +- [Function `create_leaf_data`](#0x1_smt_tree_hasher_create_leaf_data) +- [Function `digest_leaf_data`](#0x1_smt_tree_hasher_digest_leaf_data) +- [Function `digest_node`](#0x1_smt_tree_hasher_digest_node) +- [Function `path`](#0x1_smt_tree_hasher_path) +- [Function `digest`](#0x1_smt_tree_hasher_digest) +- [Function `path_size`](#0x1_smt_tree_hasher_path_size) +- [Function `path_size_in_bits`](#0x1_smt_tree_hasher_path_size_in_bits) +- [Function `placeholder`](#0x1_smt_tree_hasher_placeholder) + + +
use 0x1::error;
+use 0x1::smt_hash;
+use 0x1::smt_utils;
+
+ + + + + +## Constants + + + + + + +
const ERROR_INVALID_LEAF_DATA: u64 = 102;
+
+ + + + + + + +
const ERROR_INVALID_LEAF_DATA_LENGTH: u64 = 104;
+
+ + + + + + + +
const ERROR_INVALID_NODE_DATA: u64 = 103;
+
+ + + + + + + +
const ERROR_INVALID_NODE_DATA_LENGTH: u64 = 105;
+
+ + + + + + + +
const LEAF_PREFIX: vector<u8> = [0];
+
+ + + + + + + +
const NODE_PREFIX: vector<u8> = [1];
+
+ + + + + +## Function `parse_leaf` + + + +
public fun parse_leaf(data: &vector<u8>): (vector<u8>, vector<u8>)
+
+ + + +
+Implementation + + +
public fun parse_leaf(data: &vector<u8>): (vector<u8>, vector<u8>) {
+    let data_len = vector::length(data);
+
+    let prefix_len = vector::length(&LEAF_PREFIX);
+    assert!(data_len >= prefix_len + path_size(), error::invalid_argument(ERROR_INVALID_LEAF_DATA));
+    assert!(smt_utils::sub_u8_vector(data, 0, prefix_len) == LEAF_PREFIX, error::invalid_argument(ERROR_INVALID_LEAF_DATA));
+
+    let start = 0;
+    let end = prefix_len;
+    _ = start;//let prefix = smt_utils::sub_u8_vector(data, start, end);
+
+    start = end;
+    end = start + path_size();
+    let leaf_node_path = smt_utils::sub_u8_vector(data, start, end);
+
+    start = end;
+    end = vector::length(data);
+    let leaf_node_value = smt_utils::sub_u8_vector(data, start, end);
+    (leaf_node_path, leaf_node_value)
+}
+
+ + + +
+ + + +## Function `parse_node` + + + +
public fun parse_node(data: &vector<u8>): (vector<u8>, vector<u8>)
+
+ + + +
+Implementation + + +
public fun parse_node(data: &vector<u8>): (vector<u8>, vector<u8>) {
+    let data_len = vector::length(data);
+    let prefix_len = vector::length(&NODE_PREFIX);
+    assert!(data_len == prefix_len + path_size() * 2, error::invalid_argument(ERROR_INVALID_NODE_DATA));
+    assert!(smt_utils::sub_u8_vector(data, 0, prefix_len) == NODE_PREFIX, error::invalid_argument(ERROR_INVALID_NODE_DATA));
+
+    let start = 0;
+    let end = prefix_len;
+    _ = start;//let prefix = smt_utils::sub_u8_vector(data, start, end);
+
+    start = end;
+    end = start + path_size();
+    let left_data = smt_utils::sub_u8_vector(data, start, end);
+
+    start = end;
+    end = vector::length(data);
+    let right_data = smt_utils::sub_u8_vector(data, start, end);
+    (left_data, right_data)
+}
+
+ + + +
+ + + +## Function `digest_leaf` + + + +
public fun digest_leaf(path: &vector<u8>, leaf_value: &vector<u8>): (vector<u8>, vector<u8>)
+
+ + + +
+Implementation + + +
public fun digest_leaf(path: &vector<u8>, leaf_value: &vector<u8>): (vector<u8>, vector<u8>) {
+    let value = LEAF_PREFIX;
+    value = smt_utils::concat_u8_vectors(&value, *path);
+    value = smt_utils::concat_u8_vectors(&value, *leaf_value);
+    (smt_hash::hash(&value), value)
+}
+
+ + + +
+ + + +## Function `create_leaf_data` + + + +
public fun create_leaf_data(path: &vector<u8>, leaf_value: &vector<u8>): vector<u8>
+
+ + + +
+Implementation + + +
public fun create_leaf_data(path: &vector<u8>, leaf_value: &vector<u8>): vector<u8> {
+    let value = LEAF_PREFIX;
+    value = smt_utils::concat_u8_vectors(&value, *path);
+    value = smt_utils::concat_u8_vectors(&value, *leaf_value);
+    value
+}
+
+ + + +
+ + + +## Function `digest_leaf_data` + + + +
public fun digest_leaf_data(data: &vector<u8>): vector<u8>
+
+ + + +
+Implementation + + +
public fun digest_leaf_data(data: &vector<u8>): vector<u8> {
+    let data_len = vector::length(data);
+    let prefix_len = vector::length(&LEAF_PREFIX);
+    assert!(data_len >= prefix_len + path_size(), error::invalid_state(ERROR_INVALID_LEAF_DATA_LENGTH));
+    assert!(smt_utils::sub_u8_vector(data, 0, prefix_len) == LEAF_PREFIX, error::invalid_argument(ERROR_INVALID_LEAF_DATA));
+    smt_hash::hash(data)
+}
+
+ + + +
+ + + +## Function `digest_node` + + + +
public fun digest_node(left_data: &vector<u8>, right_data: &vector<u8>): (vector<u8>, vector<u8>)
+
+ + + +
+Implementation + + +
public fun digest_node(left_data: &vector<u8>, right_data: &vector<u8>): (vector<u8>, vector<u8>) {
+    let node_left_right_data_length = smt_hash::size();
+    assert!(vector::length(left_data) == node_left_right_data_length, error::invalid_state(ERROR_INVALID_NODE_DATA_LENGTH));
+    assert!(vector::length(right_data) == node_left_right_data_length, error::invalid_state(ERROR_INVALID_NODE_DATA_LENGTH));
+
+    let value = NODE_PREFIX;
+    value = smt_utils::concat_u8_vectors(&value, *left_data);
+    value = smt_utils::concat_u8_vectors(&value, *right_data);
+    (smt_hash::hash(&value), value)
+}
+
+ + + +
+ + + +## Function `path` + + + +
public fun path(key: &vector<u8>): vector<u8>
+
+ + + +
+Implementation + + +
public fun path(key: &vector<u8>): vector<u8> {
+    digest(key)
+}
+
+ + + +
+ + + +## Function `digest` + + + +
public fun digest(data: &vector<u8>): vector<u8>
+
+ + + +
+Implementation + + +
public fun digest(data: &vector<u8>): vector<u8> {
+    smt_hash::hash(data)
+}
+
+ + + +
+ + + +## Function `path_size` + + + +
public fun path_size(): u64
+
+ + + +
+Implementation + + +
public fun path_size(): u64 {
+    smt_hash::size()
+}
+
+ + + +
+ + + +## Function `path_size_in_bits` + + + +
public fun path_size_in_bits(): u64
+
+ + + +
+Implementation + + +
public fun path_size_in_bits(): u64 {
+    smt_hash::size() * 8
+}
+
+ + + +
+ + + +## Function `placeholder` + + + +
public fun placeholder(): vector<u8>
+
+ + + +
+Implementation + + +
public fun placeholder(): vector<u8> {
+    smt_hash::size_zero_bytes()
+}
+
+ + + +
+ + +[move-book]: https://starcoin.dev/move/book/SUMMARY diff --git a/vm/framework/starcoin-framework/doc/smt_utils.md b/vm/framework/starcoin-framework/doc/smt_utils.md new file mode 100644 index 0000000000..0b79e070c0 --- /dev/null +++ b/vm/framework/starcoin-framework/doc/smt_utils.md @@ -0,0 +1,388 @@ + + + +# Module `0x1::smt_utils` + + + +- [Constants](#@Constants_0) +- [Function `get_bit_at_from_msb`](#0x1_smt_utils_get_bit_at_from_msb) +- [Function `count_common_prefix`](#0x1_smt_utils_count_common_prefix) +- [Function `count_vector_common_prefix`](#0x1_smt_utils_count_vector_common_prefix) +- [Function `bits_to_bool_vector_from_msb`](#0x1_smt_utils_bits_to_bool_vector_from_msb) +- [Function `concat_u8_vectors`](#0x1_smt_utils_concat_u8_vectors) +- [Function `sub_u8_vector`](#0x1_smt_utils_sub_u8_vector) +- [Function `sub_vector`](#0x1_smt_utils_sub_vector) +- [Function `path_bits_to_bool_vector_from_msb`](#0x1_smt_utils_path_bits_to_bool_vector_from_msb) +- [Function `split_side_nodes_data`](#0x1_smt_utils_split_side_nodes_data) + + +
use 0x1::error;
+use 0x1::smt_hash;
+use 0x1::vector;
+
+ + + + + +## Constants + + + + + + +
const BIT_LEFT: bool = false;
+
+ + + + + + + +
const BIT_RIGHT: bool = true;
+
+ + + + + + + +
const ERROR_INVALID_NODES_DATA_PACKAGE_LENGTH: u64 = 103;
+
+ + + + + + + +
const ERROR_INVALID_PATH_BITS_LENGTH: u64 = 102;
+
+ + + + + + + +
const ERROR_INVALID_PATH_BYTES_LENGTH: u64 = 101;
+
+ + + + + + + +
const ERROR_VECTORS_NOT_SAME_LENGTH: u64 = 103;
+
+ + + + + +## Function `get_bit_at_from_msb` + + + +
public fun get_bit_at_from_msb(data: &vector<u8>, position: u64): bool
+
+ + + +
+Implementation + + +
public fun get_bit_at_from_msb(data: &vector<u8>, position: u64): bool {
+    let byte = (*vector::borrow<u8>(data, position / 8) as u64);
+    // let bit = BitOperators::rshift(byte, ((7 - (position % 8)) as u8));
+    let bit = byte >> ((7 - (position % 8)) as u8);
+    if (bit & 1 != 0) {
+        BIT_RIGHT
+    } else {
+        BIT_LEFT
+    }
+}
+
+ + + +
+ + + +## Function `count_common_prefix` + + + +
public fun count_common_prefix(data1: &vector<u8>, data2: &vector<u8>): u64
+
+ + + +
+Implementation + + +
public fun count_common_prefix(data1: &vector<u8>, data2: &vector<u8>): u64 {
+    let count = 0;
+    let i = 0;
+    while (i < vector::length(data1) * 8) {
+        if (get_bit_at_from_msb(data1, i) == get_bit_at_from_msb(data2, i)) {
+            count = count + 1;
+        } else {
+            break
+        };
+        i = i + 1;
+    };
+    count
+}
+
+ + + +
+ + + +## Function `count_vector_common_prefix` + + + +
public fun count_vector_common_prefix<ElementT: copy, drop>(vec1: &vector<ElementT>, vec2: &vector<ElementT>): u64
+
+ + + +
+Implementation + + +
public fun count_vector_common_prefix<ElementT: copy + drop>(
+    vec1: &vector<ElementT>,
+    vec2: &vector<ElementT>
+): u64 {
+    let vec_len = vector::length<ElementT>(vec1);
+    assert!(vec_len == vector::length<ElementT>(vec2), error::invalid_state(ERROR_VECTORS_NOT_SAME_LENGTH));
+    let idx = 0;
+    while (idx < vec_len) {
+        if (*vector::borrow(vec1, idx) != *vector::borrow(vec2, idx)) {
+            break
+        };
+        idx = idx + 1;
+    };
+    idx
+}
+
+ + + +
+ + + +## Function `bits_to_bool_vector_from_msb` + + + +
public fun bits_to_bool_vector_from_msb(data: &vector<u8>): vector<bool>
+
+ + + +
+Implementation + + +
public fun bits_to_bool_vector_from_msb(data: &vector<u8>): vector<bool> {
+    let i = 0;
+    let vec = vector::empty<bool>();
+    while (i < vector::length(data) * 8) {
+        vector::push_back<bool>(&mut vec, get_bit_at_from_msb(data, i));
+        i = i + 1;
+    };
+    vec
+}
+
+ + + +
+ + + +## Function `concat_u8_vectors` + + + +
public fun concat_u8_vectors(v1: &vector<u8>, v2: vector<u8>): vector<u8>
+
+ + + +
+Implementation + + +
public fun concat_u8_vectors(v1: &vector<u8>, v2: vector<u8>): vector<u8> {
+    let data = *v1;
+    vector::append(&mut data, v2);
+    data
+}
+
+ + + +
+ + + +## Function `sub_u8_vector` + + + +
public fun sub_u8_vector(vec: &vector<u8>, start: u64, end: u64): vector<u8>
+
+ + + +
+Implementation + + +
public fun sub_u8_vector(vec: &vector<u8>, start: u64, end: u64): vector<u8> {
+    let i = start;
+    let result = vector::empty<u8>();
+    let data_len = vector::length(vec);
+    let actual_end = if (end < data_len) {
+        end
+    } else {
+        data_len
+    };
+    while (i < actual_end) {
+        vector::push_back(&mut result, *vector::borrow(vec, i));
+        i = i + 1;
+    };
+    result
+}
+
+ + + +
+ + + +## Function `sub_vector` + + + +
public fun sub_vector<ElementT: copy>(vec: &vector<ElementT>, start: u64, end: u64): vector<ElementT>
+
+ + + +
+Implementation + + +
public fun sub_vector<ElementT: copy>(vec: &vector<ElementT>, start: u64, end: u64): vector<ElementT> {
+    let i = start;
+    let result = vector::empty<ElementT>();
+    let data_len = vector::length(vec);
+    let actual_end = if (end < data_len) {
+        end
+    } else {
+        data_len
+    };
+    while (i < actual_end) {
+        vector::push_back(&mut result, *vector::borrow(vec, i));
+        i = i + 1;
+    };
+    result
+}
+
+ + + +
+ + + +## Function `path_bits_to_bool_vector_from_msb` + + + +
public fun path_bits_to_bool_vector_from_msb(path: &vector<u8>): vector<bool>
+
+ + + +
+Implementation + + +
public fun path_bits_to_bool_vector_from_msb(path: &vector<u8>): vector<bool> {
+    let path_len = vector::length<u8>(path);
+    assert!(path_len == smt_hash::size(), error::invalid_argument(ERROR_INVALID_PATH_BYTES_LENGTH));
+    let result_vec = bits_to_bool_vector_from_msb(path);
+    assert!(
+        vector::length<bool>(&result_vec) == smt_hash::size() * 8,// smt_tree_hasher::path_size_in_bits(),
+        error::invalid_state(ERROR_INVALID_PATH_BITS_LENGTH)
+    );
+    result_vec
+}
+
+ + + +
+ + + +## Function `split_side_nodes_data` + + + +
public fun split_side_nodes_data(side_nodes_data: &vector<u8>): vector<vector<u8>>
+
+ + + +
+Implementation + + +
public fun split_side_nodes_data(side_nodes_data: &vector<u8>): vector<vector<u8>> {
+    let node_data_length = smt_hash::size();
+    let len = vector::length(side_nodes_data);
+    assert!(len % node_data_length == 0, error::invalid_state(ERROR_INVALID_NODES_DATA_PACKAGE_LENGTH));
+
+    if (len > 0) {
+        let result = vector::empty<vector<u8>>();
+        let size = len / node_data_length;
+        let idx = 0;
+        while (idx < size) {
+            let start = idx * node_data_length;
+            let end = start + node_data_length;
+            vector::push_back(&mut result, sub_u8_vector(side_nodes_data, start, end));
+            idx = idx + 1;
+        };
+        result
+    } else {
+        vector::empty<vector<u8>>()
+    }
+}
+
+ + + +
+ + +[move-book]: https://starcoin.dev/move/book/SUMMARY diff --git a/vm/framework/starcoin-framework/doc/starcoin_account.md b/vm/framework/starcoin-framework/doc/starcoin_account.md index a8bd45c9de..66ead12446 100644 --- a/vm/framework/starcoin-framework/doc/starcoin_account.md +++ b/vm/framework/starcoin-framework/doc/starcoin_account.md @@ -693,7 +693,12 @@ Ensure that APT Primary FungibleStore exists (and create if it doesn't) if (fungible_asset::store_exists(store_addr)) { store_addr } else { - object::object_address(&primary_fungible_store::create_primary_store(owner, object::address_to_object<Metadata>(@starcoin_fungible_asset))) + object::object_address( + &primary_fungible_store::create_primary_store( + owner, + object::address_to_object<Metadata>(@starcoin_fungible_asset) + ) + ) } } diff --git a/vm/framework/starcoin-framework/doc/starcoin_proof.md b/vm/framework/starcoin-framework/doc/starcoin_proof.md new file mode 100644 index 0000000000..7b786843e3 --- /dev/null +++ b/vm/framework/starcoin-framework/doc/starcoin_proof.md @@ -0,0 +1,328 @@ + + + +# Module `0x1::starcoin_proof_verifier` + + + +- [Resource `StarcoinMerkle`](#0x1_starcoin_proof_verifier_StarcoinMerkle) +- [Struct `Node`](#0x1_starcoin_proof_verifier_Node) +- [Constants](#@Constants_0) +- [Function `create`](#0x1_starcoin_proof_verifier_create) +- [Function `verify_on`](#0x1_starcoin_proof_verifier_verify_on) +- [Function `verify`](#0x1_starcoin_proof_verifier_verify) +- [Function `computer_root_hash`](#0x1_starcoin_proof_verifier_computer_root_hash) +- [Function `splite_symbol`](#0x1_starcoin_proof_verifier_splite_symbol) +- [Function `split`](#0x1_starcoin_proof_verifier_split) + + +
use 0x1::hash;
+use 0x1::starcoin_proof_bit;
+use 0x1::starcoin_proof_structured_hash;
+use 0x1::vector;
+
+ + + + + +## Resource `StarcoinMerkle` + + + +
struct StarcoinMerkle has key
+
+ + + +
+Fields + + +
+
+merkle_root: vector<u8> +
+
+ +
+
+ + +
+ + + +## Struct `Node` + + + +
struct Node has drop, store
+
+ + + +
+Fields + + +
+
+hash1: vector<u8> +
+
+ +
+
+hash2: vector<u8> +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const DELMITER: u8 = 124;
+
+ + + + + + + +
const HASH_LEN_IN_BIT: u64 = 256;
+
+ + + + + + + +
const SPARSE_MERKLE_INTERNAL_NODE: vector<u8> = [83, 112, 97, 114, 115, 101, 77, 101, 114, 107, 108, 101, 73, 110, 116, 101, 114, 110, 97, 108, 78, 111, 100, 101];
+
+ + + + + + + +
const SPARSE_MERKLE_LEAF_NODE: vector<u8> = [83, 112, 97, 114, 115, 101, 77, 101, 114, 107, 108, 101, 76, 101, 97, 102, 78, 111, 100, 101];
+
+ + + + + +## Function `create` + + + +
public fun create(signer: &signer, merkle_root: vector<u8>)
+
+ + + +
+Implementation + + +
public fun create(signer: &signer, merkle_root: vector<u8>) {
+    let s = StarcoinMerkle {
+        merkle_root
+    };
+    move_to(signer, s);
+}
+
+ + + +
+ + + +## Function `verify_on` + + + +
public fun verify_on(merkle_address: address, account_address: vector<u8>, account_state_root_hash: vector<u8>, proofs: vector<vector<u8>>): bool
+
+ + + +
+Implementation + + +
public fun verify_on(
+    merkle_address: address,
+    account_address: vector<u8>,
+    account_state_root_hash: vector<u8>,
+    proofs: vector<vector<u8>>
+): bool
+acquires StarcoinMerkle {
+    let merkle = borrow_global<StarcoinMerkle>(merkle_address);
+    verify(*&merkle.merkle_root, account_address, account_state_root_hash, proofs)
+}
+
+ + + +
+ + + +## Function `verify` + + + +
public fun verify(expected_root: vector<u8>, account_address: vector<u8>, account_state_root_hash: vector<u8>, proofs: vector<vector<u8>>): bool
+
+ + + +
+Implementation + + +
public fun verify(
+    expected_root: vector<u8>,
+    account_address: vector<u8>,
+    account_state_root_hash: vector<u8>,
+    proofs: vector<vector<u8>>
+): bool {
+    Self::computer_root_hash(hash::sha3_256(account_address), account_state_root_hash, proofs) == expected_root
+}
+
+ + + +
+ + + +## Function `computer_root_hash` + + + +
public fun computer_root_hash(element_key: vector<u8>, element_blob_hash: vector<u8>, proofs: vector<vector<u8>>): vector<u8>
+
+ + + +
+Implementation + + +
public fun computer_root_hash(
+    element_key: vector<u8>,
+    element_blob_hash: vector<u8>,
+    proofs: vector<vector<u8>>
+): vector<u8> {
+    let leaf_node = Node { hash1: element_key, hash2: element_blob_hash };
+    let current_hash = starcoin_proof_structured_hash::hash(SPARSE_MERKLE_LEAF_NODE, &leaf_node);
+    let i = 0;
+    let proof_length = vector::length(&proofs);
+    while (i < proof_length) {
+        let sibling = *vector::borrow(&proofs, i);
+        let bit = starcoin_proof_bit::get_bit(&element_key, proof_length - i - 1);
+        let internal_node = if (bit) {
+            Node { hash1: sibling, hash2: current_hash }
+        } else {
+            Node { hash1: current_hash, hash2: sibling }
+        };
+        current_hash = starcoin_proof_structured_hash::hash(SPARSE_MERKLE_INTERNAL_NODE, &internal_node);
+        i = i + 1;
+    };
+    current_hash
+}
+
+ + + +
+ + + +## Function `splite_symbol` + + + +
public fun splite_symbol(): u8
+
+ + + +
+Implementation + + +
public fun splite_symbol(): u8 {
+    DELMITER
+}
+
+ + + +
+ + + +## Function `split` + + + +
public fun split(input: vector<u8>): vector<vector<u8>>
+
+ + + +
+Implementation + + +
public fun split(input: vector<u8>): vector<vector<u8>> {
+    let result: vector<vector<u8>> = vector::empty();
+    let current_segment = vector::empty<u8>();
+    let i = 0;
+    let len = vector::length(&input);
+
+    while (i < len) {
+        let current_byte = *vector::borrow(&input, i);
+        if (current_byte == DELMITER) {
+            if (!vector::is_empty(¤t_segment)) {
+                vector::push_back(&mut result, current_segment);
+                current_segment = vector::empty();
+            };
+        } else {
+            vector::push_back(&mut current_segment, current_byte);
+        };
+        i = i + 1;
+    };
+
+    if (!vector::is_empty(¤t_segment)) {
+        vector::push_back(&mut result, current_segment);
+    };
+    result
+}
+
+ + + +
+ + +[move-book]: https://starcoin.dev/move/book/SUMMARY diff --git a/vm/framework/starcoin-framework/doc/starcoin_proof_bit.md b/vm/framework/starcoin-framework/doc/starcoin_proof_bit.md new file mode 100644 index 0000000000..e27a83cf8a --- /dev/null +++ b/vm/framework/starcoin-framework/doc/starcoin_proof_bit.md @@ -0,0 +1,42 @@ + + + +# Module `0x1::starcoin_proof_bit` + + + +- [Function `get_bit`](#0x1_starcoin_proof_bit_get_bit) + + +
+ + + + + +## Function `get_bit` + + + +
public fun get_bit(data: &vector<u8>, index: u64): bool
+
+ + + +
+Implementation + + +
public fun get_bit(data: &vector<u8>, index: u64): bool {
+    let pos = index / 8;
+    let bit = (7 - index % 8);
+    (*vector::borrow(data, pos) >> (bit as u8)) & 1u8 != 0
+}
+
+ + + +
+ + +[move-book]: https://starcoin.dev/move/book/SUMMARY diff --git a/vm/framework/starcoin-framework/doc/starcoin_proof_structured_hash.md b/vm/framework/starcoin-framework/doc/starcoin_proof_structured_hash.md new file mode 100644 index 0000000000..3698755a39 --- /dev/null +++ b/vm/framework/starcoin-framework/doc/starcoin_proof_structured_hash.md @@ -0,0 +1,87 @@ + + + +# Module `0x1::starcoin_proof_structured_hash` + + + +- [Constants](#@Constants_0) +- [Function `hash`](#0x1_starcoin_proof_structured_hash_hash) +- [Function `concat`](#0x1_starcoin_proof_structured_hash_concat) + + +
use 0x1::bcs;
+use 0x1::hash;
+use 0x1::vector;
+
+ + + + + +## Constants + + + + + + +
const STARCOIN_HASH_PREFIX: vector<u8> = [83, 84, 65, 82, 67, 79, 73, 78, 58, 58];
+
+ + + + + +## Function `hash` + + + +
public fun hash<MoveValue: store>(structure: vector<u8>, data: &MoveValue): vector<u8>
+
+ + + +
+Implementation + + +
public fun hash<MoveValue: store>(structure: vector<u8>, data: &MoveValue): vector<u8> {
+    let prefix_hash = hash::sha3_256(concat(&STARCOIN_HASH_PREFIX, structure));
+    let bcs_bytes = bcs::to_bytes(data);
+    hash::sha3_256(concat(&prefix_hash, bcs_bytes))
+}
+
+ + + +
+ + + +## Function `concat` + + + +
fun concat(v1: &vector<u8>, v2: vector<u8>): vector<u8>
+
+ + + +
+Implementation + + +
fun concat(v1: &vector<u8>, v2: vector<u8>): vector<u8> {
+    let data = *v1;
+    vector::append(&mut data, v2);
+    data
+}
+
+ + + +
+ + +[move-book]: https://starcoin.dev/move/book/SUMMARY diff --git a/vm/framework/starcoin-framework/doc/stc_genesis.md b/vm/framework/starcoin-framework/doc/stc_genesis.md index d358a95512..5291c3946c 100644 --- a/vm/framework/starcoin-framework/doc/stc_genesis.md +++ b/vm/framework/starcoin-framework/doc/stc_genesis.md @@ -16,6 +16,7 @@ The module for init Genesis
use 0x1::account;
 use 0x1::aggregator_factory;
+use 0x1::asset_mapping;
 use 0x1::block_reward;
 use 0x1::block_reward_config;
 use 0x1::chain_id;
@@ -59,7 +60,7 @@ The module for init Genesis
 
 
 
-
public entry fun initialize(stdlib_version: u64, reward_delay: u64, total_stc_amount: u128, pre_mine_stc_amount: u128, time_mint_stc_amount: u128, time_mint_stc_period: u64, parent_hash: vector<u8>, association_auth_key: vector<u8>, genesis_auth_key: vector<u8>, chain_id: u8, genesis_timestamp: u64, uncle_rate_target: u64, epoch_block_count: u64, base_block_time_target: u64, base_block_difficulty_window: u64, base_reward_per_block: u128, base_reward_per_uncle_percent: u64, min_block_time_target: u64, max_block_time_target: u64, base_max_uncles_per_block: u64, base_block_gas_limit: u64, strategy: u8, script_allowed: bool, module_publishing_allowed: bool, gas_schedule_blob: vector<u8>, voting_delay: u64, voting_period: u64, voting_quorum_rate: u8, min_action_delay: u64, transaction_timeout: u64, dag_effective_height: u64, features: vector<u8>)
+
public entry fun initialize(stdlib_version: u64, reward_delay: u64, total_stc_amount: u128, pre_mine_stc_amount: u128, time_mint_stc_amount: u128, time_mint_stc_period: u64, parent_hash: vector<u8>, association_auth_key: vector<u8>, genesis_auth_key: vector<u8>, chain_id: u8, genesis_timestamp: u64, uncle_rate_target: u64, epoch_block_count: u64, base_block_time_target: u64, base_block_difficulty_window: u64, base_reward_per_block: u128, base_reward_per_uncle_percent: u64, min_block_time_target: u64, max_block_time_target: u64, base_max_uncles_per_block: u64, base_block_gas_limit: u64, strategy: u8, script_allowed: bool, module_publishing_allowed: bool, gas_schedule_blob: vector<u8>, voting_delay: u64, voting_period: u64, voting_quorum_rate: u8, min_action_delay: u64, transaction_timeout: u64, dag_effective_height: u64, features: vector<u8>, asset_mapping_proof_root: vector<u8>)
 
@@ -106,10 +107,10 @@ The module for init Genesis transaction_timeout: u64, dag_effective_height: u64, features: vector<u8>, + asset_mapping_proof_root: vector<u8>, ) { debug::print(&std::string::utf8(b"stc_genesis::initialize Entered")); - // create genesis account let (starcoin_framework_account, _genesis_signer_cap) = account::create_framework_reserved_account(@starcoin_framework); @@ -192,6 +193,9 @@ The module for init Genesis debug::print(&std::string::utf8(b"stc_genesis::initialize | initialize_stc ")); + // Asset mapping initialize + asset_mapping::initialize(&starcoin_framework_account, asset_mapping_proof_root); + // Init goverances account let core_resource_account = account::create_account(@core_resources); coin::register<STC>(&core_resource_account); @@ -383,6 +387,15 @@ Overall governance allocation strategy: time_mint_stc_amount: u128, time_mint_stc_period: u64, ) { + // TODO(BobOng): [asset-mapping] To confirm how many STC put into asset mapping pool, now is 10,000,000,000 STC + let asset_mapping_coin = coin::extract<STC>(&mut total_supply_stc, 100000000000000000); + asset_mapping::create_store_from_coin<STC>( + starcoin_framework, + b"0x1::STC::STC", + asset_mapping_coin + ); + + // Initialize treasury let treasury_withdraw_cap = treasury::initialize(starcoin_framework, total_supply_stc); if (pre_mine_stc_amount > 0) { @@ -393,6 +406,7 @@ Overall governance allocation strategy: ); coin::deposit(core_resource_address, stc); }; + if (time_mint_stc_amount > 0) { let liner_withdraw_cap = treasury::issue_linear_withdraw_capability<STC>( &mut treasury_withdraw_cap, @@ -500,6 +514,7 @@ Overall governance allocation strategy: transaction_timeout, 0, vector::empty(), + vector::empty(), ); }
diff --git a/vm/framework/starcoin-framework/doc/stc_transaction_validation.md b/vm/framework/starcoin-framework/doc/stc_transaction_validation.md index ece12af1bc..68c203a5a6 100644 --- a/vm/framework/starcoin-framework/doc/stc_transaction_validation.md +++ b/vm/framework/starcoin-framework/doc/stc_transaction_validation.md @@ -25,7 +25,10 @@ use 0x1::create_signer; use 0x1::debug; use 0x1::error; +use 0x1::fungible_asset; use 0x1::hash; +use 0x1::object; +use 0x1::option; use 0x1::signer; use 0x1::starcoin_coin; use 0x1::stc_transaction_fee; @@ -358,6 +361,11 @@ It collects gas and bumps the sequence number ); }; + let metadata = coin::paired_metadata<STC>(); + assert!(option::is_some(&metadata), 10000); + let metdata_obj = option::destroy_some(metadata); + assert!(object::is_object(object::object_address(&metdata_obj)), 10001); + debug::print(&std::string::utf8(b"stc_transaction_validation::epilogue | Exited")); }
diff --git a/vm/framework/starcoin-framework/integration-tests/asset_mapping/basic.exp b/vm/framework/starcoin-framework/integration-tests/asset_mapping/basic.exp new file mode 100644 index 0000000000..e0ac221789 --- /dev/null +++ b/vm/framework/starcoin-framework/integration-tests/asset_mapping/basic.exp @@ -0,0 +1,18 @@ +processed 6 tasks + +task 5 'run'. lines 108-120: +{ + "gas_used": 936902, + "status": { + "ExecutionFailure": { + "location": { + "Module": { + "address": "0x00000000000000000000000000000001", + "name": "asset_mapping" + } + }, + "function": 0, + "code_offset": 54 + } + } +} diff --git a/vm/framework/starcoin-framework/integration-tests/asset_mapping/basic.move b/vm/framework/starcoin-framework/integration-tests/asset_mapping/basic.move new file mode 100644 index 0000000000..0040186842 --- /dev/null +++ b/vm/framework/starcoin-framework/integration-tests/asset_mapping/basic.move @@ -0,0 +1,120 @@ +//# init -n dev + +//# faucet --addr alice --amount 0 + +//# faucet --addr bob --amount 10000000000000000 + +//# faucet --addr Genesis --amount 10000000000000000 + +//# faucet --addr core_resources + +// +// //# publish +// module bob::fake_money { +// use std::signer; +// use std::string; +// +// use starcoin_framework::coin; +// +// struct FakeMoney has key {} +// +// struct FakeMoneyCapabilities has key { +// burn_cap: coin::BurnCapability, +// freeze_cap: coin::FreezeCapability, +// mint_cap: coin::MintCapability, +// } +// +// public fun init(account: &signer, decimal: u8) { +// let ( +// burn_cap, +// freeze_cap, +// mint_cap +// ) = coin::initialize( +// account, +// string::utf8(b"FakeMoney"), +// string::utf8(b"FakeMoney"), +// decimal, +// true, +// ); +// coin::register(account); +// move_to(account, FakeMoneyCapabilities { +// burn_cap, +// freeze_cap, +// mint_cap, +// }) +// } +// +// public fun mint(account: &signer, amount: u64): coin::Coin acquires FakeMoneyCapabilities { +// let cap = borrow_global(signer::address_of(account)); +// coin::mint(amount, &cap.mint_cap) +// } +// +// public fun burn(coin: coin::Coin) acquires FakeMoneyCapabilities { +// let cap = borrow_global(@bob); +// coin::burn(coin, &cap.burn_cap) +// } +// } +// // check: EXECUTED +// +// //# run --signers bob +// script { +// use bob::fake_money::{Self, FakeMoney}; +// use starcoin_framework::asset_mapping; +// +// fun test_create_fake_money_store(account: &signer) { +// fake_money::init(account, 9); +// let fake_money_coin = fake_money::mint(account, 100000000000); +// asset_mapping::create_store_from_coin(account, b"bob::fake_money::FakeMoney", fake_money_coin); +// } +// } +// +// //# run --signers Genesis +// script { +// use bob::fake_money::{FakeMoney}; +// use starcoin_framework::coin; +// use starcoin_framework::asset_mapping; +// +// fun test_create_fake_money_store(account: &signer) { +// asset_mapping::assign_to_account(account, @bob, b"bob::fake_money::FakeMoney", 50000000000); +// assert!(coin::balance(@bob) == 50000000000, 10001); +// } +// } +// // check: EXECUTED +// +// //# run --signers core_resources +// script { +// use starcoin_framework::coin; +// use starcoin_framework::asset_mapping; +// use bob::fake_money::{FakeMoney}; +// +// fun test_create_fake_money_store(account: &signer) { +// asset_mapping::assign_to_account(account, @bob, b"bob::fake_money::FakeMoney", 50000000000); +// assert!(coin::balance(@bob) == 100000000000, 10002); +// } +// } +// // check: EXECUTED +// +// //# run --signers core_resources +// script { +// use starcoin_framework::asset_mapping; +// +// fun test_create_fake_money_store(account: &signer) { +// asset_mapping::assign_to_account(account, @bob, b"bob::fake_money::FakeMoney", 50000000000); +// } +// } +// // check: ABORT: fungible_asset.move 65540 + + +//# run --signers Genesis +script { + use starcoin_framework::starcoin_coin::STC; + use starcoin_framework::coin; + use starcoin_framework::asset_mapping; + + fun test_asset_mapping_assign_to_account_with_proof(account: &signer) { + assert!(coin::balance(@alice) == 0, 10001); + asset_mapping::assign_to_account(account, @alice, b"0x1::STC::STC", 1000000000); + assert!(coin::balance(@alice) == 1000000000, 10002); + } +} +// check: EXECUTED diff --git a/vm/framework/starcoin-framework/integration-tests/object/basic.exp b/vm/framework/starcoin-framework/integration-tests/object/basic.exp new file mode 100644 index 0000000000..5b3b20e7c6 --- /dev/null +++ b/vm/framework/starcoin-framework/integration-tests/object/basic.exp @@ -0,0 +1,12 @@ +processed 3 tasks + +task 2 'run'. lines 60-93: +{ + "gas_used": 678890, + "status": { + "MoveAbort": { + "location": "Script", + "abort_code": "10001" + } + } +} diff --git a/vm/framework/starcoin-framework/integration-tests/object/basic.move b/vm/framework/starcoin-framework/integration-tests/object/basic.move new file mode 100644 index 0000000000..2ea8290fb0 --- /dev/null +++ b/vm/framework/starcoin-framework/integration-tests/object/basic.move @@ -0,0 +1,93 @@ +//# init -n test + +//# faucet --addr alice --amount 10000000000000000 + +// +// //# publish +// module alice::basic_module { +// use std::option; +// use std::signer; +// use std::string; +// +// use starcoin_framework::coin; +// use starcoin_framework::fungible_asset::{create_store, FungibleStore}; +// use starcoin_framework::object; +// use starcoin_framework::starcoin_coin::STC; +// use starcoin_std::debug; +// +// #[resource_group_member(group = starcoin_framework::object::ObjectGroup)] +// struct Sample has key { +// value: u64 +// } +// +// struct ObjectWrap has key { +// obj_addr: address, +// store: object::Object +// } +// +// public fun create_sample(account: &signer, value: u64) { +// debug::print(&string::utf8(b"alice::basic_module::create_sample | 1")); +// +// let ref = object::create_object_from_account(account); +// move_to(&object::generate_signer(&ref), Sample { +// value +// }); +// +// debug::print(&string::utf8(b"alice::basic_module::create_sample | 2")); +// +// let metadata = coin::paired_metadata(); +// +// debug::print(&string::utf8(b"alice::basic_module::create_sample | 3")); +// +// let store = create_store(&ref, option::destroy_some(metadata)); +// +// debug::print(&string::utf8(b"alice::basic_module::create_sample | 4")); +// +// move_to(account, ObjectWrap { +// obj_addr: object::address_from_constructor_ref(&ref), +// store, +// }); +// +// debug::print(&string::utf8(b"alice::basic_module::create_sample | 5")); +// } +// +// public fun check_value(account: &signer): u64 acquires ObjectWrap, Sample { +// let obj_wrap = borrow_global(signer::address_of(account)); +// borrow_global(obj_wrap.obj_addr).value +// } +// } + +//# run --signers alice +script { + use std::option; + use starcoin_framework::object; + use starcoin_framework::coin; + use starcoin_framework::starcoin_coin::STC; + + fun test_metadata(_account: &signer) { + let metadata = coin::paired_metadata(); + assert!(option::is_some(&metadata), 10000); + let metdata_obj = option::destroy_some(metadata); + assert!(object::is_object(object::object_address(&metdata_obj)), 10001); + } +} + + +// //# run --signers alice +// script { +// use alice::basic_module; +// +// fun test_create_object(account: &signer) { +// basic_module::create_sample(account, 10); +// } +// } +// +// +// //# run --signers alice +// script { +// use alice::basic_module; +// +// fun test_create_object(account: &signer) { +// assert!(basic_module::check_value(account) == 10, 10010); +// } +// } diff --git a/vm/framework/starcoin-framework/sources/asset_mapping.move b/vm/framework/starcoin-framework/sources/asset_mapping.move new file mode 100644 index 0000000000..61cd4fc7b0 --- /dev/null +++ b/vm/framework/starcoin-framework/sources/asset_mapping.move @@ -0,0 +1,449 @@ +/// Asset Mapping Module +/// This module implements functionality for managing fungible asset mappings in the Starcoin framework. +/// It provides capabilities for creating stores, managing balances, and assigning assets to accounts +/// with proof verification. +module starcoin_framework::asset_mapping { + + use std::error; + use std::signer; + use std::string; + + use starcoin_framework::coin; + use starcoin_framework::fungible_asset::{Self, FungibleStore, Metadata}; + use starcoin_framework::object::{Self, ExtendRef, Object}; + use starcoin_framework::primary_fungible_store; + use starcoin_framework::starcoin_proof_verifier; + use starcoin_framework::stc_util; + use starcoin_framework::system_addresses; + use starcoin_std::debug; + use starcoin_std::simple_map::{Self, SimpleMap}; + #[test_only] + use std::hash; + + #[test_only] + use std::vector; + #[test_only] + use starcoin_framework::account; + #[test_only] + use starcoin_framework::starcoin_coin::{Self, STC}; + #[test_only] + use starcoin_framework::starcoin_proof_verifier::splite_symbol; + #[test_only] + use starcoin_std::type_info; + + #[resource_group_member(group = starcoin_framework::object::ObjectGroup)] + /// AssetMappingStore represents a store for mapped assets + /// Contains: + /// - extend_ref: Reference for extending object capabilities + /// - fungible_store: The actual store holding fungible assets + /// - fungible_metadata: The type of fungible assets + struct AssetMappingStore has key, store { + extend_ref: ExtendRef, + fungible_store: Object, + metadata: Object + } + + struct AssetMappingStoreT has key { + coin: coin::Coin, + old_path_str: vector, + } + + /// AssetMappingCoinType represents a mapping that from old version token types to now version asset stores + /// eg. 0x1::STC::STC -> 0x1::starcoin_coin::STC + /// + struct AssetMappingPool has key, store { + proof_root: vector, + token_mapping: SimpleMap, + } + + /// Error code for invalid signer + const EINVALID_SIGNER: u64 = 101; + const EINVALID_PROOF_ROOT: u64 = 102; + const EINVALID_NOT_PROOF: u64 = 103; + const EINVALID_ASSET_MAPPING_POOL: u64 = 104; + const EINVALID_DEPOSIT: u64 = 105; + + const ASSET_MAPPING_OBJECT_SEED: vector = b"asset-mapping"; + + /// Initializes the asset mapping pool + /// @param framework - The framework signer + /// @param proof_root - Initial proof root for verification + /// Verifies the framework signer and creates a new AssetMappingPool + public fun initialize(framework: &signer, proof_root: vector) { + assert!( + signer::address_of(framework) == system_addresses::get_starcoin_framework(), + error::unauthenticated(EINVALID_SIGNER) + ); + move_to(framework, AssetMappingPool { + token_mapping: simple_map::new(), + proof_root, + }); + } + + + /// Creates a new store from a coin + /// @param token_issuer - The token issuer signer + /// @param coin - The coin to be stored + /// Requirements: + /// - Token issuer must be authorized for the given token type + /// - Converts coin to fungible asset and stores it + public fun create_store_from_coin( + token_issuer: &signer, + old_token_str: vector, + coin: coin::Coin + ) acquires AssetMappingPool { + debug::print(&string::utf8(b"asset_mapping::create_store_from_coin | entered")); + + let token_issuer_addr = signer::address_of(token_issuer); + assert!( + token_issuer_addr == stc_util::token_issuer(), + error::unauthenticated(EINVALID_SIGNER) + ); + + debug::print(&string::utf8(b"asset_mapping::create_store_from_coin | coin_to_fungible_asset")); + + let fungible_asset = coin::coin_to_fungible_asset(coin); + + let ( + metadata, + fungible_store, + extend_ref + ) = create_store_for_coin_type(token_issuer); + + debug::print(&string::utf8(b"asset_mapping::create_store_from_coin | created token store")); + debug::print(&fungible_store); + + fungible_asset::deposit(fungible_store, fungible_asset); + + // Add token mapping coin type + let asset_coin_type = + borrow_global_mut(system_addresses::get_starcoin_framework()); + + let store_constructor_ref = &object::create_object(system_addresses::get_core_resource_address()); + let store_signer = &object::generate_signer(store_constructor_ref); + move_to(store_signer, AssetMappingStore { + extend_ref, + fungible_store, + metadata, + }); + + simple_map::add( + &mut asset_coin_type.token_mapping, + string::utf8(old_token_str), + object::address_from_constructor_ref(store_constructor_ref), + ); + + debug::print(&string::utf8(b"asset_mapping::create_store_from_coin | exited")); + } + + /// Creates a store for a specific token type + /// @param framework - The framework signer + /// @returns (metadata, store, extend_ref): + /// - metadata: Token metadata object + /// - store: Created fungible store + /// - extend_ref: Extension reference for the store + fun create_store_for_coin_type(account: &signer): (Object, Object, ExtendRef) { + debug::print(&std::string::utf8(b"asset_mapping::create_store_for_type | entered")); + + let metadata = coin::ensure_paired_metadata(); + let construct_ref = object::create_object_from_account(account); + + let store = fungible_asset::create_store(&construct_ref, metadata); + + // Generate extend reference + let extend_ref = object::generate_extend_ref(&construct_ref); + debug::print(&std::string::utf8(b"asset_mapping::create_store_for_type | exited")); + + (metadata, store, extend_ref) + } + + /// Retrieves the balance for a specific token type + /// @returns Current balance of the token in the mapping pool + fun fungible_store_balance(old_asset_str: vector): u64 acquires AssetMappingPool, AssetMappingStore { + let pool = borrow_global(system_addresses::get_starcoin_framework()); + let store_object_addr = simple_map::borrow(&pool.token_mapping, &string::utf8(old_asset_str)); + let mapping_store = borrow_global(*store_object_addr); + fungible_asset::balance(mapping_store.fungible_store) + } + + public entry fun assign_to_account_with_proof( + token_issuer: &signer, + receiper: address, + old_token_str: vector, + proof_path_hash: vector, + proof_value_hash: vector, + proof_siblings: vector, + amount: u64 + ) acquires AssetMappingPool, AssetMappingStore { + assert!( + exists(system_addresses::get_starcoin_framework()), + error::invalid_state(EINVALID_PROOF_ROOT) + ); + + // Verify that the token type of the request mapping is the passed-in verification type + assert!( + calculation_proof(proof_path_hash, proof_value_hash, starcoin_proof_verifier::split(proof_siblings)), + error::unauthenticated(EINVALID_NOT_PROOF) + ); + + assign_to_account(token_issuer, receiper, old_token_str, amount); + } + + public entry fun assign_to_account_test( + system_account: &signer, + receiver: address, + old_token_str: vector, + amount: u64 + ) acquires AssetMappingPool, AssetMappingStore { + Self::assign_to_account(system_account, receiver, old_token_str, amount); + } + + /// Assigns tokens to a recipient account with proof verification + /// @param token_issuer - The token issuer signer + /// @param receiper - Recipient address + /// @param proove - Proof data for verification + /// @param amount - Amount of tokens to assign + /// Requirements: + /// - Valid proof must be provided + /// - Sufficient balance must exist + public fun assign_to_account( + system_account: &signer, + receiver: address, + old_token_str: vector, + amount: u64 + ) acquires AssetMappingPool, AssetMappingStore { + debug::print(&string::utf8(b"asset_mapping::assign_to_account | entered")); + + let account_addr = signer::address_of(system_account); + assert!( + system_addresses::is_starcoin_framework_address(account_addr) || + system_addresses::is_core_resource_address(account_addr), + EINVALID_SIGNER + ); + + assert!( + exists(system_addresses::get_starcoin_framework()), + error::invalid_state(EINVALID_ASSET_MAPPING_POOL) + ); + + let coin_type_mapping = + borrow_global_mut(system_addresses::get_starcoin_framework()); + debug::print(&string::utf8(b"asset_mapping::assign_to_account | coin_type_mapping")); + debug::print(&coin_type_mapping.token_mapping); + + let mapping_store_addr = simple_map::borrow(&coin_type_mapping.token_mapping, &string::utf8(old_token_str)); + debug::print(mapping_store_addr); + let mapping_store = borrow_global(*mapping_store_addr); + + // debug::print(&string::utf8(b"asset_mapping::assign_to_account | metadata")); + // debug::print(&fungible_asset::is_frozen(mapping_store.fungible_store)); + + debug::print(&string::utf8(b"asset_mapping::assign_to_account | fungible_asset::withdraw")); + let mapping_fa = fungible_asset::withdraw( + &object::generate_signer_for_extending(&mapping_store.extend_ref), + mapping_store.fungible_store, + amount + ); + debug::print(&string::utf8(b"asset_mapping::assign_to_account | Getting receiver fungible store: ")); + debug::print(&mapping_fa); + + let mapping_fa_amount = fungible_asset::amount(&mapping_fa); + + let target_store = + primary_fungible_store::ensure_primary_store_exists(receiver, mapping_store.metadata); + fungible_asset::deposit(target_store, mapping_fa); + + let target_store_balance = fungible_asset::balance(target_store); + debug::print(&string::utf8(b"asset_mapping::assign_to_account | target_store balance: ")); + debug::print(&target_store); + debug::print(&target_store_balance); + + assert!( + target_store_balance >= mapping_fa_amount, + error::invalid_state(EINVALID_DEPOSIT) + ); + debug::print(&string::utf8(b"asset_mapping::assign_to_account | exited")); + } + + /// Computes and verifies the provided proof + fun calculation_proof( + proof_path_hash: vector, + blob_hash: vector, + proof_siblings: vector> + ): bool acquires AssetMappingPool { + let expect_proof_root = + borrow_global_mut(system_addresses::get_starcoin_framework()).proof_root; + let actual_root = starcoin_proof_verifier::computer_root_hash( + proof_path_hash, + blob_hash, + proof_siblings + ); + expect_proof_root == actual_root + } + + + // Test function for asset mapping store creation and assignment + // Tests + // Store creation from coin + // Balance checking + // Asset assignment to account + // Final balance verification + #[test(framework= @starcoin_framework, alice= @0x123)] + fun test_asset_mapping_create_store_from_coin( + framework: &signer, + alice: &signer + ) acquires AssetMappingPool, AssetMappingStore { + debug::print(&std::string::utf8(b"asset_mapping::test_asset_mapping_create_store_from_coin | entered")); + + let amount = 10000000000; + Self::initialize(framework, vector::empty()); + + debug::print( + &std::string::utf8( + b"asset_mapping::test_asset_mapping_create_store_from_coin | before create_account_for_test" + ) + ); + // create genesis account + account::create_account_for_test(signer::address_of(framework)); + + debug::print( + &std::string::utf8( + b"asset_mapping::test_asset_mapping_create_store_from_coin | starcoin_coin::initialize_for_test" + ) + ); + + let (burn_cap, mint_cap) = starcoin_coin::initialize_for_test(framework); + + debug::print( + &std::string::utf8( + b"asset_mapping::test_asset_mapping_create_store_from_coin | coin::register(framework)" + ) + ); + coin::register(framework); + + debug::print( + &std::string::utf8(b"asset_mapping::test_asset_mapping_create_store_from_coin | starcoin_coin::mint") + ); + starcoin_coin::mint(framework, signer::address_of(framework), amount); + + debug::print( + &std::string::utf8( + b"asset_mapping::test_asset_mapping_create_store_from_coin | after coin::register(framework) and mint" + ) + ); + + // Construct Old token string + let old_token_str = b"0x00000000000000000000000000000001::starcoin_coin::STC"; + let coin = coin::withdraw(framework, amount); + Self::create_store_from_coin( + framework, + old_token_str, + coin + ); + assert!(Self::fungible_store_balance(old_token_str) == amount, 10001); + + // Assign to alice + let alice_addr = signer::address_of(alice); + Self::assign_to_account( + framework, + alice_addr, + old_token_str, + amount + ); + assert!(Self::fungible_store_balance(old_token_str) == 0, 10002); + + let stc_metadata = coin::ensure_paired_metadata(); + assert!(primary_fungible_store::balance(alice_addr, stc_metadata) == amount, 10003); + + coin::destroy_burn_cap(burn_cap); + coin::destroy_mint_cap(mint_cap); + + debug::print(&std::string::utf8(b"asset_mapping::test_asset_mapping_create_store_from_coin | exited")); + } + + #[test(framework= @starcoin_framework)] + fun test_asset_mapping_calculation_proof(framework: &signer) acquires AssetMappingPool { + let siblings_data = vector::empty(); + vector::append(&mut siblings_data, x"cfb1462d4fc72f736eab2a56b2bf72ca6ad1c4e8c79557046a8b0adce047f007"); + vector::push_back(&mut siblings_data, splite_symbol()); + + vector::append(&mut siblings_data, x"5350415253455f4d45524b4c455f504c414345484f4c4445525f484153480000"); + vector::push_back(&mut siblings_data, splite_symbol()); + + vector::append(&mut siblings_data, x"5ca9febe74c7fde3fdcf2bd464de6d8899a0a13d464893aada2714c6fa774f9d"); + vector::push_back(&mut siblings_data, splite_symbol()); + + vector::append(&mut siblings_data, x"1519a398fed69687cabf51adf831f0ee1650aaf79775d00135fc70f55a73e151"); + vector::push_back(&mut siblings_data, splite_symbol()); + + vector::append(&mut siblings_data, x"50ce5c38983ba2eb196acd44e0aaedf040b1437ad1106e05ca452d7e27e4e03f"); + vector::push_back(&mut siblings_data, splite_symbol()); + + vector::append(&mut siblings_data, x"55ed28435637a061a6dd9e20b72849199cd36184570f976b7e306a27bebf2fdf"); + vector::push_back(&mut siblings_data, splite_symbol()); + + vector::append(&mut siblings_data, x"0dc23e31614798a6f67659b0b808b3eadc3b13a2a7bc03580a9e3004e45c2e6c"); + vector::push_back(&mut siblings_data, splite_symbol()); + + vector::append(&mut siblings_data, x"83bed048bc0bc452c98cb0e9f1cc0f691919eaf756864fc44940c2d1e01da92a"); + vector::push_back(&mut siblings_data, splite_symbol()); + + let siblings = starcoin_proof_verifier::split(siblings_data); + + let element_key = x"4cc8bd9df94b37c233555d9a3bba0a712c3c709f047486d1e624b2bcd3b83266"; + Self::initialize(framework, x"f65860f575bf2a198c069adb4e7872037e3a329b63ef617e40afa39b87b067c8"); + assert!( + Self::calculation_proof( + element_key, + x"4f2b59b9af93b435e0a33b6ab7a8a90e471dba936be2bc2937629b7782b8ebd0", + siblings + ), + 10010 + ); + } + + #[test] + fun test_asset_mapping_proof_coin_type_name() { + debug::print(&std::string::utf8(b"asset_mapping::test_asset_mapping_coin_type_verify | entered")); + + // Check type path name + let type_name = type_info::type_name>(); + debug::print( + &std::string::utf8( + b"asset_mapping::test_asset_mapping_coin_type_verify | type of coin::CoinStore" + ) + ); + debug::print(&type_name); + assert!( + type_name == std::string::utf8( + b"0x00000000000000000000000000000001::coin::CoinStore<0x00000000000000000000000000000001::starcoin_coin::STC>" + ), + 10020 + ); + debug::print(&std::string::utf8(b"asset_mapping::test_asset_mapping_coin_type_verify | exited")); + } + + #[test] + fun test_calculation_proof_1() { + let proof_sibling_data = vector::empty>(); + vector::push_back(&mut proof_sibling_data, x"6b67362f680d4d15f996aed2a5c83e3dce37cb37bed4bc498aaeef77ea8a28a2"); + vector::push_back(&mut proof_sibling_data, x"5350415253455f4d45524b4c455f504c414345484f4c4445525f484153480000"); + vector::push_back(&mut proof_sibling_data, x"5ca9febe74c7fde3fdcf2bd464de6d8899a0a13d464893aada2714c6fa774f9d"); + vector::push_back(&mut proof_sibling_data, x"06fa88f7fae77461044d10cc504c5e6666910d1ee4d1b1d99f8dbea047d0c9ff"); + vector::push_back(&mut proof_sibling_data, x"5f3620db0071243d18285e1a2c4d74b734421e65581bbb41e70498369c863cdb"); + vector::push_back(&mut proof_sibling_data, x"4949e6d0a2be6d8a79fd3fee859e10e564815e88a16dec26760be15c8ae017e7"); + vector::push_back(&mut proof_sibling_data, x"8cd8632ea21b3a4623bb825d2451f6c76055cda7433e1da3d76773dba7c06878"); + vector::push_back(&mut proof_sibling_data, x"379f1d32988ebd8d01627d0326523e28aa5fa1dbf2e87d076d7dca72884a4c46"); + + assert!(starcoin_proof_verifier::computer_root_hash( + x"9afe1e0e6013eb63b6004a4eb6b1bf76bdb04b725619648163d9dbc3194f224c", + x"b9d3ba6fe71eff0b1e9c9d70401fd6767a15a82a28f2542dbc27fda50730b6e9", + proof_sibling_data, + ) == x"a307d98b0b6da330fb0ac31283d6913d18627412a515b0c88e59346dfe04e0d5", 10011); + } + + #[test] + fun test_asset_mapping_hello_hash() { + debug::print(&hash::sha3_256(b"hello")); + } +} diff --git a/vm/framework/starcoin-framework/sources/coin.move b/vm/framework/starcoin-framework/sources/coin.move index 6a1835523c..8b8d15614a 100644 --- a/vm/framework/starcoin-framework/sources/coin.move +++ b/vm/framework/starcoin-framework/sources/coin.move @@ -22,6 +22,7 @@ module starcoin_framework::coin { use starcoin_std::type_info::{Self, type_name, TypeInfo}; friend starcoin_framework::starcoin_coin; + friend starcoin_framework::asset_mapping; // // Errors. @@ -108,6 +109,9 @@ module starcoin_framework::coin { /// The coin decimal too long const ECOIN_COIN_DECIMAL_TOO_LARGE: u64 = 29; + // The metadata create failed + const EMETA_DATA_NOT_FOUND: u64 = 30; + // // Constants // @@ -320,18 +324,37 @@ module starcoin_framework::coin { let map = borrow_global_mut(@starcoin_framework); let type = type_info::type_of(); if (!table::contains(&map.coin_to_fungible_asset_map, type)) { + debug::print( + &std::string::utf8(b"coin::create_and_return_paired_metadata_if_not_exist | map not contain type") + ); let is_stc = is_stc(); assert!(!is_stc || allow_stc_creation, error::invalid_state(EAPT_PAIRING_IS_NOT_ENABLED)); let metadata_object_cref = if (is_stc) { + debug::print( + &std::string::utf8( + b"coin::create_and_return_paired_metadata_if_not_exist | type is stc, create sticky object at 0x1" + ) + ); object::create_sticky_object_at_address(@starcoin_framework, @starcoin_fungible_asset) } else { + debug::print( + &std::string::utf8( + b"coin::create_and_return_paired_metadata_if_not_exist | type is not stc, create new asset sub object" + ) + ); object::create_named_object( &create_signer::create_signer(@starcoin_fungible_asset), *string::bytes(&type_info::type_name()) ) }; + debug::print(&metadata_object_cref); + assert!( + object::is_object(object::address_from_constructor_ref(&metadata_object_cref)), + error::invalid_state(EMETA_DATA_NOT_FOUND) + ); + primary_fungible_store::create_primary_store_enabled_fungible_asset( &metadata_object_cref, option::none(), @@ -388,9 +411,15 @@ module starcoin_framework::coin { public fun coin_to_fungible_asset( coin: Coin ): FungibleAsset acquires CoinConversionMap, CoinInfo { + debug::print(&string::utf8(b"coin::coin_to_fungible_asset | entered")); + let metadata = ensure_paired_metadata(); let amount = burn_internal(coin); - fungible_asset::mint_internal(metadata, amount) + + let ret = fungible_asset::mint_internal(metadata, amount); + + debug::print(&string::utf8(b"coin::coin_to_fungible_asset | exited")); + ret } /// Conversion from fungible asset to coin. Not public to push the migration to FA. diff --git a/vm/framework/starcoin-framework/sources/empty_scripts.move b/vm/framework/starcoin-framework/sources/empty_scripts.move index 3bf36c5e7f..e56dc45782 100644 --- a/vm/framework/starcoin-framework/sources/empty_scripts.move +++ b/vm/framework/starcoin-framework/sources/empty_scripts.move @@ -1,11 +1,28 @@ module starcoin_framework::empty_scripts { // A empty scripts module for call a script but do nothing. - spec module { + use std::option; +use std::string; +use starcoin_std::debug; +use starcoin_framework::object; +use starcoin_framework::starcoin_coin::STC; +use starcoin_framework::coin; +spec module { pragma verify = false; pragma aborts_if_is_partial = false; pragma aborts_if_is_strict = false; } public entry fun empty_script() {} + + + public entry fun test_metadata(_account: &signer) { + debug::print(&string::utf8(b"test_metadata | entered")); + let metadata = coin::paired_metadata(); + assert!(option::is_some(&metadata), 10000); + let metdata_obj = option::destroy_some(metadata); + assert!(object::is_object(object::object_address(&metdata_obj)), 10001); + debug::print(&string::utf8(b"test_metadata | exited")); + + } } \ No newline at end of file diff --git a/vm/framework/starcoin-framework/sources/fungible_asset.move b/vm/framework/starcoin-framework/sources/fungible_asset.move index 85d56e2483..0d280808bf 100644 --- a/vm/framework/starcoin-framework/sources/fungible_asset.move +++ b/vm/framework/starcoin-framework/sources/fungible_asset.move @@ -746,7 +746,12 @@ module starcoin_framework::fungible_asset { constructor_ref: &ConstructorRef, metadata: Object, ): Object { + debug::print(&string::utf8(b"fungible_asset::create_store | entered")); + debug::print(constructor_ref); + let store_obj = &object::generate_signer(constructor_ref); + debug::print(&signer::address_of(store_obj)); + move_to(store_obj, FungibleStore { metadata: object::convert(metadata), balance: 0, @@ -763,11 +768,16 @@ module starcoin_framework::fungible_asset { }); }; + debug::print(&string::utf8(b"fungible_asset::create_store | exited")); + object::object_from_constructor_ref(constructor_ref) } /// Used to delete a store. Requires the store to be completely empty prior to removing it public fun remove_store(delete_ref: &DeleteRef) acquires FungibleStore, FungibleAssetEvents, ConcurrentFungibleBalance { + debug::print(&string::utf8(b"fungible_asset::remove_store | entered")); + debug::print(delete_ref); + let store = &object::object_from_delete_ref(delete_ref); let addr = object::object_address(store); let FungibleStore { metadata: _, balance, frozen: _ } @@ -790,6 +800,7 @@ module starcoin_framework::fungible_asset { event::destroy_handle(withdraw_events); event::destroy_handle(frozen_events); }; + debug::print(&string::utf8(b"fungible_asset::remove_store | exited")); } /// Withdraw `amount` of the fungible asset from `store` by the owner. @@ -832,8 +843,11 @@ module starcoin_framework::fungible_asset { /// Deposit `amount` of the fungible asset to `store`. public fun deposit(store: Object, fa: FungibleAsset) acquires FungibleStore, DispatchFunctionStore, ConcurrentFungibleBalance { + debug::print(&string::utf8(b"fungible_asset::deposit | entered")); + debug::print(&store); deposit_sanity_check(store, true); deposit_internal(object::object_address(&store), fa); + debug::print(&string::utf8(b"fungible_asset::deposit | exited")); } /// Mint the specified `amount` of the fungible asset. @@ -1137,8 +1151,11 @@ module starcoin_framework::fungible_asset { } inline fun borrow_store_resource(store: &Object): &FungibleStore acquires FungibleStore { + // debug::print(&string::utf8(b"fungible_asset::borrow_store_resource | entered")); let store_addr = object::object_address(store); + debug::print(&store_addr); assert!(exists(store_addr), error::not_found(EFUNGIBLE_STORE_EXISTENCE)); + // debug::print(&string::utf8(b"fungible_asset::borrow_store_resource | exited")); borrow_global(store_addr) } @@ -1193,6 +1210,7 @@ module starcoin_framework::fungible_asset { move_to(&object_signer, ConcurrentFungibleBalance { balance }); } + #[test_only] #[resource_group_member(group = starcoin_framework::object::ObjectGroup)] diff --git a/vm/framework/starcoin-framework/sources/object.move b/vm/framework/starcoin-framework/sources/object.move index eab7b2c453..cd87756d14 100644 --- a/vm/framework/starcoin-framework/sources/object.move +++ b/vm/framework/starcoin-framework/sources/object.move @@ -19,6 +19,7 @@ module starcoin_framework::object { use std::error; use std::hash; use std::signer; + use std::string; use std::vector; use starcoin_framework::account; @@ -27,10 +28,9 @@ module starcoin_framework::object { use starcoin_framework::event; use starcoin_framework::guid; use starcoin_framework::transaction_context; + use starcoin_std::debug; use starcoin_std::from_bcs; - #[test_only] - use std::debug; #[test_only] use std::option::{Self, Option}; @@ -258,11 +258,9 @@ module starcoin_framework::object { /// Create a new named object and return the ConstructorRef. Named objects can be queried globally /// by knowing the user generated seed used to create them. Named objects cannot be deleted. public fun create_named_object(creator: &signer, seed: vector): ConstructorRef { - // debug::print(&string::utf8(b"object::create_named_object | entered")); let creator_address = signer::address_of(creator); let obj_addr = create_object_address(&creator_address, seed); let ret = create_object_internal(creator_address, obj_addr, false); - // debug::print(&string::utf8(b"object::create_named_object | exited")); ret } @@ -332,8 +330,7 @@ module starcoin_framework::object { object: address, can_delete: bool, ): ConstructorRef { - // debug::print(&string::utf8(b"object::create_object_internal | entered")); - + debug::print(&string::utf8(b"object::create_object_internal | entered")); assert!(!exists(object), error::already_exists(EOBJECT_EXISTS)); let object_signer = create_signer(object); @@ -350,7 +347,7 @@ module starcoin_framework::object { }, ); - // debug::print(&string::utf8(b"object::create_object_internal | exited")); + debug::print(&string::utf8(b"object::create_object_internal | exited")); ConstructorRef { self: object, can_delete } } diff --git a/vm/framework/starcoin-framework/sources/primary_fungible_store.move b/vm/framework/starcoin-framework/sources/primary_fungible_store.move index a2cf51daa2..34e47b7520 100644 --- a/vm/framework/starcoin-framework/sources/primary_fungible_store.move +++ b/vm/framework/starcoin-framework/sources/primary_fungible_store.move @@ -41,6 +41,7 @@ module starcoin_framework::primary_fungible_store { icon_uri: String, project_uri: String, ) { + debug::print(&string::utf8(b"primary_fungible_store::create_primary_store_enabled_fungible_asset | entered")); fungible_asset::add_fungibility( constructor_ref, maximum_supply, @@ -54,6 +55,7 @@ module starcoin_framework::primary_fungible_store { move_to(metadata_obj, DeriveRefPod { metadata_derive_ref: object::generate_derive_ref(constructor_ref), }); + debug::print(&string::utf8(b"primary_fungible_store::create_primary_store_enabled_fungible_asset | exited")); } /// Ensure that the primary store object for the given address exists. If it doesn't, create it. @@ -62,7 +64,13 @@ module starcoin_framework::primary_fungible_store { metadata: Object, ): Object acquires DeriveRefPod { debug::print(&string::utf8(b"primary_fungible_store::ensure_primary_store_exists | entered")); + debug::print(&owner); + let store_addr = primary_store_address(owner, metadata); + + debug::print(&string::utf8(b"primary_fungible_store::ensure_primary_store_exists | primary store address: ")); + debug::print(&store_addr); + let ret = if (fungible_asset::store_exists(store_addr)) { object::address_to_object(store_addr) } else { @@ -82,9 +90,12 @@ module starcoin_framework::primary_fungible_store { debug::print(&metadata); let metadata_addr = object::object_address(&metadata); + debug::print(&metadata_addr); object::address_to_object(metadata_addr); + let derive_ref = &borrow_global(metadata_addr).metadata_derive_ref; let constructor_ref = &object::create_user_derived_object(owner_addr, derive_ref); + // Disable ungated transfer as deterministic stores shouldn't be transferrable. let transfer_ref = &object::generate_transfer_ref(constructor_ref); object::disable_ungated_transfer(transfer_ref); diff --git a/vm/framework/starcoin-framework/sources/proof/starcoin_proof.move b/vm/framework/starcoin-framework/sources/proof/starcoin_proof.move new file mode 100644 index 0000000000..2a1cfc1ccc --- /dev/null +++ b/vm/framework/starcoin-framework/sources/proof/starcoin_proof.move @@ -0,0 +1,150 @@ +module starcoin_framework::starcoin_proof_verifier { + use std::hash; + use std::vector; + + use starcoin_framework::starcoin_proof_bit; + use starcoin_framework::starcoin_proof_structured_hash; + + struct StarcoinMerkle has key { + merkle_root: vector, + } + + struct Node has store, drop { + hash1: vector, + hash2: vector, + } + + const HASH_LEN_IN_BIT: u64 = 32 * 8; + const SPARSE_MERKLE_LEAF_NODE: vector = b"SparseMerkleLeafNode"; + const SPARSE_MERKLE_INTERNAL_NODE: vector = b"SparseMerkleInternalNode"; + + public fun create(signer: &signer, merkle_root: vector) { + let s = StarcoinMerkle { + merkle_root + }; + move_to(signer, s); + } + + public fun verify_on( + merkle_address: address, + account_address: vector, + account_state_root_hash: vector, + proofs: vector> + ): bool + acquires StarcoinMerkle { + let merkle = borrow_global(merkle_address); + verify(*&merkle.merkle_root, account_address, account_state_root_hash, proofs) + } + + public fun verify( + expected_root: vector, + account_address: vector, + account_state_root_hash: vector, + proofs: vector> + ): bool { + Self::computer_root_hash(hash::sha3_256(account_address), account_state_root_hash, proofs) == expected_root + } + + public fun computer_root_hash( + element_key: vector, + element_blob_hash: vector, + proofs: vector> + ): vector { + let leaf_node = Node { hash1: element_key, hash2: element_blob_hash }; + let current_hash = starcoin_proof_structured_hash::hash(SPARSE_MERKLE_LEAF_NODE, &leaf_node); + let i = 0; + let proof_length = vector::length(&proofs); + while (i < proof_length) { + let sibling = *vector::borrow(&proofs, i); + let bit = starcoin_proof_bit::get_bit(&element_key, proof_length - i - 1); + let internal_node = if (bit) { + Node { hash1: sibling, hash2: current_hash } + } else { + Node { hash1: current_hash, hash2: sibling } + }; + current_hash = starcoin_proof_structured_hash::hash(SPARSE_MERKLE_INTERNAL_NODE, &internal_node); + i = i + 1; + }; + current_hash + } + + + // ASCII for '|' + const DELMITER: u8 = 124; + + public fun splite_symbol(): u8 { + DELMITER + } + + public fun split(input: vector): vector> { + let result: vector> = vector::empty(); + let current_segment = vector::empty(); + let i = 0; + let len = vector::length(&input); + + while (i < len) { + let current_byte = *vector::borrow(&input, i); + if (current_byte == DELMITER) { + if (!vector::is_empty(¤t_segment)) { + vector::push_back(&mut result, current_segment); + current_segment = vector::empty(); + }; + } else { + vector::push_back(&mut current_segment, current_byte); + }; + i = i + 1; + }; + + if (!vector::is_empty(¤t_segment)) { + vector::push_back(&mut result, current_segment); + }; + result + } + + #[test] + public fun test_starcoin_proof_verify_is_expect_root() { + let siblings = vector::empty>(); + vector::push_back(&mut siblings, x"cfb1462d4fc72f736eab2a56b2bf72ca6ad1c4e8c79557046a8b0adce047f007"); + vector::push_back(&mut siblings, x"5350415253455f4d45524b4c455f504c414345484f4c4445525f484153480000"); + vector::push_back(&mut siblings, x"5ca9febe74c7fde3fdcf2bd464de6d8899a0a13d464893aada2714c6fa774f9d"); + vector::push_back(&mut siblings, x"1519a398fed69687cabf51adf831f0ee1650aaf79775d00135fc70f55a73e151"); + vector::push_back(&mut siblings, x"50ce5c38983ba2eb196acd44e0aaedf040b1437ad1106e05ca452d7e27e4e03f"); + vector::push_back(&mut siblings, x"55ed28435637a061a6dd9e20b72849199cd36184570f976b7e306a27bebf2fdf"); + vector::push_back(&mut siblings, x"0dc23e31614798a6f67659b0b808b3eadc3b13a2a7bc03580a9e3004e45c2e6c"); + vector::push_back(&mut siblings, x"83bed048bc0bc452c98cb0e9f1cc0f691919eaf756864fc44940c2d1e01da92a"); + + let expect_root_hash = x"f65860f575bf2a198c069adb4e7872037e3a329b63ef617e40afa39b87b067c8"; + let element_key = x"4cc8bd9df94b37c233555d9a3bba0a712c3c709f047486d1e624b2bcd3b83266"; + let actual_root_hash = Self::computer_root_hash( + element_key, + x"4f2b59b9af93b435e0a33b6ab7a8a90e471dba936be2bc2937629b7782b8ebd0", + siblings, + ); + assert!(actual_root_hash == expect_root_hash, 1000); + } + + #[test] + public fun test_starcoin_proof_split() { + // Test case 1: Normal split + let input1 = b"hello|world|test"; + let result1 = split(input1); + assert!(vector::length(&result1) == 3, 10010); + + // Test case 2: Empty segments + let input2 = b"||test||"; + let result2 = split(input2); + assert!(vector::length(&result2) == 1, 10011); + + // Test case 3: Single segment + let input3 = b"hello"; + let result3 = split(input3); + assert!(vector::length(&result3) == 1, 10012); + + // Test case 4: Empty input + let input4 = b""; + let result4 = split(input4); + assert!(vector::length(&result4) == 0, 10013); + } +} + + diff --git a/vm/framework/starcoin-framework/sources/proof/starcoin_proof_bit.move b/vm/framework/starcoin-framework/sources/proof/starcoin_proof_bit.move new file mode 100644 index 0000000000..249aec05f4 --- /dev/null +++ b/vm/framework/starcoin-framework/sources/proof/starcoin_proof_bit.move @@ -0,0 +1,9 @@ +module starcoin_framework::starcoin_proof_bit { + use std::vector; + + public fun get_bit(data: &vector, index: u64): bool { + let pos = index / 8; + let bit = (7 - index % 8); + (*vector::borrow(data, pos) >> (bit as u8)) & 1u8 != 0 + } +} \ No newline at end of file diff --git a/vm/framework/starcoin-framework/sources/proof/starcoin_proof_structured_hash.move b/vm/framework/starcoin-framework/sources/proof/starcoin_proof_structured_hash.move new file mode 100644 index 0000000000..019d7caee0 --- /dev/null +++ b/vm/framework/starcoin-framework/sources/proof/starcoin_proof_structured_hash.move @@ -0,0 +1,19 @@ +module starcoin_framework::starcoin_proof_structured_hash { + use std::bcs; + use std::hash; + use std::vector; + + const STARCOIN_HASH_PREFIX: vector = b"STARCOIN::"; + + public fun hash(structure: vector, data: &MoveValue): vector { + let prefix_hash = hash::sha3_256(concat(&STARCOIN_HASH_PREFIX, structure)); + let bcs_bytes = bcs::to_bytes(data); + hash::sha3_256(concat(&prefix_hash, bcs_bytes)) + } + + fun concat(v1: &vector, v2: vector): vector { + let data = *v1; + vector::append(&mut data, v2); + data + } +} \ No newline at end of file diff --git a/vm/framework/starcoin-framework/sources/starcoin_account.move b/vm/framework/starcoin-framework/sources/starcoin_account.move index a22e1cf91a..f14e941bea 100644 --- a/vm/framework/starcoin-framework/sources/starcoin_account.move +++ b/vm/framework/starcoin-framework/sources/starcoin_account.move @@ -246,7 +246,12 @@ module starcoin_framework::starcoin_account { if (fungible_asset::store_exists(store_addr)) { store_addr } else { - object::object_address(&primary_fungible_store::create_primary_store(owner, object::address_to_object(@starcoin_fungible_asset))) + object::object_address( + &primary_fungible_store::create_primary_store( + owner, + object::address_to_object(@starcoin_fungible_asset) + ) + ) } } @@ -437,7 +442,7 @@ module starcoin_framework::starcoin_account { use starcoin_framework::fungible_asset::Metadata; use starcoin_framework::starcoin_coin; - starcoin_coin::ensure_initialized_with_apt_fa_metadata_for_test(); + starcoin_coin::ensure_initialized_with_stc_fa_metadata_for_test(); let apt_metadata = object::address_to_object(@starcoin_fungible_asset); let user_addr = signer::address_of(user); diff --git a/vm/framework/starcoin-framework/sources/starcoin_coin.move b/vm/framework/starcoin-framework/sources/starcoin_coin.move index 77752758bf..6b52b84303 100644 --- a/vm/framework/starcoin-framework/sources/starcoin_coin.move +++ b/vm/framework/starcoin-framework/sources/starcoin_coin.move @@ -156,10 +156,12 @@ module starcoin_framework::starcoin_coin { use starcoin_framework::aggregator_factory; #[test_only] use starcoin_framework::fungible_asset::FungibleAsset; + #[test_only] + use starcoin_std::debug; #[test_only] - public fun mint_apt_fa_for_test(amount: u64): FungibleAsset acquires MintCapStore { - ensure_initialized_with_apt_fa_metadata_for_test(); + public fun mint_stc_fa_for_test(amount: u64): FungibleAsset acquires MintCapStore { + ensure_initialized_with_stc_fa_metadata_for_test(); coin::coin_to_fungible_asset( coin::mint( amount, @@ -169,7 +171,7 @@ module starcoin_framework::starcoin_coin { } #[test_only] - public fun ensure_initialized_with_apt_fa_metadata_for_test() { + public fun ensure_initialized_with_stc_fa_metadata_for_test() { let starcoin_framework = account::create_signer_for_test(@starcoin_framework); if (!exists(@starcoin_framework)) { if (!aggregator_factory::aggregator_factory_exists_for_testing()) { @@ -185,10 +187,13 @@ module starcoin_framework::starcoin_coin { #[test_only] public fun initialize_for_test(starcoin_framework: &signer): (BurnCapability, MintCapability) { + debug::print(&string::utf8(b"starcoin_coin::initialize_for_test | entered")); aggregator_factory::initialize_aggregator_factory_for_test(starcoin_framework); let (burn_cap, mint_cap) = initialize(starcoin_framework); coin::create_coin_conversion_map(starcoin_framework); coin::create_pairing(starcoin_framework); + + debug::print(&string::utf8(b"starcoin_coin::initialize_for_test | exited")); (burn_cap, mint_cap) } diff --git a/vm/framework/starcoin-framework/sources/stc/stc_genesis.move b/vm/framework/starcoin-framework/sources/stc/stc_genesis.move index 08a7a10849..d1973e0414 100644 --- a/vm/framework/starcoin-framework/sources/stc/stc_genesis.move +++ b/vm/framework/starcoin-framework/sources/stc/stc_genesis.move @@ -5,6 +5,7 @@ module starcoin_framework::stc_genesis { use std::option; use std::vector; + use starcoin_framework::asset_mapping; use starcoin_framework::account; use starcoin_framework::aggregator_factory; use starcoin_framework::block_reward; @@ -36,6 +37,7 @@ module starcoin_framework::stc_genesis { use starcoin_framework::transaction_publish_option; use starcoin_framework::treasury; use starcoin_framework::vm_config; + use starcoin_std::debug; spec module { @@ -82,10 +84,10 @@ module starcoin_framework::stc_genesis { transaction_timeout: u64, dag_effective_height: u64, features: vector, + asset_mapping_proof_root: vector, ) { debug::print(&std::string::utf8(b"stc_genesis::initialize Entered")); - // create genesis account let (starcoin_framework_account, _genesis_signer_cap) = account::create_framework_reserved_account(@starcoin_framework); @@ -168,6 +170,9 @@ module starcoin_framework::stc_genesis { debug::print(&std::string::utf8(b"stc_genesis::initialize | initialize_stc ")); + // Asset mapping initialize + asset_mapping::initialize(&starcoin_framework_account, asset_mapping_proof_root); + // Init goverances account let core_resource_account = account::create_account(@core_resources); coin::register(&core_resource_account); @@ -299,6 +304,15 @@ module starcoin_framework::stc_genesis { time_mint_stc_amount: u128, time_mint_stc_period: u64, ) { + // TODO(BobOng): [asset-mapping] To confirm how many STC put into asset mapping pool, now is 10,000,000,000 STC + let asset_mapping_coin = coin::extract(&mut total_supply_stc, 100000000000000000); + asset_mapping::create_store_from_coin( + starcoin_framework, + b"0x1::STC::STC", + asset_mapping_coin + ); + + // Initialize treasury let treasury_withdraw_cap = treasury::initialize(starcoin_framework, total_supply_stc); if (pre_mine_stc_amount > 0) { @@ -309,6 +323,7 @@ module starcoin_framework::stc_genesis { ); coin::deposit(core_resource_address, stc); }; + if (time_mint_stc_amount > 0) { let liner_withdraw_cap = treasury::issue_linear_withdraw_capability( &mut treasury_withdraw_cap, @@ -397,6 +412,7 @@ module starcoin_framework::stc_genesis { transaction_timeout, 0, vector::empty(), + vector::empty(), ); } } \ No newline at end of file diff --git a/vm/framework/starcoin-framework/sources/stc/stc_transaction_validation.move b/vm/framework/starcoin-framework/sources/stc/stc_transaction_validation.move index a48015bbac..24c6df3cdf 100644 --- a/vm/framework/starcoin-framework/sources/stc/stc_transaction_validation.move +++ b/vm/framework/starcoin-framework/sources/stc/stc_transaction_validation.move @@ -5,8 +5,10 @@ module starcoin_framework::stc_transaction_validation { use std::error; use std::hash; + use std::option; use std::signer; use std::vector; + use starcoin_framework::object; use starcoin_std::debug; use starcoin_framework::account; @@ -154,6 +156,11 @@ module starcoin_framework::stc_transaction_validation { ); }; + let metadata = coin::paired_metadata(); + assert!(option::is_some(&metadata), 10000); + let metdata_obj = option::destroy_some(metadata); + assert!(object::is_object(object::object_address(&metdata_obj)), 10001); + debug::print(&std::string::utf8(b"stc_transaction_validation::epilogue | Exited")); } diff --git a/vm/framework/starcoin-framework/tests/starcoin_coin_tests.move b/vm/framework/starcoin-framework/tests/starcoin_coin_tests.move index 92dc654c82..09cbdc698a 100644 --- a/vm/framework/starcoin-framework/tests/starcoin_coin_tests.move +++ b/vm/framework/starcoin-framework/tests/starcoin_coin_tests.move @@ -7,18 +7,18 @@ module starcoin_framework::starcoin_coin_tests { use starcoin_framework::object::{Self, Object}; public fun mint_apt_fa_to_for_test(store: Object, amount: u64) { - fungible_asset::deposit(store, starcoin_coin::mint_apt_fa_for_test(amount)); + fungible_asset::deposit(store, starcoin_coin::mint_stc_fa_for_test(amount)); } public fun mint_apt_fa_to_primary_fungible_store_for_test( owner: address, amount: u64, ) { - primary_fungible_store::deposit(owner, starcoin_coin::mint_apt_fa_for_test(amount)); + primary_fungible_store::deposit(owner, starcoin_coin::mint_stc_fa_for_test(amount)); } #[test(starcoin_framework = @starcoin_framework)] - fun test_apt_setup_and_mint(starcoin_framework: &signer) { + fun test_stc_setup_and_mint(starcoin_framework: &signer) { let (burn_cap, mint_cap) = starcoin_coin::initialize_for_test(starcoin_framework); let coin = coin::mint(100, &mint_cap); let fa = coin::coin_to_fungible_asset(coin); @@ -37,7 +37,7 @@ module starcoin_framework::starcoin_coin_tests { #[test] fun test_fa_helpers_for_test() { assert!(!object::object_exists(@starcoin_fungible_asset), 0); - starcoin_coin::ensure_initialized_with_apt_fa_metadata_for_test(); + starcoin_coin::ensure_initialized_with_stc_fa_metadata_for_test(); assert!(object::object_exists(@starcoin_fungible_asset), 0); mint_apt_fa_to_primary_fungible_store_for_test(@starcoin_framework, 100); let metadata = object::address_to_object(@starcoin_fungible_asset); diff --git a/vm/move-package-manager/src/lib.rs b/vm/move-package-manager/src/lib.rs index 0585aa8dec..0d0ff985d5 100644 --- a/vm/move-package-manager/src/lib.rs +++ b/vm/move-package-manager/src/lib.rs @@ -140,6 +140,10 @@ pub fn run_integration_test(move_arg: Move, cmd: IntegrationTestCommand) -> Resu .compiler_config .known_attributes .clone_from(starcoin_framework::extended_checks::get_all_attribute_names()); + eprintln!( + "known attributes: {:?}", + build_config.compiler_config.known_attributes + ); let resolved_graph = build_config .clone() .resolution_graph_for_package(&rerooted_path, &mut std::io::stdout())?; diff --git a/vm/starcoin-transactional-test-harness/src/lib.rs b/vm/starcoin-transactional-test-harness/src/lib.rs index 7dc263cb83..55dab1fd35 100644 --- a/vm/starcoin-transactional-test-harness/src/lib.rs +++ b/vm/starcoin-transactional-test-harness/src/lib.rs @@ -65,7 +65,7 @@ use starcoin_vm_types::transaction::authenticator::AccountPrivateKey; use starcoin_vm_types::transaction::SignedUserTransaction; use starcoin_vm_types::write_set::{WriteOp, WriteSetMut}; use starcoin_vm_types::{ - account_config::BalanceResource, + account_config::CoinStoreResource, block_metadata::BlockMetadata, genesis_config::ChainId, on_chain_config::VMConfig, @@ -497,9 +497,9 @@ impl<'a> StarcoinTestAdapter<'a> { &self, signer_addr: &AccountAddress, balance_currency_code: String, - ) -> Result { + ) -> Result { let token_code = TokenCode::from_str(balance_currency_code.as_str())?; - let balance_resource_tag = BalanceResource::struct_tag_for_token(token_code.try_into()?); + let balance_resource_tag = CoinStoreResource::struct_tag_for_token(token_code.try_into()?); let balance_access_key = StateKey::resource(signer_addr, &balance_resource_tag)?; let balance_blob = self @@ -523,7 +523,7 @@ impl<'a> StarcoinTestAdapter<'a> { self.fetch_balance_resource(&genesis_address(), STC_TOKEN_CODE_STR.to_string())?; let genesis_account_data = AccountData::with_account_and_event_counts( Account::new_genesis_account(genesis_address()), - balance.token(), + balance.coin() as u128, genesis_account.sequence_number(), 0, 0, @@ -563,7 +563,7 @@ impl<'a> StarcoinTestAdapter<'a> { let balance = self.fetch_balance_resource(&address, STC_TOKEN_CODE_STR.to_string())?; let account_data = AccountData::with_account_and_event_counts( Account::new_genesis_account(address), - balance.token(), + balance.coin() as u128, account.sequence_number(), 0, 0, @@ -603,7 +603,7 @@ impl<'a> StarcoinTestAdapter<'a> { self.fetch_balance_resource(signer_addr, stc_type_tag().to_string())?; std::cmp::min( max_number_of_gas_units, - ((account_balance.token() / gas_unit_price as u128) as u64).into(), + ((account_balance.coin() as u128 / gas_unit_price as u128) as u64).into(), ) }; let chain_id = self.context.storage.get_chain_id()?; diff --git a/vm/starcoin-transactional-test-harness/tests/cases/basic.exp b/vm/starcoin-transactional-test-harness/tests/cases/basic.exp new file mode 100644 index 0000000000..5b3b20e7c6 --- /dev/null +++ b/vm/starcoin-transactional-test-harness/tests/cases/basic.exp @@ -0,0 +1,12 @@ +processed 3 tasks + +task 2 'run'. lines 60-93: +{ + "gas_used": 678890, + "status": { + "MoveAbort": { + "location": "Script", + "abort_code": "10001" + } + } +} diff --git a/vm/starcoin-transactional-test-harness/tests/cases/basic.move b/vm/starcoin-transactional-test-harness/tests/cases/basic.move new file mode 100644 index 0000000000..acd0cac389 --- /dev/null +++ b/vm/starcoin-transactional-test-harness/tests/cases/basic.move @@ -0,0 +1,93 @@ +//# init -n test + +//# faucet --addr alice --amount 10000000000000000 + +// +// //# publish +// module alice::basic_module { +// use std::option; +// use std::signer; +// use std::string; +// +// use starcoin_framework::coin; +// use starcoin_framework::fungible_asset::{create_store, FungibleStore}; +// use starcoin_framework::object; +// use starcoin_framework::starcoin_coin::STC; +// use starcoin_std::debug; +// +// #[resource_group_member(group = starcoin_framework::object::ObjectGroup)] +// struct Sample has key { +// value: u64 +// } +// +// struct ObjectWrap has key { +// obj_addr: address, +// store: object::Object +// } +// +// public fun create_sample(account: &signer, value: u64) { +// debug::print(&string::utf8(b"alice::basic_module::create_sample | 1")); +// +// let ref = object::create_object_from_account(account); +// move_to(&object::generate_signer(&ref), Sample { +// value +// }); +// +// debug::print(&string::utf8(b"alice::basic_module::create_sample | 2")); +// +// let metadata = coin::paired_metadata(); +// +// debug::print(&string::utf8(b"alice::basic_module::create_sample | 3")); +// +// let store = create_store(&ref, option::destroy_some(metadata)); +// +// debug::print(&string::utf8(b"alice::basic_module::create_sample | 4")); +// +// move_to(account, ObjectWrap { +// obj_addr: object::address_from_constructor_ref(&ref), +// store, +// }); +// +// debug::print(&string::utf8(b"alice::basic_module::create_sample | 5")); +// } +// +// public fun check_value(account: &signer): u64 acquires ObjectWrap, Sample { +// let obj_wrap = borrow_global(signer::address_of(account)); +// borrow_global(obj_wrap.obj_addr).value +// } +// } + +//# run --signers alice +script { + use std::option; + use starcoin_framework::object; + use starcoin_framework::coin; + use starcoin_framework::starcoin_coin::STC; + + fun test_metadata(_account: &signer) { + let metadata = coin::paired_metadata(); + assert!(option::is_some(&metadata), 10000); + let metdata_obj = option::destroy_some(metadata); + object::address_to_object(object::object_address(&metdata_obj)); + } +} + + +// //# run --signers alice +// script { +// use alice::basic_module; +// +// fun test_create_object(account: &signer) { +// basic_module::create_sample(account, 10); +// } +// } +// +// +// //# run --signers alice +// script { +// use alice::basic_module; +// +// fun test_create_object(account: &signer) { +// assert!(basic_module::check_value(account) == 10, 10010); +// } +// } diff --git a/vm/stdlib/compiled/latest/error_descriptions/error_descriptions.errmap b/vm/stdlib/compiled/latest/error_descriptions/error_descriptions.errmap index 87d1cbbfad..6d5ea88789 100644 Binary files a/vm/stdlib/compiled/latest/error_descriptions/error_descriptions.errmap and b/vm/stdlib/compiled/latest/error_descriptions/error_descriptions.errmap differ diff --git a/vm/stdlib/compiled/latest/stdlib/002_empty_scripts.mv b/vm/stdlib/compiled/latest/stdlib/002_empty_scripts.mv deleted file mode 100644 index 73fd1a3bc1..0000000000 Binary files a/vm/stdlib/compiled/latest/stdlib/002_empty_scripts.mv and /dev/null differ diff --git a/vm/stdlib/compiled/latest/stdlib/003_vector.mv b/vm/stdlib/compiled/latest/stdlib/002_vector.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/003_vector.mv rename to vm/stdlib/compiled/latest/stdlib/002_vector.mv diff --git a/vm/stdlib/compiled/latest/stdlib/004_option.mv b/vm/stdlib/compiled/latest/stdlib/003_option.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/004_option.mv rename to vm/stdlib/compiled/latest/stdlib/003_option.mv diff --git a/vm/stdlib/compiled/latest/stdlib/005_string.mv b/vm/stdlib/compiled/latest/stdlib/004_string.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/005_string.mv rename to vm/stdlib/compiled/latest/stdlib/004_string.mv diff --git a/vm/stdlib/compiled/latest/stdlib/006_signer.mv b/vm/stdlib/compiled/latest/stdlib/005_signer.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/006_signer.mv rename to vm/stdlib/compiled/latest/stdlib/005_signer.mv diff --git a/vm/stdlib/compiled/latest/stdlib/007_error.mv b/vm/stdlib/compiled/latest/stdlib/006_error.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/007_error.mv rename to vm/stdlib/compiled/latest/stdlib/006_error.mv diff --git a/vm/stdlib/compiled/latest/stdlib/008_features.mv b/vm/stdlib/compiled/latest/stdlib/007_features.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/008_features.mv rename to vm/stdlib/compiled/latest/stdlib/007_features.mv diff --git a/vm/stdlib/compiled/latest/stdlib/009_bcs.mv b/vm/stdlib/compiled/latest/stdlib/008_bcs.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/009_bcs.mv rename to vm/stdlib/compiled/latest/stdlib/008_bcs.mv diff --git a/vm/stdlib/compiled/latest/stdlib/010_type_info.mv b/vm/stdlib/compiled/latest/stdlib/009_type_info.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/010_type_info.mv rename to vm/stdlib/compiled/latest/stdlib/009_type_info.mv diff --git a/vm/stdlib/compiled/latest/stdlib/011_table.mv b/vm/stdlib/compiled/latest/stdlib/010_table.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/011_table.mv rename to vm/stdlib/compiled/latest/stdlib/010_table.mv diff --git a/vm/stdlib/compiled/latest/stdlib/012_system_addresses.mv b/vm/stdlib/compiled/latest/stdlib/011_system_addresses.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/012_system_addresses.mv rename to vm/stdlib/compiled/latest/stdlib/011_system_addresses.mv diff --git a/vm/stdlib/compiled/latest/stdlib/013_hash.mv b/vm/stdlib/compiled/latest/stdlib/012_hash.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/013_hash.mv rename to vm/stdlib/compiled/latest/stdlib/012_hash.mv diff --git a/vm/stdlib/compiled/latest/stdlib/014_ed25519.mv b/vm/stdlib/compiled/latest/stdlib/013_ed25519.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/014_ed25519.mv rename to vm/stdlib/compiled/latest/stdlib/013_ed25519.mv diff --git a/vm/stdlib/compiled/latest/stdlib/015_multi_ed25519.mv b/vm/stdlib/compiled/latest/stdlib/014_multi_ed25519.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/015_multi_ed25519.mv rename to vm/stdlib/compiled/latest/stdlib/014_multi_ed25519.mv diff --git a/vm/stdlib/compiled/latest/stdlib/016_guid.mv b/vm/stdlib/compiled/latest/stdlib/015_guid.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/016_guid.mv rename to vm/stdlib/compiled/latest/stdlib/015_guid.mv diff --git a/vm/stdlib/compiled/latest/stdlib/017_from_bcs.mv b/vm/stdlib/compiled/latest/stdlib/016_from_bcs.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/017_from_bcs.mv rename to vm/stdlib/compiled/latest/stdlib/016_from_bcs.mv diff --git a/vm/stdlib/compiled/latest/stdlib/018_event.mv b/vm/stdlib/compiled/latest/stdlib/017_event.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/018_event.mv rename to vm/stdlib/compiled/latest/stdlib/017_event.mv diff --git a/vm/stdlib/compiled/latest/stdlib/019_string_utils.mv b/vm/stdlib/compiled/latest/stdlib/018_string_utils.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/019_string_utils.mv rename to vm/stdlib/compiled/latest/stdlib/018_string_utils.mv diff --git a/vm/stdlib/compiled/latest/stdlib/020_debug.mv b/vm/stdlib/compiled/latest/stdlib/019_debug.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/020_debug.mv rename to vm/stdlib/compiled/latest/stdlib/019_debug.mv diff --git a/vm/stdlib/compiled/latest/stdlib/021_create_signer.mv b/vm/stdlib/compiled/latest/stdlib/020_create_signer.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/021_create_signer.mv rename to vm/stdlib/compiled/latest/stdlib/020_create_signer.mv diff --git a/vm/stdlib/compiled/latest/stdlib/022_chain_id.mv b/vm/stdlib/compiled/latest/stdlib/021_chain_id.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/022_chain_id.mv rename to vm/stdlib/compiled/latest/stdlib/021_chain_id.mv diff --git a/vm/stdlib/compiled/latest/stdlib/023_bcs_util.mv b/vm/stdlib/compiled/latest/stdlib/022_bcs_util.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/023_bcs_util.mv rename to vm/stdlib/compiled/latest/stdlib/022_bcs_util.mv diff --git a/vm/stdlib/compiled/latest/stdlib/024_account.mv b/vm/stdlib/compiled/latest/stdlib/023_account.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/024_account.mv rename to vm/stdlib/compiled/latest/stdlib/023_account.mv diff --git a/vm/stdlib/compiled/latest/stdlib/025_acl.mv b/vm/stdlib/compiled/latest/stdlib/024_acl.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/025_acl.mv rename to vm/stdlib/compiled/latest/stdlib/024_acl.mv diff --git a/vm/stdlib/compiled/latest/stdlib/026_aggregator.mv b/vm/stdlib/compiled/latest/stdlib/025_aggregator.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/026_aggregator.mv rename to vm/stdlib/compiled/latest/stdlib/025_aggregator.mv diff --git a/vm/stdlib/compiled/latest/stdlib/027_aggregator_factory.mv b/vm/stdlib/compiled/latest/stdlib/026_aggregator_factory.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/027_aggregator_factory.mv rename to vm/stdlib/compiled/latest/stdlib/026_aggregator_factory.mv diff --git a/vm/stdlib/compiled/latest/stdlib/028_aggregator_v2.mv b/vm/stdlib/compiled/latest/stdlib/027_aggregator_v2.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/028_aggregator_v2.mv rename to vm/stdlib/compiled/latest/stdlib/027_aggregator_v2.mv diff --git a/vm/stdlib/compiled/latest/stdlib/029_any.mv b/vm/stdlib/compiled/latest/stdlib/028_any.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/029_any.mv rename to vm/stdlib/compiled/latest/stdlib/028_any.mv diff --git a/vm/stdlib/compiled/latest/stdlib/035_stc_util.mv b/vm/stdlib/compiled/latest/stdlib/029_stc_util.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/035_stc_util.mv rename to vm/stdlib/compiled/latest/stdlib/029_stc_util.mv diff --git a/vm/stdlib/compiled/latest/stdlib/030_starcoin_proof_structured_hash.mv b/vm/stdlib/compiled/latest/stdlib/030_starcoin_proof_structured_hash.mv new file mode 100644 index 0000000000..064b40d530 Binary files /dev/null and b/vm/stdlib/compiled/latest/stdlib/030_starcoin_proof_structured_hash.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/031_starcoin_proof_bit.mv b/vm/stdlib/compiled/latest/stdlib/031_starcoin_proof_bit.mv new file mode 100644 index 0000000000..65b61f8aee Binary files /dev/null and b/vm/stdlib/compiled/latest/stdlib/031_starcoin_proof_bit.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/032_starcoin_proof_verifier.mv b/vm/stdlib/compiled/latest/stdlib/032_starcoin_proof_verifier.mv new file mode 100644 index 0000000000..4ff68cd8c5 Binary files /dev/null and b/vm/stdlib/compiled/latest/stdlib/032_starcoin_proof_verifier.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/069_simple_map.mv b/vm/stdlib/compiled/latest/stdlib/033_simple_map.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/069_simple_map.mv rename to vm/stdlib/compiled/latest/stdlib/033_simple_map.mv diff --git a/vm/stdlib/compiled/latest/stdlib/039_transaction_context.mv b/vm/stdlib/compiled/latest/stdlib/034_transaction_context.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/039_transaction_context.mv rename to vm/stdlib/compiled/latest/stdlib/034_transaction_context.mv diff --git a/vm/stdlib/compiled/latest/stdlib/040_object.mv b/vm/stdlib/compiled/latest/stdlib/035_object.mv similarity index 54% rename from vm/stdlib/compiled/latest/stdlib/040_object.mv rename to vm/stdlib/compiled/latest/stdlib/035_object.mv index 8571e5a2b6..9ce1cdc91d 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/040_object.mv and b/vm/stdlib/compiled/latest/stdlib/035_object.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/041_optional_aggregator.mv b/vm/stdlib/compiled/latest/stdlib/036_optional_aggregator.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/041_optional_aggregator.mv rename to vm/stdlib/compiled/latest/stdlib/036_optional_aggregator.mv diff --git a/vm/stdlib/compiled/latest/stdlib/042_function_info.mv b/vm/stdlib/compiled/latest/stdlib/037_function_info.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/042_function_info.mv rename to vm/stdlib/compiled/latest/stdlib/037_function_info.mv diff --git a/vm/stdlib/compiled/latest/stdlib/038_fungible_asset.mv b/vm/stdlib/compiled/latest/stdlib/038_fungible_asset.mv new file mode 100644 index 0000000000..a4b082b823 Binary files /dev/null and b/vm/stdlib/compiled/latest/stdlib/038_fungible_asset.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/044_dispatchable_fungible_asset.mv b/vm/stdlib/compiled/latest/stdlib/039_dispatchable_fungible_asset.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/044_dispatchable_fungible_asset.mv rename to vm/stdlib/compiled/latest/stdlib/039_dispatchable_fungible_asset.mv diff --git a/vm/stdlib/compiled/latest/stdlib/040_primary_fungible_store.mv b/vm/stdlib/compiled/latest/stdlib/040_primary_fungible_store.mv new file mode 100644 index 0000000000..38301f0462 Binary files /dev/null and b/vm/stdlib/compiled/latest/stdlib/040_primary_fungible_store.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/041_coin.mv b/vm/stdlib/compiled/latest/stdlib/041_coin.mv new file mode 100644 index 0000000000..e7a9efc1ba Binary files /dev/null and b/vm/stdlib/compiled/latest/stdlib/041_coin.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/042_asset_mapping.mv b/vm/stdlib/compiled/latest/stdlib/042_asset_mapping.mv new file mode 100644 index 0000000000..2140f83c4a Binary files /dev/null and b/vm/stdlib/compiled/latest/stdlib/042_asset_mapping.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/043_fungible_asset.mv b/vm/stdlib/compiled/latest/stdlib/043_fungible_asset.mv deleted file mode 100644 index f4409cc30d..0000000000 Binary files a/vm/stdlib/compiled/latest/stdlib/043_fungible_asset.mv and /dev/null differ diff --git a/vm/stdlib/compiled/latest/stdlib/030_table_with_length.mv b/vm/stdlib/compiled/latest/stdlib/043_table_with_length.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/030_table_with_length.mv rename to vm/stdlib/compiled/latest/stdlib/043_table_with_length.mv diff --git a/vm/stdlib/compiled/latest/stdlib/031_big_vector.mv b/vm/stdlib/compiled/latest/stdlib/044_big_vector.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/031_big_vector.mv rename to vm/stdlib/compiled/latest/stdlib/044_big_vector.mv diff --git a/vm/stdlib/compiled/latest/stdlib/032_bit_vector.mv b/vm/stdlib/compiled/latest/stdlib/045_bit_vector.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/032_bit_vector.mv rename to vm/stdlib/compiled/latest/stdlib/045_bit_vector.mv diff --git a/vm/stdlib/compiled/latest/stdlib/045_primary_fungible_store.mv b/vm/stdlib/compiled/latest/stdlib/045_primary_fungible_store.mv deleted file mode 100644 index ff43b9619a..0000000000 Binary files a/vm/stdlib/compiled/latest/stdlib/045_primary_fungible_store.mv and /dev/null differ diff --git a/vm/stdlib/compiled/latest/stdlib/033_chain_status.mv b/vm/stdlib/compiled/latest/stdlib/046_chain_status.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/033_chain_status.mv rename to vm/stdlib/compiled/latest/stdlib/046_chain_status.mv diff --git a/vm/stdlib/compiled/latest/stdlib/046_coin.mv b/vm/stdlib/compiled/latest/stdlib/046_coin.mv deleted file mode 100644 index 7502ce6b61..0000000000 Binary files a/vm/stdlib/compiled/latest/stdlib/046_coin.mv and /dev/null differ diff --git a/vm/stdlib/compiled/latest/stdlib/034_timestamp.mv b/vm/stdlib/compiled/latest/stdlib/047_timestamp.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/034_timestamp.mv rename to vm/stdlib/compiled/latest/stdlib/047_timestamp.mv diff --git a/vm/stdlib/compiled/latest/stdlib/036_fixed_point64.mv b/vm/stdlib/compiled/latest/stdlib/048_fixed_point64.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/036_fixed_point64.mv rename to vm/stdlib/compiled/latest/stdlib/048_fixed_point64.mv diff --git a/vm/stdlib/compiled/latest/stdlib/037_fixed_point32.mv b/vm/stdlib/compiled/latest/stdlib/049_fixed_point32.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/037_fixed_point32.mv rename to vm/stdlib/compiled/latest/stdlib/049_fixed_point32.mv diff --git a/vm/stdlib/compiled/latest/stdlib/038_math128.mv b/vm/stdlib/compiled/latest/stdlib/050_math128.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/038_math128.mv rename to vm/stdlib/compiled/latest/stdlib/050_math128.mv diff --git a/vm/stdlib/compiled/latest/stdlib/047_treasury.mv b/vm/stdlib/compiled/latest/stdlib/051_treasury.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/047_treasury.mv rename to vm/stdlib/compiled/latest/stdlib/051_treasury.mv diff --git a/vm/stdlib/compiled/latest/stdlib/048_starcoin_coin.mv b/vm/stdlib/compiled/latest/stdlib/052_starcoin_coin.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/048_starcoin_coin.mv rename to vm/stdlib/compiled/latest/stdlib/052_starcoin_coin.mv diff --git a/vm/stdlib/compiled/latest/stdlib/049_on_chain_config.mv b/vm/stdlib/compiled/latest/stdlib/053_on_chain_config.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/049_on_chain_config.mv rename to vm/stdlib/compiled/latest/stdlib/053_on_chain_config.mv diff --git a/vm/stdlib/compiled/latest/stdlib/050_dao.mv b/vm/stdlib/compiled/latest/stdlib/054_dao.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/050_dao.mv rename to vm/stdlib/compiled/latest/stdlib/054_dao.mv diff --git a/vm/stdlib/compiled/latest/stdlib/051_dao_treasury_withdraw_proposal.mv b/vm/stdlib/compiled/latest/stdlib/055_dao_treasury_withdraw_proposal.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/051_dao_treasury_withdraw_proposal.mv rename to vm/stdlib/compiled/latest/stdlib/055_dao_treasury_withdraw_proposal.mv diff --git a/vm/stdlib/compiled/latest/stdlib/052_block_reward_config.mv b/vm/stdlib/compiled/latest/stdlib/056_block_reward_config.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/052_block_reward_config.mv rename to vm/stdlib/compiled/latest/stdlib/056_block_reward_config.mv diff --git a/vm/stdlib/compiled/latest/stdlib/053_block_reward.mv b/vm/stdlib/compiled/latest/stdlib/057_block_reward.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/053_block_reward.mv rename to vm/stdlib/compiled/latest/stdlib/057_block_reward.mv diff --git a/vm/stdlib/compiled/latest/stdlib/054_bls12381.mv b/vm/stdlib/compiled/latest/stdlib/058_bls12381.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/054_bls12381.mv rename to vm/stdlib/compiled/latest/stdlib/058_bls12381.mv diff --git a/vm/stdlib/compiled/latest/stdlib/055_capability.mv b/vm/stdlib/compiled/latest/stdlib/059_capability.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/055_capability.mv rename to vm/stdlib/compiled/latest/stdlib/059_capability.mv diff --git a/vm/stdlib/compiled/latest/stdlib/056_royalty.mv b/vm/stdlib/compiled/latest/stdlib/060_royalty.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/056_royalty.mv rename to vm/stdlib/compiled/latest/stdlib/060_royalty.mv diff --git a/vm/stdlib/compiled/latest/stdlib/057_collection.mv b/vm/stdlib/compiled/latest/stdlib/061_collection.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/057_collection.mv rename to vm/stdlib/compiled/latest/stdlib/061_collection.mv diff --git a/vm/stdlib/compiled/latest/stdlib/058_comparator.mv b/vm/stdlib/compiled/latest/stdlib/062_comparator.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/058_comparator.mv rename to vm/stdlib/compiled/latest/stdlib/062_comparator.mv diff --git a/vm/stdlib/compiled/latest/stdlib/059_consensus_config.mv b/vm/stdlib/compiled/latest/stdlib/063_consensus_config.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/059_consensus_config.mv rename to vm/stdlib/compiled/latest/stdlib/063_consensus_config.mv diff --git a/vm/stdlib/compiled/latest/stdlib/060_consensus_strategy.mv b/vm/stdlib/compiled/latest/stdlib/064_consensus_strategy.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/060_consensus_strategy.mv rename to vm/stdlib/compiled/latest/stdlib/064_consensus_strategy.mv diff --git a/vm/stdlib/compiled/latest/stdlib/061_copyable_any.mv b/vm/stdlib/compiled/latest/stdlib/065_copyable_any.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/061_copyable_any.mv rename to vm/stdlib/compiled/latest/stdlib/065_copyable_any.mv diff --git a/vm/stdlib/compiled/latest/stdlib/062_crypto_algebra.mv b/vm/stdlib/compiled/latest/stdlib/066_crypto_algebra.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/062_crypto_algebra.mv rename to vm/stdlib/compiled/latest/stdlib/066_crypto_algebra.mv diff --git a/vm/stdlib/compiled/latest/stdlib/063_dao_features_proposal.mv b/vm/stdlib/compiled/latest/stdlib/067_dao_features_proposal.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/063_dao_features_proposal.mv rename to vm/stdlib/compiled/latest/stdlib/067_dao_features_proposal.mv diff --git a/vm/stdlib/compiled/latest/stdlib/064_dao_modify_config_proposal.mv b/vm/stdlib/compiled/latest/stdlib/068_dao_modify_config_proposal.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/064_dao_modify_config_proposal.mv rename to vm/stdlib/compiled/latest/stdlib/068_dao_modify_config_proposal.mv diff --git a/vm/stdlib/compiled/latest/stdlib/065_stc_version.mv b/vm/stdlib/compiled/latest/stdlib/069_stc_version.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/065_stc_version.mv rename to vm/stdlib/compiled/latest/stdlib/069_stc_version.mv diff --git a/vm/stdlib/compiled/latest/stdlib/066_stc_transaction_package_validation.mv b/vm/stdlib/compiled/latest/stdlib/070_stc_transaction_package_validation.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/066_stc_transaction_package_validation.mv rename to vm/stdlib/compiled/latest/stdlib/070_stc_transaction_package_validation.mv diff --git a/vm/stdlib/compiled/latest/stdlib/067_dao_upgrade_module_proposal.mv b/vm/stdlib/compiled/latest/stdlib/071_dao_upgrade_module_proposal.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/067_dao_upgrade_module_proposal.mv rename to vm/stdlib/compiled/latest/stdlib/071_dao_upgrade_module_proposal.mv diff --git a/vm/stdlib/compiled/latest/stdlib/068_dao_vote_scripts.mv b/vm/stdlib/compiled/latest/stdlib/072_dao_vote_scripts.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/068_dao_vote_scripts.mv rename to vm/stdlib/compiled/latest/stdlib/072_dao_vote_scripts.mv diff --git a/vm/stdlib/compiled/latest/stdlib/070_reserved_accounts_signer.mv b/vm/stdlib/compiled/latest/stdlib/073_reserved_accounts_signer.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/070_reserved_accounts_signer.mv rename to vm/stdlib/compiled/latest/stdlib/073_reserved_accounts_signer.mv diff --git a/vm/stdlib/compiled/latest/stdlib/071_oracle.mv b/vm/stdlib/compiled/latest/stdlib/074_oracle.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/071_oracle.mv rename to vm/stdlib/compiled/latest/stdlib/074_oracle.mv diff --git a/vm/stdlib/compiled/latest/stdlib/072_oracle_price.mv b/vm/stdlib/compiled/latest/stdlib/075_oracle_price.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/072_oracle_price.mv rename to vm/stdlib/compiled/latest/stdlib/075_oracle_price.mv diff --git a/vm/stdlib/compiled/latest/stdlib/073_easy_gas.mv b/vm/stdlib/compiled/latest/stdlib/076_easy_gas.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/073_easy_gas.mv rename to vm/stdlib/compiled/latest/stdlib/076_easy_gas.mv diff --git a/vm/stdlib/compiled/latest/stdlib/074_easy_gas_script.mv b/vm/stdlib/compiled/latest/stdlib/077_easy_gas_script.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/074_easy_gas_script.mv rename to vm/stdlib/compiled/latest/stdlib/077_easy_gas_script.mv diff --git a/vm/stdlib/compiled/latest/stdlib/078_empty_scripts.mv b/vm/stdlib/compiled/latest/stdlib/078_empty_scripts.mv new file mode 100644 index 0000000000..6776a8ac2b Binary files /dev/null and b/vm/stdlib/compiled/latest/stdlib/078_empty_scripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/075_epoch.mv b/vm/stdlib/compiled/latest/stdlib/079_epoch.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/075_epoch.mv rename to vm/stdlib/compiled/latest/stdlib/079_epoch.mv diff --git a/vm/stdlib/compiled/latest/stdlib/076_flexi_dag_config.mv b/vm/stdlib/compiled/latest/stdlib/080_flexi_dag_config.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/076_flexi_dag_config.mv rename to vm/stdlib/compiled/latest/stdlib/080_flexi_dag_config.mv diff --git a/vm/stdlib/compiled/latest/stdlib/077_managed_coin.mv b/vm/stdlib/compiled/latest/stdlib/081_managed_coin.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/077_managed_coin.mv rename to vm/stdlib/compiled/latest/stdlib/081_managed_coin.mv diff --git a/vm/stdlib/compiled/latest/stdlib/078_math64.mv b/vm/stdlib/compiled/latest/stdlib/082_math64.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/078_math64.mv rename to vm/stdlib/compiled/latest/stdlib/082_math64.mv diff --git a/vm/stdlib/compiled/latest/stdlib/079_math_fixed.mv b/vm/stdlib/compiled/latest/stdlib/083_math_fixed.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/079_math_fixed.mv rename to vm/stdlib/compiled/latest/stdlib/083_math_fixed.mv diff --git a/vm/stdlib/compiled/latest/stdlib/080_math_fixed64.mv b/vm/stdlib/compiled/latest/stdlib/084_math_fixed64.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/080_math_fixed64.mv rename to vm/stdlib/compiled/latest/stdlib/084_math_fixed64.mv diff --git a/vm/stdlib/compiled/latest/stdlib/081_object_property_map.mv b/vm/stdlib/compiled/latest/stdlib/085_object_property_map.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/081_object_property_map.mv rename to vm/stdlib/compiled/latest/stdlib/085_object_property_map.mv diff --git a/vm/stdlib/compiled/latest/stdlib/082_object_token.mv b/vm/stdlib/compiled/latest/stdlib/086_object_token.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/082_object_token.mv rename to vm/stdlib/compiled/latest/stdlib/086_object_token.mv diff --git a/vm/stdlib/compiled/latest/stdlib/083_on_chain_config_dao.mv b/vm/stdlib/compiled/latest/stdlib/087_on_chain_config_dao.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/083_on_chain_config_dao.mv rename to vm/stdlib/compiled/latest/stdlib/087_on_chain_config_dao.mv diff --git a/vm/stdlib/compiled/latest/stdlib/084_util.mv b/vm/stdlib/compiled/latest/stdlib/088_util.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/084_util.mv rename to vm/stdlib/compiled/latest/stdlib/088_util.mv diff --git a/vm/stdlib/compiled/latest/stdlib/085_vm_config.mv b/vm/stdlib/compiled/latest/stdlib/089_vm_config.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/085_vm_config.mv rename to vm/stdlib/compiled/latest/stdlib/089_vm_config.mv diff --git a/vm/stdlib/compiled/latest/stdlib/086_transaction_publish_option.mv b/vm/stdlib/compiled/latest/stdlib/090_transaction_publish_option.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/086_transaction_publish_option.mv rename to vm/stdlib/compiled/latest/stdlib/090_transaction_publish_option.mv diff --git a/vm/stdlib/compiled/latest/stdlib/087_stc_transaction_timeout_config.mv b/vm/stdlib/compiled/latest/stdlib/091_stc_transaction_timeout_config.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/087_stc_transaction_timeout_config.mv rename to vm/stdlib/compiled/latest/stdlib/091_stc_transaction_timeout_config.mv diff --git a/vm/stdlib/compiled/latest/stdlib/088_stc_language_version.mv b/vm/stdlib/compiled/latest/stdlib/092_stc_language_version.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/088_stc_language_version.mv rename to vm/stdlib/compiled/latest/stdlib/092_stc_language_version.mv diff --git a/vm/stdlib/compiled/latest/stdlib/089_on_chain_config_scripts.mv b/vm/stdlib/compiled/latest/stdlib/093_on_chain_config_scripts.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/089_on_chain_config_scripts.mv rename to vm/stdlib/compiled/latest/stdlib/093_on_chain_config_scripts.mv diff --git a/vm/stdlib/compiled/latest/stdlib/090_oracle_aggregator.mv b/vm/stdlib/compiled/latest/stdlib/094_oracle_aggregator.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/090_oracle_aggregator.mv rename to vm/stdlib/compiled/latest/stdlib/094_oracle_aggregator.mv diff --git a/vm/stdlib/compiled/latest/stdlib/091_oracle_stc_usd.mv b/vm/stdlib/compiled/latest/stdlib/095_oracle_stc_usd.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/091_oracle_stc_usd.mv rename to vm/stdlib/compiled/latest/stdlib/095_oracle_stc_usd.mv diff --git a/vm/stdlib/compiled/latest/stdlib/092_pool_u64.mv b/vm/stdlib/compiled/latest/stdlib/096_pool_u64.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/092_pool_u64.mv rename to vm/stdlib/compiled/latest/stdlib/096_pool_u64.mv diff --git a/vm/stdlib/compiled/latest/stdlib/093_pool_u64_unbound.mv b/vm/stdlib/compiled/latest/stdlib/097_pool_u64_unbound.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/093_pool_u64_unbound.mv rename to vm/stdlib/compiled/latest/stdlib/097_pool_u64_unbound.mv diff --git a/vm/stdlib/compiled/latest/stdlib/094_property_map.mv b/vm/stdlib/compiled/latest/stdlib/098_property_map.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/094_property_map.mv rename to vm/stdlib/compiled/latest/stdlib/098_property_map.mv diff --git a/vm/stdlib/compiled/latest/stdlib/095_starcoin_account.mv b/vm/stdlib/compiled/latest/stdlib/099_starcoin_account.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/095_starcoin_account.mv rename to vm/stdlib/compiled/latest/stdlib/099_starcoin_account.mv diff --git a/vm/stdlib/compiled/latest/stdlib/096_resource_account.mv b/vm/stdlib/compiled/latest/stdlib/100_resource_account.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/096_resource_account.mv rename to vm/stdlib/compiled/latest/stdlib/100_resource_account.mv diff --git a/vm/stdlib/compiled/latest/stdlib/097_ring.mv b/vm/stdlib/compiled/latest/stdlib/101_ring.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/097_ring.mv rename to vm/stdlib/compiled/latest/stdlib/101_ring.mv diff --git a/vm/stdlib/compiled/latest/stdlib/098_ristretto255.mv b/vm/stdlib/compiled/latest/stdlib/102_ristretto255.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/098_ristretto255.mv rename to vm/stdlib/compiled/latest/stdlib/102_ristretto255.mv diff --git a/vm/stdlib/compiled/latest/stdlib/099_ristretto255_pedersen.mv b/vm/stdlib/compiled/latest/stdlib/103_ristretto255_pedersen.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/099_ristretto255_pedersen.mv rename to vm/stdlib/compiled/latest/stdlib/103_ristretto255_pedersen.mv diff --git a/vm/stdlib/compiled/latest/stdlib/100_ristretto255_bulletproofs.mv b/vm/stdlib/compiled/latest/stdlib/104_ristretto255_bulletproofs.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/100_ristretto255_bulletproofs.mv rename to vm/stdlib/compiled/latest/stdlib/104_ristretto255_bulletproofs.mv diff --git a/vm/stdlib/compiled/latest/stdlib/101_ristretto255_elgamal.mv b/vm/stdlib/compiled/latest/stdlib/105_ristretto255_elgamal.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/101_ristretto255_elgamal.mv rename to vm/stdlib/compiled/latest/stdlib/105_ristretto255_elgamal.mv diff --git a/vm/stdlib/compiled/latest/stdlib/102_secp256k1.mv b/vm/stdlib/compiled/latest/stdlib/106_secp256k1.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/102_secp256k1.mv rename to vm/stdlib/compiled/latest/stdlib/106_secp256k1.mv diff --git a/vm/stdlib/compiled/latest/stdlib/103_starcoin_hash.mv b/vm/stdlib/compiled/latest/stdlib/107_starcoin_hash.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/103_starcoin_hash.mv rename to vm/stdlib/compiled/latest/stdlib/107_starcoin_hash.mv diff --git a/vm/stdlib/compiled/latest/stdlib/104_smart_table.mv b/vm/stdlib/compiled/latest/stdlib/108_smart_table.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/104_smart_table.mv rename to vm/stdlib/compiled/latest/stdlib/108_smart_table.mv diff --git a/vm/stdlib/compiled/latest/stdlib/105_smart_vector.mv b/vm/stdlib/compiled/latest/stdlib/109_smart_vector.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/105_smart_vector.mv rename to vm/stdlib/compiled/latest/stdlib/109_smart_vector.mv diff --git a/vm/stdlib/compiled/latest/stdlib/109_stc_genesis.mv b/vm/stdlib/compiled/latest/stdlib/109_stc_genesis.mv deleted file mode 100644 index 2ac2e089ee..0000000000 Binary files a/vm/stdlib/compiled/latest/stdlib/109_stc_genesis.mv and /dev/null differ diff --git a/vm/stdlib/compiled/latest/stdlib/106_starcoin_token.mv b/vm/stdlib/compiled/latest/stdlib/110_starcoin_token.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/106_starcoin_token.mv rename to vm/stdlib/compiled/latest/stdlib/110_starcoin_token.mv diff --git a/vm/stdlib/compiled/latest/stdlib/107_stc_transaction_fee.mv b/vm/stdlib/compiled/latest/stdlib/111_stc_transaction_fee.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/107_stc_transaction_fee.mv rename to vm/stdlib/compiled/latest/stdlib/111_stc_transaction_fee.mv diff --git a/vm/stdlib/compiled/latest/stdlib/108_stc_block.mv b/vm/stdlib/compiled/latest/stdlib/112_stc_block.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/108_stc_block.mv rename to vm/stdlib/compiled/latest/stdlib/112_stc_block.mv diff --git a/vm/stdlib/compiled/latest/stdlib/112_stc_transaction_validation.mv b/vm/stdlib/compiled/latest/stdlib/112_stc_transaction_validation.mv deleted file mode 100644 index df589bf321..0000000000 Binary files a/vm/stdlib/compiled/latest/stdlib/112_stc_transaction_validation.mv and /dev/null differ diff --git a/vm/stdlib/compiled/latest/stdlib/113_stc_genesis.mv b/vm/stdlib/compiled/latest/stdlib/113_stc_genesis.mv new file mode 100644 index 0000000000..21b5c1a350 Binary files /dev/null and b/vm/stdlib/compiled/latest/stdlib/113_stc_genesis.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/110_stc_offer.mv b/vm/stdlib/compiled/latest/stdlib/114_stc_offer.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/110_stc_offer.mv rename to vm/stdlib/compiled/latest/stdlib/114_stc_offer.mv diff --git a/vm/stdlib/compiled/latest/stdlib/111_stc_transaction_timeout.mv b/vm/stdlib/compiled/latest/stdlib/115_stc_transaction_timeout.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/111_stc_transaction_timeout.mv rename to vm/stdlib/compiled/latest/stdlib/115_stc_transaction_timeout.mv diff --git a/vm/stdlib/compiled/latest/stdlib/116_stc_transaction_validation.mv b/vm/stdlib/compiled/latest/stdlib/116_stc_transaction_validation.mv new file mode 100644 index 0000000000..7e643369ca Binary files /dev/null and b/vm/stdlib/compiled/latest/stdlib/116_stc_transaction_validation.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/113_token_event_store.mv b/vm/stdlib/compiled/latest/stdlib/117_token_event_store.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/113_token_event_store.mv rename to vm/stdlib/compiled/latest/stdlib/117_token_event_store.mv diff --git a/vm/stdlib/compiled/latest/stdlib/114_token.mv b/vm/stdlib/compiled/latest/stdlib/118_token.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/114_token.mv rename to vm/stdlib/compiled/latest/stdlib/118_token.mv diff --git a/vm/stdlib/compiled/latest/stdlib/115_token_coin_swap.mv b/vm/stdlib/compiled/latest/stdlib/119_token_coin_swap.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/115_token_coin_swap.mv rename to vm/stdlib/compiled/latest/stdlib/119_token_coin_swap.mv diff --git a/vm/stdlib/compiled/latest/stdlib/116_token_transfers.mv b/vm/stdlib/compiled/latest/stdlib/120_token_transfers.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/116_token_transfers.mv rename to vm/stdlib/compiled/latest/stdlib/120_token_transfers.mv diff --git a/vm/stdlib/compiled/latest/stdlib/117_transfer_scripts.mv b/vm/stdlib/compiled/latest/stdlib/121_transfer_scripts.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/117_transfer_scripts.mv rename to vm/stdlib/compiled/latest/stdlib/121_transfer_scripts.mv diff --git a/vm/stdlib/compiled/latest/stdlib/118_treasury_scripts.mv b/vm/stdlib/compiled/latest/stdlib/122_treasury_scripts.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/118_treasury_scripts.mv rename to vm/stdlib/compiled/latest/stdlib/122_treasury_scripts.mv diff --git a/vm/transaction-builder/src/lib.rs b/vm/transaction-builder/src/lib.rs index 48ae9483b7..a9ab279f6b 100644 --- a/vm/transaction-builder/src/lib.rs +++ b/vm/transaction-builder/src/lib.rs @@ -6,6 +6,7 @@ use std::convert::TryInto; use anyhow::Result; use starcoin_crypto::{hash::PlainCryptoHash, HashValue}; +use starcoin_cached_packages::starcoin_stdlib::empty_scripts_test_metadata; use starcoin_cached_packages::{ starcoin_framework_sdk_builder::{empty_scripts_empty_script, stc_genesis_initialize}, starcoin_stdlib::{ @@ -13,7 +14,6 @@ use starcoin_cached_packages::{ transfer_scripts_peer_to_peer, transfer_scripts_peer_to_peer_v2, }, }; - use starcoin_config::{genesis_config::G_TOTAL_STC_AMOUNT, ChainNetwork}; use starcoin_types::account::Account; use starcoin_vm_types::on_chain_config::Features; @@ -395,6 +395,7 @@ pub fn build_init_script(net: &ChainNetwork) -> EntryFunction { // flexidag effective height genesis_config.dag_effective_height, Features::default().features, + genesis_config.asset_mapping_root_hash.to_vec(), ); match payload { @@ -566,6 +567,10 @@ pub fn empty_txn_payload() -> TransactionPayload { empty_scripts_empty_script() } +pub fn empty_test_metadata() -> TransactionPayload { + empty_scripts_test_metadata() +} + pub fn build_signed_empty_txn( user_address: AccountAddress, prikey: &AccountPrivateKey, diff --git a/vm/types/src/account_config/resources/balance.rs b/vm/types/src/account_config/resources/balance.rs deleted file mode 100644 index b0b297546f..0000000000 --- a/vm/types/src/account_config/resources/balance.rs +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// SPDX-License-Identifier: Apache-2.0 - -use crate::access_path::DataPath; -use crate::event::EventHandle; -use crate::token::token_code::TokenCode; -use crate::{ - access_path::AccessPath, - account_config::constants::{stc_type_tag, CORE_CODE_ADDRESS}, -}; -use move_core_types::ident_str; -use move_core_types::identifier::{IdentStr, Identifier}; -use move_core_types::language_storage::{StructTag, TypeTag}; -use move_core_types::move_resource::{MoveResource, MoveStructType}; -use serde::{Deserialize, Serialize}; - -/// The balance resource held under an account. -#[derive(Debug, Serialize, Deserialize)] -pub struct BalanceResource { - coin: u64, - frozen: bool, - deposit_events: EventHandle, - withdraw_events: EventHandle, -} - -impl BalanceResource { - pub fn new(coin: u128, deposit_events: EventHandle, withdraw_events: EventHandle) -> Self { - Self { - coin: coin as u64, - frozen: false, - deposit_events, - withdraw_events, - } - } - - pub fn token(&self) -> u128 { - self.coin as u128 - } - - // TODO/XXX: remove this once the MoveResource trait allows type arguments to `struct_tag`. - pub fn struct_tag_for_token(token_type_tag: StructTag) -> StructTag { - StructTag { - address: CORE_CODE_ADDRESS, - name: Self::struct_identifier(), - module: Self::module_identifier(), - type_args: vec![TypeTag::Struct(Box::new(token_type_tag))], - } - } - - // TODO: remove this once the MoveResource trait allows type arguments to `resource_path`. - pub fn access_path_for(token_type_tag: StructTag) -> DataPath { - AccessPath::resource_data_path(Self::struct_tag_for_token(token_type_tag)) - } - - /// Get token code from Balance StructTag, return None if struct tag is not a valid Balance StructTag - pub fn token_code(struct_tag: &StructTag) -> Option { - if struct_tag.address == CORE_CODE_ADDRESS - && struct_tag.module == Identifier::from(Self::MODULE_NAME) - && struct_tag.name == Identifier::from(Self::STRUCT_NAME) - { - if let Some(TypeTag::Struct(token_tag)) = struct_tag.type_args.first() { - Some((*(token_tag.clone())).into()) - } else { - None - } - } else { - None - } - } -} - -impl MoveStructType for BalanceResource { - const MODULE_NAME: &'static IdentStr = ident_str!("coin"); - const STRUCT_NAME: &'static IdentStr = ident_str!("CoinStore"); - fn type_args() -> Vec { - vec![stc_type_tag()] - } -} - -impl MoveResource for BalanceResource {} diff --git a/vm/types/src/account_config/resources/coin_store.rs b/vm/types/src/account_config/resources/coin_store.rs index c435fcd6c6..dff99cfd53 100644 --- a/vm/types/src/account_config/resources/coin_store.rs +++ b/vm/types/src/account_config/resources/coin_store.rs @@ -1,16 +1,18 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::{event::EventHandle, utility_coin::STARCOIN_COIN_TYPE}; use move_core_types::{ ident_str, - identifier::IdentStr, - language_storage::TypeTag, + identifier::{IdentStr, Identifier}, + language_storage::{StructTag, TypeTag, CORE_CODE_ADDRESS}, move_resource::{MoveResource, MoveStructType}, }; - use serde::{Deserialize, Serialize}; +use crate::access_path::{AccessPath, DataPath}; +use crate::account_config::token_code::TokenCode; +use crate::{event::EventHandle, utility_coin::STARCOIN_COIN_TYPE}; + /// The balance resource held under an account. #[derive(Debug, Serialize, Deserialize)] pub struct CoinStoreResource { @@ -50,6 +52,37 @@ impl CoinStoreResource { pub fn withdraw_events(&self) -> &EventHandle { &self.withdraw_events } + + // TODO/XXX: remove this once the MoveResource trait allows type arguments to `struct_tag`. + pub fn struct_tag_for_token(token_type_tag: StructTag) -> StructTag { + StructTag { + address: CORE_CODE_ADDRESS, + name: Self::struct_identifier(), + module: Self::module_identifier(), + type_args: vec![TypeTag::Struct(Box::new(token_type_tag))], + } + } + + // TODO: remove this once the MoveResource trait allows type arguments to `resource_path`. + pub fn access_path_for(token_type_tag: StructTag) -> DataPath { + AccessPath::resource_data_path(Self::struct_tag_for_token(token_type_tag)) + } + + /// Get token code from Balance StructTag, return None if struct tag is not a valid Balance StructTag + pub fn token_code(struct_tag: &StructTag) -> Option { + if struct_tag.address == CORE_CODE_ADDRESS + && struct_tag.module == Identifier::from(Self::MODULE_NAME) + && struct_tag.name == Identifier::from(Self::STRUCT_NAME) + { + if let Some(TypeTag::Struct(token_tag)) = struct_tag.type_args.first() { + Some((*(token_tag.clone())).into()) + } else { + None + } + } else { + None + } + } } impl MoveStructType for CoinStoreResource { diff --git a/vm/types/src/account_config/resources/fungible_store.rs b/vm/types/src/account_config/resources/fungible_store.rs new file mode 100644 index 0000000000..d1a1d2d7d2 --- /dev/null +++ b/vm/types/src/account_config/resources/fungible_store.rs @@ -0,0 +1,92 @@ +// Copyright © Starcoin Foundation +// SPDX-License-Identifier: Apache-2.0 + +use move_core_types::language_storage::{StructTag, CORE_CODE_ADDRESS}; +use move_core_types::{ + account_address::AccountAddress, + ident_str, + identifier::IdentStr, + move_resource::{MoveResource, MoveStructType}, +}; + +#[cfg(any(test, feature = "fuzzing"))] +use proptest_derive::Arbitrary; +use serde::{Deserialize, Serialize}; + +pub fn primary_store(address: &AccountAddress, meta_address: &AccountAddress) -> AccountAddress { + let mut bytes = address.to_vec(); + // bytes.append(&mut AccountAddress::TEN.to_vec()); + bytes.append(&mut meta_address.to_vec()); + bytes.push(0xFC); + let hash_vec = starcoin_crypto::hash::HashValue::sha3_256_of(&bytes).to_vec(); + let address_bytes: [u8; AccountAddress::LENGTH] = hash_vec[16..] + .try_into() + .expect("Slice with incorrect length"); + AccountAddress::from_bytes(address_bytes).unwrap() +} +/// The balance resource held under an account. +#[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))] +pub struct FungibleStoreResource { + metadata: AccountAddress, + balance: u64, + frozen: bool, +} + +impl FungibleStoreResource { + pub fn new(metadata: AccountAddress, balance: u64, frozen: bool) -> Self { + Self { + metadata, + balance, + frozen, + } + } + + pub fn metadata(&self) -> AccountAddress { + self.metadata + } + + pub fn balance(&self) -> u64 { + self.balance + } + + pub fn frozen(&self) -> bool { + self.frozen + } + + // TODO/XXX: remove this once the MoveResource trait allows type arguments to `struct_tag`. + pub fn struct_tag_for_resource() -> StructTag { + StructTag { + address: CORE_CODE_ADDRESS, + name: Self::struct_identifier(), + module: Self::module_identifier(), + type_args: vec![], + } + } + + // TODO: remove this once the MoveResource trait allows type arguments to `resource_path`. + // pub fn access_path_for(token_type_tag: StructTag) -> DataPath { + // AccessPath::resource_data_path(Self::struct_tag_for_token(token_type_tag)) + // } +} + +impl MoveStructType for FungibleStoreResource { + const MODULE_NAME: &'static IdentStr = ident_str!("fungible_asset"); + const STRUCT_NAME: &'static IdentStr = ident_str!("FungibleStore"); +} + +impl MoveResource for FungibleStoreResource {} + +#[test] +fn test_compare_primary_store_address() -> anyhow::Result<()> { + let primary_store_addr = primary_store( + &AccountAddress::from_hex_literal("0xd0c5a06ae6100ce115cad1600fe59e96")?, + &AccountAddress::ONE, + ); + assert_eq!( + primary_store_addr, + AccountAddress::from_hex_literal("0x786d516a2228196dff48bf39a4b085f0")?, + "Not expect address" + ); + Ok(()) +} diff --git a/vm/types/src/account_config/resources/mod.rs b/vm/types/src/account_config/resources/mod.rs index 79278c8828..5a4128da21 100644 --- a/vm/types/src/account_config/resources/mod.rs +++ b/vm/types/src/account_config/resources/mod.rs @@ -3,18 +3,17 @@ mod account; pub mod auto_accept_token; -mod balance; pub mod coin_store; +pub mod fungible_store; + mod key_rotation_capability; mod module_upgrade_strategy; mod object; -mod withdraw_capability; pub use crate::token::token_info::*; pub use account::*; -pub use balance::*; pub use coin_store::*; +pub use fungible_store::*; pub use key_rotation_capability::*; pub use module_upgrade_strategy::*; pub use object::ObjectGroupResource; -pub use withdraw_capability::*; diff --git a/vm/types/src/account_config/resources/withdraw_capability.rs b/vm/types/src/account_config/resources/withdraw_capability.rs deleted file mode 100644 index d5fff4ea3d..0000000000 --- a/vm/types/src/account_config/resources/withdraw_capability.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// SPDX-License-Identifier: Apache-2.0 - -use crate::{account_address::AccountAddress, account_config::constants::ACCOUNT_MODULE_NAME}; -use move_core_types::ident_str; -use move_core_types::identifier::IdentStr; -use move_core_types::move_resource::{MoveResource, MoveStructType}; -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Serialize, Deserialize)] -pub struct WithdrawCapabilityResource { - account_address: AccountAddress, -} - -impl WithdrawCapabilityResource { - pub fn account_address(&self) -> &AccountAddress { - &self.account_address - } -} - -impl MoveStructType for WithdrawCapabilityResource { - const MODULE_NAME: &'static IdentStr = ident_str!(ACCOUNT_MODULE_NAME); - const STRUCT_NAME: &'static IdentStr = ident_str!("WithdrawCapability"); -} - -impl MoveResource for WithdrawCapabilityResource {} diff --git a/vm/types/src/on_chain_config/starcoin_features.rs b/vm/types/src/on_chain_config/starcoin_features.rs index 4e01bedd23..4ba41de122 100644 --- a/vm/types/src/on_chain_config/starcoin_features.rs +++ b/vm/types/src/on_chain_config/starcoin_features.rs @@ -113,7 +113,7 @@ impl FeatureFlag { FeatureFlag::TRANSACTION_CONTEXT_EXTENSION, FeatureFlag::COIN_TO_FUNGIBLE_ASSET_MIGRATION, FeatureFlag::DISPATCHABLE_FUNGIBLE_ASSET, - //FeatureFlag::NEW_ACCOUNTS_DEFAULT_TO_FA_STC_STORE, + FeatureFlag::NEW_ACCOUNTS_DEFAULT_TO_FA_STC_STORE, ] } } diff --git a/vm/types/src/state_view.rs b/vm/types/src/state_view.rs index 95f15fcd3d..cb3a9c2e35 100644 --- a/vm/types/src/state_view.rs +++ b/vm/types/src/state_view.rs @@ -8,12 +8,11 @@ //! This crate defines [`trait StateView`](StateView). -use crate::state_store::state_key::StateKey; -use crate::state_store::StateView; +use crate::account_config::{fungible_store, ObjectGroupResource}; use crate::{ account_config::{ - genesis_address, token_code::TokenCode, AccountResource, BalanceResource, TokenInfo, - G_STC_TOKEN_CODE, + genesis_address, token_code::TokenCode, AccountResource, CoinStoreResource, + FungibleStoreResource, TokenInfo, G_STC_TOKEN_CODE, }, genesis_config::ChainId, move_resource::MoveResource, @@ -23,13 +22,17 @@ use crate::{ BlockMetadata, Epoch, EpochData, EpochInfo, Treasury, }, sips::SIP, + state_store::{state_key::StateKey, StateView}, }; use anyhow::{format_err, Result}; use bytes::Bytes; +use log::warn; +use move_core_types::move_resource::MoveStructType; use move_core_types::{ account_address::AccountAddress, language_storage::{ModuleId, StructTag}, }; +use std::collections::BTreeMap; impl StateReaderExt for T where T: StateView {} @@ -53,6 +56,23 @@ pub trait StateReaderExt: StateView { Ok(rsrc_bytes) } + // todo(simon): remove me for performance reason + fn get_resource_from_group( + &self, + group_key: &StateKey, + resource_tag: &StructTag, + ) -> Result> { + Ok( + if let Some(group_data_blob) = self.get_state_value_bytes(group_key)? { + let group_data = + bcs_ext::from_bytes::>(&group_data_blob)?; + group_data.get(resource_tag).cloned() + } else { + None + }, + ) + } + fn get_resource_type_bytes(&self, address: AccountAddress) -> Result where R: MoveResource, @@ -105,20 +125,41 @@ pub trait StateReaderExt: StateView { /// Get balance by address and coin type fn get_balance_by_type(&self, address: AccountAddress, type_tag: StructTag) -> Result { - let rsrc_bytes = self - .get_state_value_bytes(&StateKey::resource( - &address, - &BalanceResource::struct_tag_for_token(type_tag.clone()), - )?)? - .ok_or_else(|| { - format_err!( - "BalanceResource not exists at address:{} for type tag:{}", - address, - type_tag - ) - })?; - let rsrc = bcs_ext::from_bytes::(&rsrc_bytes)?; - Ok(rsrc.token()) + // Get from coin store + let coin_balance = match self.get_state_value_bytes(&StateKey::resource( + &address, + &CoinStoreResource::struct_tag_for_token(type_tag.clone()), + )?)? { + Some(bytes) => bcs_ext::from_bytes::(&bytes)?.coin() as u128, + None => { + warn!( + "CoinStoreResource not exists at address:{} for type tag:{}", + address, type_tag + ); + 0 + } + }; + + let primary_store_address = fungible_store::primary_store(&address, &type_tag.address); + // Get from coin store + let object_group_tag = ObjectGroupResource::struct_tag(); + let fungible_store_tag = FungibleStoreResource::struct_tag_for_resource(); + let fungible_store_group_key = + StateKey::resource_group(&primary_store_address, &object_group_tag); + + let fungible_balance = match self + .get_resource_from_group(&fungible_store_group_key, &fungible_store_tag)? + { + Some(bytes) => bcs_ext::from_bytes::(&bytes)?.balance() as u128, + None => { + warn!( + "FungibleStoreResource not exists at address:{:?} for type tag:{:?}", + primary_store_address, fungible_store_group_key + ); + 0 + } + }; + Ok(coin_balance + fungible_balance) } fn get_balance_by_token_code( diff --git a/vm/types/src/token/stc.rs b/vm/types/src/token/stc.rs index 12c9f219d8..c2d6bf6aeb 100644 --- a/vm/types/src/token/stc.rs +++ b/vm/types/src/token/stc.rs @@ -22,12 +22,16 @@ pub static G_STC_TOKEN_CODE: Lazy = Lazy::new(|| { static G_STC_IDENTIFIER: Lazy = Lazy::new(|| Identifier::new(STC_NAME).unwrap()); pub fn stc_type_tag() -> TypeTag { - TypeTag::Struct(Box::new(StructTag { + TypeTag::Struct(Box::new(stc_struct_tag())) +} + +pub fn stc_struct_tag() -> StructTag { + StructTag { address: CORE_CODE_ADDRESS, module: Identifier::new("starcoin_coin").unwrap(), name: G_STC_IDENTIFIER.clone(), type_args: vec![], - })) + } } pub const SYMBOL_NANOSTC: &str = "nanoSTC"; diff --git a/vm/types/src/transaction/package.rs b/vm/types/src/transaction/package.rs index 52eac11b3e..1838663f48 100644 --- a/vm/types/src/transaction/package.rs +++ b/vm/types/src/transaction/package.rs @@ -70,15 +70,15 @@ impl Package { } fn check_module_address( - _package_address: &AccountAddress, - _module_address: &AccountAddress, + package_address: &AccountAddress, + module_address: &AccountAddress, ) -> Result<()> { - //ensure!( - // package_address == module_address, - // "module's address ({:?}) not same as package module address {:?}", - // module_address, - // package_address, - //); + ensure!( + package_address == module_address, + "module's address ({:?}) not same as package module address {:?}", + module_address, + package_address, + ); Ok(()) } diff --git a/vm/vm-runtime/src/data_cache.rs b/vm/vm-runtime/src/data_cache.rs index 2a25732626..926eb55458 100644 --- a/vm/vm-runtime/src/data_cache.rs +++ b/vm/vm-runtime/src/data_cache.rs @@ -40,7 +40,19 @@ pub fn get_resource_group_member_from_metadata( struct_tag: &StructTag, metadata: &[Metadata], ) -> Option { + // eprintln!( + // "get_resource_group_member_from_metadata {} origin metadata count {}", + // struct_tag, + // metadata.len() + // ); + if metadata.is_empty() && struct_tag.name.as_ident_str().as_str() == "ObjectCore" { + panic!("let's see the backtrace"); + } let metadata = starcoin_framework::get_metadata(metadata)?; + // eprintln!( + // "get_resource_group_member_from_metadata {} metadata struct_attributes {:?}", + // struct_tag, metadata.struct_attributes + // ); metadata .struct_attributes .get(struct_tag.name.as_ident_str().as_str())? diff --git a/vm/vm-runtime/src/move_vm_ext/session.rs b/vm/vm-runtime/src/move_vm_ext/session.rs index 6ad75a19e9..4f285073b3 100644 --- a/vm/vm-runtime/src/move_vm_ext/session.rs +++ b/vm/vm-runtime/src/move_vm_ext/session.rs @@ -309,6 +309,10 @@ impl<'r, 'l> SessionExt<'r, 'l> { get_resource_group_member_from_metadata(&struct_tag, md) }); + // eprintln!( + // "struct_tag: {:?} resource group tag {:?}", + // struct_tag, resource_group_tag + // ); if let Some(resource_group_tag) = resource_group_tag { if resource_groups .entry(resource_group_tag) diff --git a/vm/vm-runtime/src/move_vm_ext/vm.rs b/vm/vm-runtime/src/move_vm_ext/vm.rs index a7454c9521..2ff4f3cabe 100644 --- a/vm/vm-runtime/src/move_vm_ext/vm.rs +++ b/vm/vm-runtime/src/move_vm_ext/vm.rs @@ -23,12 +23,13 @@ use starcoin_vm_types::{ on_chain_config::{Features, TimedFeatureFlag, TimedFeatures, TimedFeaturesBuilder}, }; +use starcoin_framework::natives::transaction_context::NativeTransactionContext; use std::ops::Deref; use std::sync::Arc; pub struct MoveVmExt { inner: MoveVM, - _chain_id: u8, + chain_id: u8, features: Arc, } @@ -37,7 +38,7 @@ impl MoveVmExt { native_gas_parameters: NativeGasParameters, misc_gas_parameters: MiscGasParameters, gas_feature_version: u64, - _chain_id: u8, + chain_id: u8, features: Features, timed_features: TimedFeatures, gas_hook: Option, @@ -65,7 +66,7 @@ impl MoveVmExt { } Ok(Self { inner: WarmVmCache::get_warm_vm(builder, vm_config, resolver)?, - _chain_id, + chain_id, features: Arc::new(features), }) } @@ -131,6 +132,14 @@ impl MoveVmExt { extensions.add(NativeAggregatorContext::new(txn_hash, resolver, resolver)); extensions.add(NativeEventContext::default()); extensions.add(NativeObjectContext::default()); + extensions.add(NativeTransactionContext::new( + txn_hash.to_vec(), + //session_id.into_script_hash(), + vec![1], // TODO(BobOng): [compiler-v2] to confirm the script hash + self.chain_id, + // TODO(BobOng): [compiler-v2] to confirm the user transaction context + None, + )); // The VM code loader has bugs around module upgrade. After a module upgrade, the internal // cache needs to be flushed to work around those bugs.