From fc7a735eb1e0beb58337e8c378c365ae1a66d789 Mon Sep 17 00:00:00 2001 From: Mango Date: Wed, 11 Dec 2024 17:04:36 +0800 Subject: [PATCH] commit devnetv1.0.0 --- .gitignore | 1 + Cargo.lock | 30 +- consensus/config/src/crypto.rs | 4 +- crates/data-transform/src/main.rs | 25 +- ...000000000000000000000000000000000000000001 | Bin 0 -> 6963 bytes ...000000000000000000000000000000000000000002 | Bin 0 -> 57477 bytes ...000000000000000000000000000000000000000003 | Bin 0 -> 41741 bytes ...000000000000000000000000000000000000000004 | Bin 0 -> 9728 bytes crates/mgo-framework-snapshot/manifest.json | 9 + crates/mgo-framework-snapshot/src/lib.rs | 3 +- crates/mgo-framework-tests/src/unit_tests.rs | 10 + crates/mgo-framework/build.rs | 45 +- .../docs/mgo-inscription/coinscription.md | 939 ++++++++++++ .../dependencies/mgo-framework/address.md | 305 ++++ .../mgo-framework/authenticator_state.md | 793 ++++++++++ .../dependencies/mgo-framework/bag.md | 322 ++++ .../dependencies/mgo-framework/balance.md | 450 ++++++ .../dependencies/mgo-framework/clock.md | 154 ++ .../dependencies/mgo-framework/coin.md | 1293 +++++++++++++++++ .../dependencies/mgo-framework/deny_list.md | 391 +++++ .../dependencies/mgo-framework/display.md | 516 +++++++ .../mgo-framework/dynamic_field.md | 552 +++++++ .../mgo-framework/dynamic_object_field.md | 260 ++++ .../dependencies/mgo-framework/event.md | 35 + .../dependencies/mgo-framework/hex.md | 146 ++ .../dependencies/mgo-framework/math.md | 242 +++ .../dependencies/mgo-framework/mgo.md | 164 +++ .../dependencies/mgo-framework/object.md | 715 +++++++++ .../dependencies/mgo-framework/package.md | 897 ++++++++++++ .../dependencies/mgo-framework/random.md | 296 ++++ .../dependencies/mgo-framework/table.md | 323 ++++ .../dependencies/mgo-framework/transfer.md | 423 ++++++ .../dependencies/mgo-framework/tx_context.md | 240 +++ .../dependencies/mgo-framework/types.md | 35 + .../dependencies/mgo-framework/url.md | 142 ++ .../dependencies/mgo-framework/vec_map.md | 630 ++++++++ .../dependencies/mgo-framework/vec_set.md | 354 +++++ .../dependencies/mgo-framework/versioned.md | 291 ++++ .../dependencies/move-stdlib/address.md | 37 + .../dependencies/move-stdlib/ascii.md | 407 ++++++ .../dependencies/move-stdlib/bcs.md | 35 + .../dependencies/move-stdlib/option.md | 519 +++++++ .../dependencies/move-stdlib/string.md | 478 ++++++ .../dependencies/move-stdlib/type_name.md | 341 +++++ .../dependencies/move-stdlib/vector.md | 478 ++++++ .../docs/mgo-inscription/inscription.md | 302 ++++ .../docs/mgo-inscription/singlescription.md | 648 +++++++++ .../docs/mgo-inscription/string_util.md | 459 ++++++ .../mgo-framework/docs/mgo-inscription/svg.md | 189 +++ .../packages/mgo-inscription/Move.lock | 28 + .../packages/mgo-inscription/Move.toml | 11 + .../sources/coinscription.move | 298 ++++ .../mgo-inscription/sources/inscription.move | 94 ++ .../sources/singlescription.move | 222 +++ .../mgo-inscription/sources/string_util.move | 177 +++ .../packages/mgo-inscription/sources/svg.move | 53 + crates/mgo-framework/src/lib.rs | 13 +- crates/mgo-graphql-rpc/tests/e2e_tests.rs | 68 +- crates/mgo-keys/src/key_derive.rs | 14 +- crates/mgo-move-build/src/lib.rs | 8 +- crates/mgo-protocol-config/src/lib.rs | 13 +- crates/mgo-replay/src/replay.rs | 8 +- .../mgo-source-validation-service/config.toml | 3 + .../src/test_adapter.rs | 18 +- crates/mgo-types/src/crypto.rs | 4 +- crates/mgo-types/src/lib.rs | 10 +- crates/mgo-types/src/mgo_serde.rs | 5 +- crates/mgo/src/client_commands.rs | 4 +- crates/mgo/src/keytool.rs | 20 +- crates/mgo/src/unit_tests/keytool_tests.rs | 51 +- narwhal/crypto/src/lib.rs | 4 +- parameters | 9 + 72 files changed, 15972 insertions(+), 91 deletions(-) create mode 100644 crates/mgo-framework-snapshot/bytecode_snapshot/3/0x0000000000000000000000000000000000000000000000000000000000000001 create mode 100644 crates/mgo-framework-snapshot/bytecode_snapshot/3/0x0000000000000000000000000000000000000000000000000000000000000002 create mode 100644 crates/mgo-framework-snapshot/bytecode_snapshot/3/0x0000000000000000000000000000000000000000000000000000000000000003 create mode 100644 crates/mgo-framework-snapshot/bytecode_snapshot/3/0x0000000000000000000000000000000000000000000000000000000000000004 create mode 100644 crates/mgo-framework/docs/mgo-inscription/coinscription.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/address.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/authenticator_state.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/bag.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/balance.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/clock.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/coin.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/deny_list.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/display.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/dynamic_field.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/dynamic_object_field.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/event.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/hex.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/math.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/mgo.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/object.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/package.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/random.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/table.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/transfer.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/tx_context.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/types.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/url.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/vec_map.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/vec_set.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/versioned.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/address.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/ascii.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/bcs.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/option.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/string.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/type_name.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/vector.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/inscription.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/singlescription.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/string_util.md create mode 100644 crates/mgo-framework/docs/mgo-inscription/svg.md create mode 100644 crates/mgo-framework/packages/mgo-inscription/Move.lock create mode 100644 crates/mgo-framework/packages/mgo-inscription/Move.toml create mode 100644 crates/mgo-framework/packages/mgo-inscription/sources/coinscription.move create mode 100644 crates/mgo-framework/packages/mgo-inscription/sources/inscription.move create mode 100644 crates/mgo-framework/packages/mgo-inscription/sources/singlescription.move create mode 100644 crates/mgo-framework/packages/mgo-inscription/sources/string_util.move create mode 100644 crates/mgo-framework/packages/mgo-inscription/sources/svg.move create mode 100644 parameters diff --git a/.gitignore b/.gitignore index 63dbb364..d6d78336 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ Move.lock !crates/mgo-framework/packages/move-stdlib/Move.lock !crates/mgo-framework/packages/mgo-framework/Move.lock !crates/mgo-framework/packages/mgo-system/Move.lock +!crates/mgo-framework/packages/mgo-inscription/Move.lock .trace .coverage_map.mvcov diff --git a/Cargo.lock b/Cargo.lock index a923ab3c..ee6a242b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6530,7 +6530,7 @@ dependencies = [ [[package]] name = "mgo" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anemo", "anyhow", @@ -6719,7 +6719,7 @@ dependencies = [ [[package]] name = "mgo-analytics-indexer" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anyhow", "arrow", @@ -6773,7 +6773,7 @@ dependencies = [ [[package]] name = "mgo-analytics-indexer-derive" -version = "1.0.0" +version = "1.0.1" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.33", @@ -7302,7 +7302,7 @@ dependencies = [ [[package]] name = "mgo-faucet" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anyhow", "async-recursion", @@ -7513,7 +7513,7 @@ dependencies = [ [[package]] name = "mgo-indexer" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anyhow", "async-trait", @@ -7803,7 +7803,7 @@ dependencies = [ [[package]] name = "mgo-move" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anyhow", "assert_cmd", @@ -7845,7 +7845,7 @@ dependencies = [ [[package]] name = "mgo-move-build" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anyhow", "datatest-stable", @@ -7987,7 +7987,7 @@ dependencies = [ [[package]] name = "mgo-node" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anemo", "anemo-tower", @@ -8038,7 +8038,7 @@ dependencies = [ [[package]] name = "mgo-open-rpc" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anyhow", "bcs", @@ -8076,7 +8076,7 @@ dependencies = [ [[package]] name = "mgo-oracle" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anyhow", "bcs", @@ -8313,7 +8313,7 @@ dependencies = [ [[package]] name = "mgo-rpc-loadgen" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anyhow", "async-trait", @@ -8343,7 +8343,7 @@ dependencies = [ [[package]] name = "mgo-sdk" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anyhow", "async-recursion", @@ -8465,7 +8465,7 @@ dependencies = [ [[package]] name = "mgo-source-validation" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anyhow", "colored", @@ -8594,7 +8594,7 @@ dependencies = [ [[package]] name = "mgo-surfer" -version = "1.0.0" +version = "1.0.1" dependencies = [ "async-trait", "bcs", @@ -8742,7 +8742,7 @@ dependencies = [ [[package]] name = "mgo-tool" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anemo", "anemo-cli", diff --git a/consensus/config/src/crypto.rs b/consensus/config/src/crypto.rs index b69ed310..5be77d07 100644 --- a/consensus/config/src/crypto.rs +++ b/consensus/config/src/crypto.rs @@ -3,7 +3,7 @@ use fastcrypto::{ bls12381, ed25519, - hash::{Blake2b256, HashFunction}, + hash::{Keccak256, HashFunction}, }; use shared_crypto::intent::INTENT_PREFIX_LENGTH; @@ -31,6 +31,6 @@ pub type ProtocolPrivateKey = bls12381::min_sig::BLS12381PrivateKey; pub type ProtocolKeyPair = bls12381::min_sig::BLS12381KeyPair; /// For block digest. -pub type DefaultHashFunction = Blake2b256; +pub type DefaultHashFunction = Keccak256; pub const DIGEST_LENGTH: usize = DefaultHashFunction::OUTPUT_SIZE; pub const INTENT_MESSAGE_LENGTH: usize = INTENT_PREFIX_LENGTH + DIGEST_LENGTH; diff --git a/crates/data-transform/src/main.rs b/crates/data-transform/src/main.rs index 4c4e85b8..4bcaab4e 100644 --- a/crates/data-transform/src/main.rs +++ b/crates/data-transform/src/main.rs @@ -108,15 +108,30 @@ impl ModuleResolver for GrootModuleResolver { fn get_module(&self, id: &ModuleId) -> Result>, Self::Error> { let address = id.address(); println!("address = {}", address); - let mapped_address = map_typus_address(address); - let module_id = ModuleId::new(mapped_address, id.name().to_owned()); - if &module_id != id { - println!("remapped module from {:#?} to {:#?}", id, module_id); + if is_move_inscription(address) { + let module_name = id.name().to_string(); + println!("i am groot, module_name: {}", module_name); + Ok(self.module_map.get(&module_name).cloned()) + } else { + let mapped_address = map_typus_address(address); + let module_id = ModuleId::new(mapped_address, id.name().to_owned()); + if &module_id != id { + println!("remapped module from {:#?} to {:#?}", id, module_id); + } + self.original.get_module(&module_id) } - self.original.get_module(&module_id) } } +static MOVE_INSCRIPTION: Lazy = Lazy::new(|| { + AccountAddress::from_str("0x0000000000000000000000000000000000000000000000000000000000000004") + .unwrap() +}); + +fn is_move_inscription(address: &AccountAddress) -> bool { + address == &*MOVE_INSCRIPTION +} + static TYPUS_LATEST: Lazy = Lazy::new(|| { AccountAddress::from_str("0xec2cc88cc1ba1da7a936ece33417634e18618e6898e496a3493d8f58d97e705b") .unwrap() diff --git a/crates/mgo-framework-snapshot/bytecode_snapshot/3/0x0000000000000000000000000000000000000000000000000000000000000001 b/crates/mgo-framework-snapshot/bytecode_snapshot/3/0x0000000000000000000000000000000000000000000000000000000000000001 new file mode 100644 index 0000000000000000000000000000000000000000..3329c2e9c655c935ef7425409f310fc981a1f3ac GIT binary patch literal 6963 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 literal 0 HcmV?d00001 diff --git a/crates/mgo-framework-snapshot/bytecode_snapshot/3/0x0000000000000000000000000000000000000000000000000000000000000003 b/crates/mgo-framework-snapshot/bytecode_snapshot/3/0x0000000000000000000000000000000000000000000000000000000000000003 new file mode 100644 index 0000000000000000000000000000000000000000..f17ee197fc2797eda5f13ccbe0b545d31a1fa839 GIT binary patch literal 41741 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 W$1vs>HZ8JlW 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 @@ -22,6 +22,7 @@ const SYSTEM_PACKAGE_PUBLISH_ORDER: &[ObjectID] = &[ MOVE_STDLIB_PACKAGE_ID, MGO_FRAMEWORK_PACKAGE_ID, MGO_SYSTEM_PACKAGE_ID, + MGO_INSCRIPTION_PACKAGE_ID, ]; pub fn load_bytecode_snapshot_manifest() -> SnapshotManifest { diff --git a/crates/mgo-framework-tests/src/unit_tests.rs b/crates/mgo-framework-tests/src/unit_tests.rs index 48744c0a..076d6bf4 100644 --- a/crates/mgo-framework-tests/src/unit_tests.rs +++ b/crates/mgo-framework-tests/src/unit_tests.rs @@ -29,6 +29,16 @@ fn run_mgo_system_tests() { }); } +#[test] +#[cfg_attr(msim, ignore)] +fn run_mgo_inscription_tests() { + check_move_unit_tests({ + let mut buf = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + buf.extend(["..", "mgo-framework", "packages", "mgo-inscription"]); + buf + }); +} + #[test] #[cfg_attr(msim, ignore)] fn run_examples_move_unit_tests() { diff --git a/crates/mgo-framework/build.rs b/crates/mgo-framework/build.rs index b421850e..38444333 100644 --- a/crates/mgo-framework/build.rs +++ b/crates/mgo-framework/build.rs @@ -20,8 +20,10 @@ fn main() { let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); let packages_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("packages"); + let mgo_inscription_path = packages_path.join("mgo-inscription"); let mgo_system_path = packages_path.join("mgo-system"); let mgo_framework_path = packages_path.join("mgo-framework"); + let mgo_inscription_path_clone = mgo_inscription_path.clone(); let mgo_system_path_clone = mgo_system_path.clone(); let mgo_framework_path_clone = mgo_framework_path.clone(); let move_stdlib_path = packages_path.join("move-stdlib"); @@ -30,6 +32,7 @@ fn main() { .stack_size(16 * 1024 * 1024) // build_packages require bigger stack size on windows. .spawn(move || { build_packages( + mgo_inscription_path_clone, mgo_system_path_clone, mgo_framework_path_clone, out_dir, @@ -40,6 +43,14 @@ fn main() { .unwrap(); println!("cargo:rerun-if-changed=build.rs"); + println!( + "cargo:return-if-changed={}", + mgo_inscription_path.join("Move.toml").display() + ); + println!( + "cargo:return-if-changed={}", + mgo_inscription_path.join("sources").display() + ); println!( "cargo:rerun-if-changed={}", mgo_system_path.join("Move.toml").display() @@ -67,6 +78,7 @@ fn main() { } fn build_packages( + mgo_inscription_path: PathBuf, mgo_system_path: PathBuf, mgo_framework_path: PathBuf, out_dir: PathBuf, @@ -80,9 +92,11 @@ fn build_packages( }; debug_assert!(!config.test_mode); build_packages_with_move_config( + mgo_inscription_path.clone(), mgo_system_path.clone(), mgo_framework_path.clone(), out_dir.clone(), + "mgo-inscription", "mgo-system", "mgo-framework", "move-stdlib", @@ -98,9 +112,11 @@ fn build_packages( ..Default::default() }; build_packages_with_move_config( + mgo_inscription_path, mgo_system_path, mgo_framework_path, out_dir, + "mgo-inscription-test", "mgo-system-test", "mgo-framework-test", "move-stdlib-test", @@ -110,9 +126,11 @@ fn build_packages( } fn build_packages_with_move_config( + mgo_inscription_path: PathBuf, mgo_system_path: PathBuf, mgo_framework_path: PathBuf, out_dir: PathBuf, + mgo_inscription_dir: &str, system_dir: &str, framework_dir: &str, stdlib_dir: &str, @@ -124,26 +142,43 @@ fn build_packages_with_move_config( run_bytecode_verifier: true, print_diags_to_stderr: false, } - .build(mgo_framework_path) - .unwrap(); + .build(mgo_framework_path) + .unwrap(); let system_pkg = BuildConfig { config: config.clone(), run_bytecode_verifier: true, print_diags_to_stderr: false, } - .build(mgo_system_path) - .unwrap(); + .build(mgo_system_path) + .unwrap(); + + let mgo_inscription_pkg = BuildConfig { + config, + run_bytecode_verifier: true, + print_diags_to_stderr: false, + } + .build(mgo_inscription_path) + .unwrap(); let mgo_system = system_pkg.get_mgo_system_modules(); let mgo_framework = framework_pkg.get_mgo_framework_modules(); + let mgo_inscription = mgo_inscription_pkg.get_mgo_inscription_modules(); let move_stdlib = framework_pkg.get_stdlib_modules(); serialize_modules_to_file(mgo_system, &out_dir.join(system_dir)).unwrap(); serialize_modules_to_file(mgo_framework, &out_dir.join(framework_dir)).unwrap(); + serialize_modules_to_file(mgo_inscription, &out_dir.join(mgo_inscription_dir)).unwrap(); serialize_modules_to_file(move_stdlib, &out_dir.join(stdlib_dir)).unwrap(); // write out generated docs // TODO: remove docs of deleted files if write_docs { + for (fname, doc) in mgo_inscription_pkg.package.compiled_docs.unwrap() { + let mut dst_path = PathBuf::from(DOCS_DIR); + dst_path.push(mgo_inscription_dir); + dst_path.push(fname); + fs::create_dir_all(dst_path.parent().unwrap()).unwrap(); + fs::write(dst_path, doc).unwrap(); + } for (fname, doc) in system_pkg.package.compiled_docs.unwrap() { let mut dst_path = PathBuf::from(DOCS_DIR); dst_path.push(system_dir); @@ -162,7 +197,7 @@ fn build_packages_with_move_config( } fn serialize_modules_to_file<'a>( - modules: impl Iterator, + modules: impl Iterator, file: &Path, ) -> Result<()> { let mut serialized_modules = Vec::new(); diff --git a/crates/mgo-framework/docs/mgo-inscription/coinscription.md b/crates/mgo-framework/docs/mgo-inscription/coinscription.md new file mode 100644 index 00000000..f0f12980 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/coinscription.md @@ -0,0 +1,939 @@ + + + +# Module `0x4::coinscription` + + + +- [Resource `TickPoolRecord`](#0x4_coinscription_TickPoolRecord) +- [Resource `TickRecord`](#0x4_coinscription_TickRecord) +- [Resource `CoinScription`](#0x4_coinscription_CoinScription) +- [Struct `COINSCRIPTION`](#0x4_coinscription_COINSCRIPTION) +- [Struct `NewTick`](#0x4_coinscription_NewTick) +- [Struct `MintCoinScription`](#0x4_coinscription_MintCoinScription) +- [Struct `BurnCoinScription`](#0x4_coinscription_BurnCoinScription) +- [Constants](#@Constants_0) +- [Function `init`](#0x4_coinscription_init) +- [Function `init_display`](#0x4_coinscription_init_display) +- [Function `new_tick`](#0x4_coinscription_new_tick) +- [Function `find_tick`](#0x4_coinscription_find_tick) +- [Function `tick_record_address_list`](#0x4_coinscription_tick_record_address_list) +- [Function `do_mint`](#0x4_coinscription_do_mint) +- [Function `is_mergeable`](#0x4_coinscription_is_mergeable) +- [Function `do_merge`](#0x4_coinscription_do_merge) +- [Function `is_splitable`](#0x4_coinscription_is_splitable) +- [Function `do_split`](#0x4_coinscription_do_split) +- [Function `split`](#0x4_coinscription_split) +- [Function `zero`](#0x4_coinscription_zero) +- [Function `is_zero`](#0x4_coinscription_is_zero) +- [Function `destroy_zero`](#0x4_coinscription_destroy_zero) +- [Function `do_burn`](#0x4_coinscription_do_burn) + + +
use 0x1::option;
+use 0x1::string;
+use 0x2::display;
+use 0x2::event;
+use 0x2::object;
+use 0x2::package;
+use 0x2::table;
+use 0x2::transfer;
+use 0x2::tx_context;
+use 0x4::string_util;
+use 0x4::svg;
+
+ + + + + +## Resource `TickPoolRecord` + + + +
struct TickPoolRecord has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+record: table::Table<string::String, address> +
+
+ The Tick name -> TickRecord object id +
+
+display: display::Display<coinscription::CoinScription> +
+
+ +
+
+ + +
+ + + +## Resource `TickRecord` + + + +
struct TickRecord has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+tick: string::String +
+
+ +
+
+total_supply: u64 +
+
+ +
+
+burnable: bool +
+
+ +
+
+remain: u64 +
+
+ +
+
+current_supply: u64 +
+
+ +
+
+ + +
+ + + +## Resource `CoinScription` + + + +
struct CoinScription has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+amount: u64 +
+
+ +
+
+tick: string::String +
+
+ +
+
+ + +
+ + + +## Struct `COINSCRIPTION` + + + +
struct COINSCRIPTION has drop
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `NewTick` + + + +
struct NewTick has copy, drop
+
+ + + +
+Fields + + +
+
+id: object::ID +
+
+ +
+
+deployer: address +
+
+ +
+
+tick: string::String +
+
+ +
+
+total_supply: u64 +
+
+ +
+
+burnable: bool +
+
+ +
+
+ + +
+ + + +## Struct `MintCoinScription` + + + +
struct MintCoinScription has copy, drop
+
+ + + +
+Fields + + +
+
+id: object::ID +
+
+ +
+
+sender: address +
+
+ +
+
+tick: string::String +
+
+ +
+
+amount: u64 +
+
+ +
+
+ + +
+ + + +## Struct `BurnCoinScription` + + + +
struct BurnCoinScription has copy, drop
+
+ + + +
+Fields + + +
+
+sender: address +
+
+ +
+
+tick: string::String +
+
+ +
+
+amount: u64 +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const EInvalidAmount: u64 = 4;
+
+ + + + + + + +
const ErrorCannotBurn: u64 = 6;
+
+ + + + + + + +
const ErrorDisplayInited: u64 = 9;
+
+ + + + + + + +
const ErrorInvalidTick: u64 = 8;
+
+ + + + + + + +
const ErrorNotEnoughSupply: u64 = 2;
+
+ + + + + + + +
const ErrorNotEnoughToMint: u64 = 3;
+
+ + + + + + + +
const ErrorNotSameTick: u64 = 5;
+
+ + + + + + + +
const ErrorNotZero: u64 = 7;
+
+ + + + + + + +
const ErrorTickAlreadyExists: u64 = 1;
+
+ + + + + +## Function `init` + + + +
fun init(otw: coinscription::COINSCRIPTION, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
fun init(otw: COINSCRIPTION, ctx: &mut TxContext) {
+    let publisher = package::claim(otw, ctx);
+
+    let keys = vector[
+        std::string::utf8(b"tick"),
+        std::string::utf8(b"amount"),
+        std::string::utf8(b"image_url"),
+    ];
+
+    let p = b"mrc-20";
+    let op = b"mint";
+    let tick = b"{tick}";
+    let amt = b"{amount}";
+
+    let img_metadata = svg::generate_coinscription_svg(p, op, tick, amt);
+
+    let values = vector[
+        std::string::utf8(b"{tick}"),
+        std::string::utf8(b"{amount}"),
+        std::string::utf8(img_metadata),
+    ];
+    let display = display::new_with_fields<CoinScription>(
+        &publisher, keys, values, ctx
+    );
+
+    let tick_pool_record = TickPoolRecord {
+        id: object::new(ctx), record: table::new(
+            ctx
+        ), display
+    };
+    transfer::share_object(tick_pool_record);
+
+    package::burn_publisher(publisher);
+}
+
+ + + +
+ + + +## Function `init_display` + + + +
public entry fun init_display(tick_pool_record: &mut coinscription::TickPoolRecord, _ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun init_display(tick_pool_record: &mut TickPoolRecord, _ctx: &mut TxContext) {
+    assert!(display::version(&tick_pool_record.display) == 0, ErrorDisplayInited);
+    display::update_version(&mut tick_pool_record.display);
+}
+
+ + + +
+ + + +## Function `new_tick` + + + +
public fun new_tick(tick_pool_record: &mut coinscription::TickPoolRecord, tick: string::String, total_supply: u64, burnable: bool, ctx: &mut tx_context::TxContext): coinscription::TickRecord
+
+ + + +
+Implementation + + +
public fun new_tick(
+    tick_pool_record: &mut TickPoolRecord,
+    tick: String,
+    total_supply: u64,
+    burnable: bool,
+    ctx: &mut TxContext
+): TickRecord {
+    assert!(string_util::is_tick_valid(&tick), ErrorInvalidTick);
+    assert!(!table::contains(&tick_pool_record.record, tick), ErrorTickAlreadyExists);
+    assert!(total_supply > 0, ErrorNotEnoughSupply);
+
+    let tick_uid = object::new(ctx);
+    let tick_id = object::uid_to_inner(&tick_uid);
+    let tick_record: TickRecord = TickRecord {
+        id: tick_uid,
+        tick,
+        total_supply,
+        burnable,
+        remain: total_supply,
+        current_supply: 0,
+    };
+    table::add(&mut tick_pool_record.record, tick, id_to_address(&tick_id));
+    emit(NewTick {
+        id: tick_id,
+        deployer: tx_context::sender(ctx),
+        tick,
+        total_supply,
+        burnable
+    });
+    tick_record
+}
+
+ + + +
+ + + +## Function `find_tick` + + + +
public fun find_tick(tick_pool_record: &mut coinscription::TickPoolRecord, tick: string::String): option::Option<address>
+
+ + + +
+Implementation + + +
public fun find_tick(tick_pool_record: &mut TickPoolRecord, tick: String): Option<address> {
+    if (table::contains(&tick_pool_record.record, tick)) {
+        let id_tick = table::borrow(&tick_pool_record.record, tick);
+        option::some(*id_tick)
+    } else {
+        option::none()
+    }
+}
+
+ + + +
+ + + +## Function `tick_record_address_list` + + + +
public fun tick_record_address_list(tick_pool_record: &coinscription::TickPoolRecord, ticks: vector<string::String>): vector<address>
+
+ + + +
+Implementation + + +
public fun tick_record_address_list(
+    tick_pool_record: &TickPoolRecord,
+    ticks: vector<String>,
+): vector<address> {
+    let vec_addrs = vector::empty<address>();
+
+    let i = 0;
+    let end = vector::length(&ticks);
+    while (i < end) {
+        let key = *vector::borrow(&ticks, i);
+        let value = table::borrow(&tick_pool_record.record, key);
+        vector::push_back(&mut vec_addrs, *value);
+        i = i + 1;
+    };
+
+    vec_addrs
+}
+
+ + + +
+ + + +## Function `do_mint` + + + +
public fun do_mint(tick_record: &mut coinscription::TickRecord, amount: u64, ctx: &mut tx_context::TxContext): coinscription::CoinScription
+
+ + + +
+Implementation + + +
public fun do_mint(
+    tick_record: &mut TickRecord,
+    amount: u64,
+    ctx: &mut TxContext
+): CoinScription {
+    assert!(tick_record.remain > 0, ErrorNotEnoughToMint);
+    assert!(tick_record.remain >= amount, ErrorNotEnoughToMint);
+
+    tick_record.remain = tick_record.remain - amount;
+    tick_record.current_supply = tick_record.current_supply + amount;
+
+    let tick: String = tick_record.tick;
+    let sender = tx_context::sender(ctx);
+    let coinscription = CoinScription {
+        id: object::new(ctx),
+        amount,
+        tick,
+    };
+    emit(MintCoinScription {
+        id: object::id(&coinscription),
+        sender,
+        tick,
+        amount,
+    });
+    coinscription
+}
+
+ + + +
+ + + +## Function `is_mergeable` + + + +
public fun is_mergeable(inscription1: &coinscription::CoinScription, inscription2: &coinscription::CoinScription): bool
+
+ + + +
+Implementation + + +
public fun is_mergeable(inscription1: &CoinScription, inscription2: &CoinScription): bool {
+    inscription1.tick == inscription2.tick
+}
+
+ + + +
+ + + +## Function `do_merge` + + + +
public fun do_merge(inscription1: &mut coinscription::CoinScription, inscription2: coinscription::CoinScription)
+
+ + + +
+Implementation + + +
public fun do_merge(
+    inscription1: &mut CoinScription,
+    inscription2: CoinScription,
+) {
+    assert!(inscription1.tick == inscription2.tick, ErrorNotSameTick);
+    let CoinScription { id, amount, tick: _ } = inscription2;
+    inscription1.amount = inscription1.amount + amount;
+    object::delete(id);
+}
+
+ + + +
+ + + +## Function `is_splitable` + +Check if the inscription can be split + + +
public fun is_splitable(inscription: &coinscription::CoinScription): bool
+
+ + + +
+Implementation + + +
public fun is_splitable(inscription: &CoinScription): bool {
+    inscription.amount > 1
+}
+
+ + + +
+ + + +## Function `do_split` + +Split the inscription and return the new inscription + + +
public fun do_split(inscription: &mut coinscription::CoinScription, amount: u64, ctx: &mut tx_context::TxContext): coinscription::CoinScription
+
+ + + +
+Implementation + + +
public fun do_split(
+    inscription: &mut CoinScription,
+    amount: u64,
+    ctx: &mut TxContext
+): CoinScription {
+    assert!(0 < amount && amount < inscription.amount, EInvalidAmount);
+    let original_amount = inscription.amount;
+    inscription.amount = original_amount - amount;
+    let split_movescription = CoinScription {
+        id: object::new(ctx),
+        amount,
+        tick: inscription.tick,
+    };
+    split_movescription
+}
+
+ + + +
+ + + +## Function `split` + + + +
public entry fun split(inscription: &mut coinscription::CoinScription, amount: u64, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun split(
+    inscription: &mut CoinScription,
+    amount: u64,
+    ctx: &mut TxContext
+) {
+    let ins = do_split(inscription, amount, ctx);
+    transfer::public_transfer(ins, tx_context::sender(ctx));
+}
+
+ + + +
+ + + +## Function `zero` + + + +
public fun zero(tick_record: &coinscription::TickRecord, ctx: &mut tx_context::TxContext): coinscription::CoinScription
+
+ + + +
+Implementation + + +
public fun zero(tick_record: &TickRecord, ctx: &mut TxContext): CoinScription {
+    CoinScription {
+        id: object::new(ctx),
+        tick: tick_record.tick,
+        amount: 0
+    }
+}
+
+ + + +
+ + + +## Function `is_zero` + + + +
public fun is_zero(self: &coinscription::CoinScription): bool
+
+ + + +
+Implementation + + +
public fun is_zero(self: &CoinScription): bool {
+    self.amount == 0
+}
+
+ + + +
+ + + +## Function `destroy_zero` + + + +
public fun destroy_zero(self: coinscription::CoinScription)
+
+ + + +
+Implementation + + +
public fun destroy_zero(self: CoinScription) {
+    assert!(self.amount == 0, ErrorNotZero);
+    let CoinScription { id, amount: _, tick: _ } = self;
+    object::delete(id);
+}
+
+ + + +
+ + + +## Function `do_burn` + + + +
public entry fun do_burn(tick_record: &mut coinscription::TickRecord, inscription: coinscription::CoinScription, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun do_burn(
+    tick_record: &mut TickRecord,
+    inscription: CoinScription,
+    ctx: &mut TxContext
+) {
+    assert!(tick_record.tick == inscription.tick, ErrorNotSameTick);
+    assert!(tick_record.burnable, ErrorCannotBurn);
+    let sender = tx_context::sender(ctx);
+    let CoinScription { id: scription_uid, amount, tick } = inscription;
+    tick_record.current_supply = tick_record.current_supply - amount;
+    object::delete(scription_uid);
+
+    emit({
+        BurnCoinScription {
+            sender,
+            tick,
+            amount,
+        }
+    });
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/address.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/address.md new file mode 100644 index 00000000..3e83bb51 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/address.md @@ -0,0 +1,305 @@ + + + +# Module `0x2::address` + + + +- [Constants](#@Constants_0) +- [Function `to_u256`](#0x2_address_to_u256) +- [Function `from_u256`](#0x2_address_from_u256) +- [Function `from_bytes`](#0x2_address_from_bytes) +- [Function `to_bytes`](#0x2_address_to_bytes) +- [Function `to_ascii_string`](#0x2_address_to_ascii_string) +- [Function `to_string`](#0x2_address_to_string) +- [Function `from_ascii_bytes`](#0x2_address_from_ascii_bytes) +- [Function `hex_char_value`](#0x2_address_hex_char_value) +- [Function `length`](#0x2_address_length) +- [Function `max`](#0x2_address_max) + + +
use 0x1::ascii;
+use 0x1::bcs;
+use 0x1::string;
+use 0x2::hex;
+
+ + + + + +## Constants + + + + + + +
const EAddressParseError: u64 = 0;
+
+ + + + + + + +
const LENGTH: u64 = 32;
+
+ + + + + + + +
const MAX: u256 = 115792089237316195423570985008687907853269984665640564039457584007913129639935;
+
+ + + + + +## Function `to_u256` + + + +
public fun to_u256(a: address): u256
+
+ + + +
+Implementation + + +
public native fun to_u256(a: address): u256;
+
+ + + +
+ + + +## Function `from_u256` + + + +
public fun from_u256(n: u256): address
+
+ + + +
+Implementation + + +
public native fun from_u256(n: u256): address;
+
+ + + +
+ + + +## Function `from_bytes` + + + +
public fun from_bytes(bytes: vector<u8>): address
+
+ + + +
+Implementation + + +
public native fun from_bytes(bytes: vector<u8>): address;
+
+ + + +
+ + + +## Function `to_bytes` + + + +
public fun to_bytes(a: address): vector<u8>
+
+ + + +
+Implementation + + +
public fun to_bytes(a: address): vector<u8> {
+    bcs::to_bytes(&a)
+}
+
+ + + +
+ + + +## Function `to_ascii_string` + + + +
public fun to_ascii_string(a: address): ascii::String
+
+ + + +
+Implementation + + +
public fun to_ascii_string(a: address): ascii::String {
+    ascii::string(hex::encode(to_bytes(a)))
+}
+
+ + + +
+ + + +## Function `to_string` + + + +
public fun to_string(a: address): string::String
+
+ + + +
+Implementation + + +
public fun to_string(a: address): string::String {
+    string::from_ascii(to_ascii_string(a))
+}
+
+ + + +
+ + + +## Function `from_ascii_bytes` + + + +
public fun from_ascii_bytes(bytes: &vector<u8>): address
+
+ + + +
+Implementation + + +
public fun from_ascii_bytes(bytes: &vector<u8>): address {
+    assert!(vector::length(bytes) == 64, EAddressParseError);
+    let hex_bytes = vector[];
+    let i = 0;
+    while (i < 64) {
+        let hi = hex_char_value(*vector::borrow(bytes, i));
+        let lo = hex_char_value(*vector::borrow(bytes, i + 1));
+        vector::push_back(&mut hex_bytes, (hi << 4) | lo);
+        i = i + 2;
+    };
+    from_bytes(hex_bytes)
+}
+
+ + + +
+ + + +## Function `hex_char_value` + + + +
fun hex_char_value(c: u8): u8
+
+ + + +
+Implementation + + +
fun hex_char_value(c: u8): u8 {
+    if (c >= 48 && c <= 57) c - 48 // 0-9
+    else if (c >= 65 && c <= 70) c - 55 // A-F
+    else if (c >= 97 && c <= 102) c - 87 // a-f
+    else abort EAddressParseError
+}
+
+ + + +
+ + + +## Function `length` + + + +
public fun length(): u64
+
+ + + +
+Implementation + + +
public fun length(): u64 {
+    LENGTH
+}
+
+ + + +
+ + + +## Function `max` + + + +
public fun max(): u256
+
+ + + +
+Implementation + + +
public fun max(): u256 {
+    MAX
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/authenticator_state.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/authenticator_state.md new file mode 100644 index 00000000..658cdd49 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/authenticator_state.md @@ -0,0 +1,793 @@ + + + +# Module `0x2::authenticator_state` + + + +- [Resource `AuthenticatorState`](#0x2_authenticator_state_AuthenticatorState) +- [Struct `AuthenticatorStateInner`](#0x2_authenticator_state_AuthenticatorStateInner) +- [Struct `JWK`](#0x2_authenticator_state_JWK) +- [Struct `JwkId`](#0x2_authenticator_state_JwkId) +- [Struct `ActiveJwk`](#0x2_authenticator_state_ActiveJwk) +- [Constants](#@Constants_0) +- [Function `active_jwk_equal`](#0x2_authenticator_state_active_jwk_equal) +- [Function `jwk_equal`](#0x2_authenticator_state_jwk_equal) +- [Function `jwk_id_equal`](#0x2_authenticator_state_jwk_id_equal) +- [Function `string_bytes_lt`](#0x2_authenticator_state_string_bytes_lt) +- [Function `jwk_lt`](#0x2_authenticator_state_jwk_lt) +- [Function `create`](#0x2_authenticator_state_create) +- [Function `load_inner_mut`](#0x2_authenticator_state_load_inner_mut) +- [Function `load_inner`](#0x2_authenticator_state_load_inner) +- [Function `check_sorted`](#0x2_authenticator_state_check_sorted) +- [Function `update_authenticator_state`](#0x2_authenticator_state_update_authenticator_state) +- [Function `deduplicate`](#0x2_authenticator_state_deduplicate) +- [Function `expire_jwks`](#0x2_authenticator_state_expire_jwks) +- [Function `get_active_jwks`](#0x2_authenticator_state_get_active_jwks) + + +
use 0x1::option;
+use 0x1::string;
+use 0x2::dynamic_field;
+use 0x2::math;
+use 0x2::object;
+use 0x2::transfer;
+use 0x2::tx_context;
+
+ + + + + +## Resource `AuthenticatorState` + + + +
struct AuthenticatorState has key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+version: u64 +
+
+ +
+
+ + +
+ + + +## Struct `AuthenticatorStateInner` + + + +
struct AuthenticatorStateInner has store
+
+ + + +
+Fields + + +
+
+version: u64 +
+
+ +
+
+active_jwks: vector<authenticator_state::ActiveJwk> +
+
+ +
+
+ + +
+ + + +## Struct `JWK` + + + +
struct JWK has copy, drop, store
+
+ + + +
+Fields + + +
+
+kty: string::String +
+
+ +
+
+e: string::String +
+
+ +
+
+n: string::String +
+
+ +
+
+alg: string::String +
+
+ +
+
+ + +
+ + + +## Struct `JwkId` + + + +
struct JwkId has copy, drop, store
+
+ + + +
+Fields + + +
+
+iss: string::String +
+
+ +
+
+kid: string::String +
+
+ +
+
+ + +
+ + + +## Struct `ActiveJwk` + + + +
struct ActiveJwk has copy, drop, store
+
+ + + +
+Fields + + +
+
+jwk_id: authenticator_state::JwkId +
+
+ +
+
+jwk: authenticator_state::JWK +
+
+ +
+
+epoch: u64 +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ENotSystemAddress: u64 = 0;
+
+ + + + + + + +
const CurrentVersion: u64 = 1;
+
+ + + + + + + +
const EJwksNotSorted: u64 = 2;
+
+ + + + + + + +
const EWrongInnerVersion: u64 = 1;
+
+ + + + + +## Function `active_jwk_equal` + + + +
fun active_jwk_equal(a: &authenticator_state::ActiveJwk, b: &authenticator_state::ActiveJwk): bool
+
+ + + +
+Implementation + + +
fun active_jwk_equal(a: &ActiveJwk, b: &ActiveJwk): bool {
+    // note: epoch is ignored
+    jwk_equal(&a.jwk, &b.jwk) && jwk_id_equal(&a.jwk_id, &b.jwk_id)
+}
+
+ + + +
+ + + +## Function `jwk_equal` + + + +
fun jwk_equal(a: &authenticator_state::JWK, b: &authenticator_state::JWK): bool
+
+ + + +
+Implementation + + +
fun jwk_equal(a: &JWK, b: &JWK): bool {
+    (&a.kty == &b.kty) &&
+       (&a.e == &b.e) &&
+       (&a.n == &b.n) &&
+       (&a.alg == &b.alg)
+}
+
+ + + +
+ + + +## Function `jwk_id_equal` + + + +
fun jwk_id_equal(a: &authenticator_state::JwkId, b: &authenticator_state::JwkId): bool
+
+ + + +
+Implementation + + +
fun jwk_id_equal(a: &JwkId, b: &JwkId): bool {
+    (&a.iss == &b.iss) && (&a.kid == &b.kid)
+}
+
+ + + +
+ + + +## Function `string_bytes_lt` + + + +
fun string_bytes_lt(a: &string::String, b: &string::String): bool
+
+ + + +
+Implementation + + +
fun string_bytes_lt(a: &String, b: &String): bool {
+    let a_bytes = string::bytes(a);
+    let b_bytes = string::bytes(b);
+
+    if (vector::length(a_bytes) < vector::length(b_bytes)) {
+        true
+    } else if (vector::length(a_bytes) > vector::length(b_bytes)) {
+        false
+    } else {
+        let i = 0;
+        while (i < vector::length(a_bytes)) {
+            let a_byte = *vector::borrow(a_bytes, i);
+            let b_byte = *vector::borrow(b_bytes, i);
+            if (a_byte < b_byte) {
+                return true
+            } else if (a_byte > b_byte) {
+                return false
+            };
+            i = i + 1;
+        };
+        // all bytes are equal
+        false
+    }
+}
+
+ + + +
+ + + +## Function `jwk_lt` + + + +
fun jwk_lt(a: &authenticator_state::ActiveJwk, b: &authenticator_state::ActiveJwk): bool
+
+ + + +
+Implementation + + +
fun jwk_lt(a: &ActiveJwk, b: &ActiveJwk): bool {
+    // note: epoch is ignored
+    if (&a.jwk_id.iss != &b.jwk_id.iss) {
+        return string_bytes_lt(&a.jwk_id.iss, &b.jwk_id.iss)
+    };
+    if (&a.jwk_id.kid != &b.jwk_id.kid) {
+        return string_bytes_lt(&a.jwk_id.kid, &b.jwk_id.kid)
+    };
+    if (&a.jwk.kty != &b.jwk.kty) {
+        return string_bytes_lt(&a.jwk.kty, &b.jwk.kty)
+    };
+    if (&a.jwk.e != &b.jwk.e) {
+        return string_bytes_lt(&a.jwk.e, &b.jwk.e)
+    };
+    if (&a.jwk.n != &b.jwk.n) {
+        return string_bytes_lt(&a.jwk.n, &b.jwk.n)
+    };
+    string_bytes_lt(&a.jwk.alg, &b.jwk.alg)
+}
+
+ + + +
+ + + +## Function `create` + + + +
fun create(ctx: &tx_context::TxContext)
+
+ + + +
+Implementation + + +
fun create(ctx: &TxContext) {
+    assert!(tx_context::sender(ctx) == @0x0, ENotSystemAddress);
+
+    let version = CurrentVersion;
+
+    let inner = AuthenticatorStateInner {
+        version,
+        active_jwks: vector[],
+    };
+
+    let self = AuthenticatorState {
+        id: object::authenticator_state(),
+        version,
+    };
+
+    dynamic_field::add(&mut self.id, version, inner);
+    transfer::share_object(self);
+}
+
+ + + +
+ + + +## Function `load_inner_mut` + + + +
fun load_inner_mut(self: &mut authenticator_state::AuthenticatorState): &mut authenticator_state::AuthenticatorStateInner
+
+ + + +
+Implementation + + +
fun load_inner_mut(
+    self: &mut AuthenticatorState,
+): &mut AuthenticatorStateInner {
+    let version = self.version;
+
+    // replace this with a lazy update function when we add a new version of the inner object.
+    assert!(version == CurrentVersion, EWrongInnerVersion);
+
+    let inner: &mut AuthenticatorStateInner = dynamic_field::borrow_mut(&mut self.id, self.version);
+
+    assert!(inner.version == version, EWrongInnerVersion);
+    inner
+}
+
+ + + +
+ + + +## Function `load_inner` + + + +
fun load_inner(self: &authenticator_state::AuthenticatorState): &authenticator_state::AuthenticatorStateInner
+
+ + + +
+Implementation + + +
fun load_inner(
+    self: &AuthenticatorState,
+): &AuthenticatorStateInner {
+    let version = self.version;
+
+    // replace this with a lazy update function when we add a new version of the inner object.
+    assert!(version == CurrentVersion, EWrongInnerVersion);
+
+    let inner: &AuthenticatorStateInner = dynamic_field::borrow(&self.id, self.version);
+
+    assert!(inner.version == version, EWrongInnerVersion);
+    inner
+}
+
+ + + +
+ + + +## Function `check_sorted` + + + +
fun check_sorted(new_active_jwks: &vector<authenticator_state::ActiveJwk>)
+
+ + + +
+Implementation + + +
fun check_sorted(new_active_jwks: &vector<ActiveJwk>) {
+    let i = 0;
+    while (i < vector::length(new_active_jwks) - 1) {
+        let a = vector::borrow(new_active_jwks, i);
+        let b = vector::borrow(new_active_jwks, i + 1);
+        assert!(jwk_lt(a, b), EJwksNotSorted);
+        i = i + 1;
+    };
+}
+
+ + + +
+ + + +## Function `update_authenticator_state` + + + +
fun update_authenticator_state(self: &mut authenticator_state::AuthenticatorState, new_active_jwks: vector<authenticator_state::ActiveJwk>, ctx: &tx_context::TxContext)
+
+ + + +
+Implementation + + +
fun update_authenticator_state(
+    self: &mut AuthenticatorState,
+    new_active_jwks: vector<ActiveJwk>,
+    ctx: &TxContext,
+) {
+    // Validator will make a special system call with sender set as 0x0.
+    assert!(tx_context::sender(ctx) == @0x0, ENotSystemAddress);
+
+    check_sorted(&new_active_jwks);
+    let new_active_jwks = deduplicate(new_active_jwks);
+
+    let inner = load_inner_mut(self);
+
+    let res = vector[];
+    let i = 0;
+    let j = 0;
+    let active_jwks_len = vector::length(&inner.active_jwks);
+    let new_active_jwks_len = vector::length(&new_active_jwks);
+
+    while (i < active_jwks_len && j < new_active_jwks_len) {
+        let old_jwk = vector::borrow(&inner.active_jwks, i);
+        let new_jwk = vector::borrow(&new_active_jwks, j);
+
+        // when they are equal, push only one, but use the max epoch of the two
+        if (active_jwk_equal(old_jwk, new_jwk)) {
+            let jwk = *old_jwk;
+            jwk.epoch = math::max(old_jwk.epoch, new_jwk.epoch);
+            vector::push_back(&mut res, jwk);
+            i = i + 1;
+            j = j + 1;
+        } else if (jwk_id_equal(&old_jwk.jwk_id, &new_jwk.jwk_id)) {
+            // if only jwk_id is equal, then the key has changed. Providers should not send
+            // JWKs like this, but if they do, we must ignore the new JWK to avoid having a
+            // liveness / forking issues
+            vector::push_back(&mut res, *old_jwk);
+            i = i + 1;
+            j = j + 1;
+        } else if (jwk_lt(old_jwk, new_jwk)) {
+            vector::push_back(&mut res, *old_jwk);
+            i = i + 1;
+        } else {
+            vector::push_back(&mut res, *new_jwk);
+            j = j + 1;
+        }
+    };
+
+    while (i < active_jwks_len) {
+        vector::push_back(&mut res, *vector::borrow(&inner.active_jwks, i));
+        i = i + 1;
+    };
+    while (j < new_active_jwks_len) {
+        vector::push_back(&mut res, *vector::borrow(&new_active_jwks, j));
+        j = j + 1;
+    };
+
+    inner.active_jwks = res;
+}
+
+ + + +
+ + + +## Function `deduplicate` + + + +
fun deduplicate(jwks: vector<authenticator_state::ActiveJwk>): vector<authenticator_state::ActiveJwk>
+
+ + + +
+Implementation + + +
fun deduplicate(jwks: vector<ActiveJwk>): vector<ActiveJwk> {
+    let res = vector[];
+    let i = 0;
+    let prev: Option<JwkId> = option::none();
+    while (i < vector::length(&jwks)) {
+        let jwk = vector::borrow(&jwks, i);
+        if (option::is_none(&prev)) {
+            option::fill(&mut prev, jwk.jwk_id);
+        } else if (jwk_id_equal(option::borrow(&prev), &jwk.jwk_id)) {
+            // skip duplicate jwks in input
+            i = i + 1;
+            continue
+        } else {
+            *option::borrow_mut(&mut prev) = jwk.jwk_id;
+        };
+        vector::push_back(&mut res, *jwk);
+        i = i + 1;
+    };
+    res
+}
+
+ + + +
+ + + +## Function `expire_jwks` + + + +
fun expire_jwks(self: &mut authenticator_state::AuthenticatorState, min_epoch: u64, ctx: &tx_context::TxContext)
+
+ + + +
+Implementation + + +
fun expire_jwks(
+    self: &mut AuthenticatorState,
+    // any jwk below this epoch is not retained
+    min_epoch: u64,
+    ctx: &TxContext) {
+    // This will only be called by mgo_system::advance_epoch
+    assert!(tx_context::sender(ctx) == @0x0, ENotSystemAddress);
+
+    let inner = load_inner_mut(self);
+
+    let len = vector::length(&inner.active_jwks);
+
+    // first we count how many jwks from each issuer are above the min_epoch
+    // and store the counts in a vector that parallels the (sorted) active_jwks vector
+    let issuer_max_epochs = vector[];
+    let i = 0;
+    let prev_issuer: Option<String> = option::none();
+
+    while (i < len) {
+        let cur = vector::borrow(&inner.active_jwks, i);
+        let cur_iss = &cur.jwk_id.iss;
+        if (option::is_none(&prev_issuer)) {
+            option::fill(&mut prev_issuer, *cur_iss);
+            vector::push_back(&mut issuer_max_epochs, cur.epoch);
+        } else {
+            if (cur_iss == option::borrow(&prev_issuer)) {
+                let back = vector::length(&issuer_max_epochs) - 1;
+                let prev_max_epoch = vector::borrow_mut(&mut issuer_max_epochs, back);
+                *prev_max_epoch = math::max(*prev_max_epoch, cur.epoch);
+            } else {
+                *option::borrow_mut(&mut prev_issuer) = *cur_iss;
+                vector::push_back(&mut issuer_max_epochs, cur.epoch);
+            }
+        };
+        i = i + 1;
+    };
+
+    // Now, filter out any JWKs that are below the min_epoch, unless that issuer has no
+    // JWKs >= the min_epoch, in which case we keep all of them.
+    let new_active_jwks: vector<ActiveJwk> = vector[];
+    let prev_issuer: Option<String> = option::none();
+    let i = 0;
+    let j = 0;
+    while (i < len) {
+        let jwk = vector::borrow(&inner.active_jwks, i);
+        let cur_iss = &jwk.jwk_id.iss;
+
+        if (option::is_none(&prev_issuer)) {
+            option::fill(&mut prev_issuer, *cur_iss);
+        } else if (cur_iss != option::borrow(&prev_issuer)) {
+            *option::borrow_mut(&mut prev_issuer) = *cur_iss;
+            j = j + 1;
+        };
+
+        let max_epoch_for_iss = vector::borrow(&issuer_max_epochs, j);
+
+        // TODO: if the iss for this jwk has *no* jwks that meet the minimum epoch,
+        // then expire nothing.
+        if (*max_epoch_for_iss < min_epoch || jwk.epoch >= min_epoch) {
+            vector::push_back(&mut new_active_jwks, *jwk);
+        };
+        i = i + 1;
+    };
+    inner.active_jwks = new_active_jwks;
+}
+
+ + + +
+ + + +## Function `get_active_jwks` + + + +
fun get_active_jwks(self: &authenticator_state::AuthenticatorState, ctx: &tx_context::TxContext): vector<authenticator_state::ActiveJwk>
+
+ + + +
+Implementation + + +
fun get_active_jwks(
+    self: &AuthenticatorState,
+    ctx: &TxContext,
+): vector<ActiveJwk> {
+    assert!(tx_context::sender(ctx) == @0x0, ENotSystemAddress);
+    load_inner(self).active_jwks
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/bag.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/bag.md new file mode 100644 index 00000000..55fa0673 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/bag.md @@ -0,0 +1,322 @@ + + + +# Module `0x2::bag` + + + +- [Resource `Bag`](#0x2_bag_Bag) +- [Constants](#@Constants_0) +- [Function `new`](#0x2_bag_new) +- [Function `add`](#0x2_bag_add) +- [Function `borrow`](#0x2_bag_borrow) +- [Function `borrow_mut`](#0x2_bag_borrow_mut) +- [Function `remove`](#0x2_bag_remove) +- [Function `contains`](#0x2_bag_contains) +- [Function `contains_with_type`](#0x2_bag_contains_with_type) +- [Function `length`](#0x2_bag_length) +- [Function `is_empty`](#0x2_bag_is_empty) +- [Function `destroy_empty`](#0x2_bag_destroy_empty) + + +
use 0x2::dynamic_field;
+use 0x2::object;
+use 0x2::tx_context;
+
+ + + + + +## Resource `Bag` + + + +
struct Bag has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+size: u64 +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const EBagNotEmpty: u64 = 0;
+
+ + + + + +## Function `new` + + + +
public fun new(ctx: &mut tx_context::TxContext): bag::Bag
+
+ + + +
+Implementation + + +
public fun new(ctx: &mut TxContext): Bag {
+    Bag {
+        id: object::new(ctx),
+        size: 0,
+    }
+}
+
+ + + +
+ + + +## Function `add` + + + +
public fun add<K: copy, drop, store, V: store>(bag: &mut bag::Bag, k: K, v: V)
+
+ + + +
+Implementation + + +
public fun add<K: copy + drop + store, V: store>(bag: &mut Bag, k: K, v: V) {
+    field::add(&mut bag.id, k, v);
+    bag.size = bag.size + 1;
+}
+
+ + + +
+ + + +## Function `borrow` + + + +
public fun borrow<K: copy, drop, store, V: store>(bag: &bag::Bag, k: K): &V
+
+ + + +
+Implementation + + +
public fun borrow<K: copy + drop + store, V: store>(bag: &Bag, k: K): &V {
+    field::borrow(&bag.id, k)
+}
+
+ + + +
+ + + +## Function `borrow_mut` + + + +
public fun borrow_mut<K: copy, drop, store, V: store>(bag: &mut bag::Bag, k: K): &mut V
+
+ + + +
+Implementation + + +
public fun borrow_mut<K: copy + drop + store, V: store>(bag: &mut Bag, k: K): &mut V {
+    field::borrow_mut(&mut bag.id, k)
+}
+
+ + + +
+ + + +## Function `remove` + + + +
public fun remove<K: copy, drop, store, V: store>(bag: &mut bag::Bag, k: K): V
+
+ + + +
+Implementation + + +
public fun remove<K: copy + drop + store, V: store>(bag: &mut Bag, k: K): V {
+    let v = field::remove(&mut bag.id, k);
+    bag.size = bag.size - 1;
+    v
+}
+
+ + + +
+ + + +## Function `contains` + + + +
public fun contains<K: copy, drop, store>(bag: &bag::Bag, k: K): bool
+
+ + + +
+Implementation + + +
public fun contains<K: copy + drop + store>(bag: &Bag, k: K): bool {
+    field::exists_<K>(&bag.id, k)
+}
+
+ + + +
+ + + +## Function `contains_with_type` + + + +
public fun contains_with_type<K: copy, drop, store, V: store>(bag: &bag::Bag, k: K): bool
+
+ + + +
+Implementation + + +
public fun contains_with_type<K: copy + drop + store, V: store>(bag: &Bag, k: K): bool {
+    field::exists_with_type<K, V>(&bag.id, k)
+}
+
+ + + +
+ + + +## Function `length` + + + +
public fun length(bag: &bag::Bag): u64
+
+ + + +
+Implementation + + +
public fun length(bag: &Bag): u64 {
+    bag.size
+}
+
+ + + +
+ + + +## Function `is_empty` + + + +
public fun is_empty(bag: &bag::Bag): bool
+
+ + + +
+Implementation + + +
public fun is_empty(bag: &Bag): bool {
+    bag.size == 0
+}
+
+ + + +
+ + + +## Function `destroy_empty` + + + +
public fun destroy_empty(bag: bag::Bag)
+
+ + + +
+Implementation + + +
public fun destroy_empty(bag: Bag) {
+    let Bag { id, size } = bag;
+    assert!(size == 0, EBagNotEmpty);
+    object::delete(id)
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/balance.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/balance.md new file mode 100644 index 00000000..22ee264e --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/balance.md @@ -0,0 +1,450 @@ + + + +# Module `0x2::balance` + + + +- [Struct `Supply`](#0x2_balance_Supply) +- [Struct `Balance`](#0x2_balance_Balance) +- [Constants](#@Constants_0) +- [Function `value`](#0x2_balance_value) +- [Function `supply_value`](#0x2_balance_supply_value) +- [Function `create_supply`](#0x2_balance_create_supply) +- [Function `increase_supply`](#0x2_balance_increase_supply) +- [Function `decrease_supply`](#0x2_balance_decrease_supply) +- [Function `zero`](#0x2_balance_zero) +- [Function `join`](#0x2_balance_join) +- [Function `split`](#0x2_balance_split) +- [Function `withdraw_all`](#0x2_balance_withdraw_all) +- [Function `destroy_zero`](#0x2_balance_destroy_zero) +- [Function `create_staking_rewards`](#0x2_balance_create_staking_rewards) +- [Function `destroy_storage_rebates`](#0x2_balance_destroy_storage_rebates) +- [Function `destroy_supply`](#0x2_balance_destroy_supply) + + +
use 0x2::tx_context;
+
+ + + + + +## Struct `Supply` + + + +
struct Supply<T> has store
+
+ + + +
+Fields + + +
+
+value: u64 +
+
+ +
+
+ + +
+ + + +## Struct `Balance` + + + +
struct Balance<T> has store
+
+ + + +
+Fields + + +
+
+value: u64 +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ENotSystemAddress: u64 = 3;
+
+ + + + + + + +
const ENonZero: u64 = 0;
+
+ + + + + + + +
const ENotEnough: u64 = 2;
+
+ + + + + + + +
const EOverflow: u64 = 1;
+
+ + + + + +## Function `value` + + + +
public fun value<T>(self: &balance::Balance<T>): u64
+
+ + + +
+Implementation + + +
public fun value<T>(self: &Balance<T>): u64 {
+    self.value
+}
+
+ + + +
+ + + +## Function `supply_value` + + + +
public fun supply_value<T>(supply: &balance::Supply<T>): u64
+
+ + + +
+Implementation + + +
public fun supply_value<T>(supply: &Supply<T>): u64 {
+    supply.value
+}
+
+ + + +
+ + + +## Function `create_supply` + + + +
public fun create_supply<T: drop>(_: T): balance::Supply<T>
+
+ + + +
+Implementation + + +
public fun create_supply<T: drop>(_: T): Supply<T> {
+    Supply { value: 0 }
+}
+
+ + + +
+ + + +## Function `increase_supply` + + + +
public fun increase_supply<T>(self: &mut balance::Supply<T>, value: u64): balance::Balance<T>
+
+ + + +
+Implementation + + +
public fun increase_supply<T>(self: &mut Supply<T>, value: u64): Balance<T> {
+    assert!(value < (18446744073709551615u64 - self.value), EOverflow);
+    self.value = self.value + value;
+    Balance { value }
+}
+
+ + + +
+ + + +## Function `decrease_supply` + + + +
public fun decrease_supply<T>(self: &mut balance::Supply<T>, balance: balance::Balance<T>): u64
+
+ + + +
+Implementation + + +
public fun decrease_supply<T>(self: &mut Supply<T>, balance: Balance<T>): u64 {
+    let Balance { value } = balance;
+    assert!(self.value >= value, EOverflow);
+    self.value = self.value - value;
+    value
+}
+
+ + + +
+ + + +## Function `zero` + + + +
public fun zero<T>(): balance::Balance<T>
+
+ + + +
+Implementation + + +
public fun zero<T>(): Balance<T> {
+    Balance { value: 0 }
+}
+
+ + + +
+ + + +## Function `join` + + + +
public fun join<T>(self: &mut balance::Balance<T>, balance: balance::Balance<T>): u64
+
+ + + +
+Implementation + + +
public fun join<T>(self: &mut Balance<T>, balance: Balance<T>): u64 {
+    let Balance { value } = balance;
+    self.value = self.value + value;
+    self.value
+}
+
+ + + +
+ + + +## Function `split` + + + +
public fun split<T>(self: &mut balance::Balance<T>, value: u64): balance::Balance<T>
+
+ + + +
+Implementation + + +
public fun split<T>(self: &mut Balance<T>, value: u64): Balance<T> {
+    assert!(self.value >= value, ENotEnough);
+    self.value = self.value - value;
+    Balance { value }
+}
+
+ + + +
+ + + +## Function `withdraw_all` + + + +
public fun withdraw_all<T>(self: &mut balance::Balance<T>): balance::Balance<T>
+
+ + + +
+Implementation + + +
public fun withdraw_all<T>(self: &mut Balance<T>): Balance<T> {
+    let value = self.value;
+    split(self, value)
+}
+
+ + + +
+ + + +## Function `destroy_zero` + + + +
public fun destroy_zero<T>(balance: balance::Balance<T>)
+
+ + + +
+Implementation + + +
public fun destroy_zero<T>(balance: Balance<T>) {
+    assert!(balance.value == 0, ENonZero);
+    let Balance { value: _ } = balance;
+}
+
+ + + +
+ + + +## Function `create_staking_rewards` + + + +
fun create_staking_rewards<T>(value: u64, ctx: &tx_context::TxContext): balance::Balance<T>
+
+ + + +
+Implementation + + +
fun create_staking_rewards<T>(value: u64, ctx: &TxContext): Balance<T> {
+    assert!(tx_context::sender(ctx) == @0x0, ENotSystemAddress);
+    Balance { value }
+}
+
+ + + +
+ + + +## Function `destroy_storage_rebates` + + + +
fun destroy_storage_rebates<T>(self: balance::Balance<T>, ctx: &tx_context::TxContext)
+
+ + + +
+Implementation + + +
fun destroy_storage_rebates<T>(self: Balance<T>, ctx: &TxContext) {
+    assert!(tx_context::sender(ctx) == @0x0, ENotSystemAddress);
+    let Balance { value: _ } = self;
+}
+
+ + + +
+ + + +## Function `destroy_supply` + + + +
public(friend) fun destroy_supply<T>(self: balance::Supply<T>): u64
+
+ + + +
+Implementation + + +
public(friend) fun destroy_supply<T>(self: Supply<T>): u64 {
+    let Supply { value } = self;
+    value
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/clock.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/clock.md new file mode 100644 index 00000000..66a40346 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/clock.md @@ -0,0 +1,154 @@ + + + +# Module `0x2::clock` + + + +- [Resource `Clock`](#0x2_clock_Clock) +- [Constants](#@Constants_0) +- [Function `timestamp_ms`](#0x2_clock_timestamp_ms) +- [Function `create`](#0x2_clock_create) +- [Function `consensus_commit_prologue`](#0x2_clock_consensus_commit_prologue) + + +
use 0x2::object;
+use 0x2::transfer;
+use 0x2::tx_context;
+
+ + + + + +## Resource `Clock` + + + +
struct Clock has key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+timestamp_ms: u64 +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ENotSystemAddress: u64 = 0;
+
+ + + + + +## Function `timestamp_ms` + + + +
public fun timestamp_ms(clock: &clock::Clock): u64
+
+ + + +
+Implementation + + +
public fun timestamp_ms(clock: &Clock): u64 {
+    clock.timestamp_ms
+}
+
+ + + +
+ + + +## Function `create` + + + +
fun create(ctx: &tx_context::TxContext)
+
+ + + +
+Implementation + + +
fun create(ctx: &TxContext) {
+    assert!(tx_context::sender(ctx) == @0x0, ENotSystemAddress);
+
+    transfer::share_object(Clock {
+        id: object::clock(),
+        // Initialised to zero, but set to a real timestamp by a
+        // system transaction before it can be witnessed by a move
+        // call.
+        timestamp_ms: 0,
+    })
+}
+
+ + + +
+ + + +## Function `consensus_commit_prologue` + + + +
fun consensus_commit_prologue(clock: &mut clock::Clock, timestamp_ms: u64, ctx: &tx_context::TxContext)
+
+ + + +
+Implementation + + +
fun consensus_commit_prologue(
+    clock: &mut Clock,
+    timestamp_ms: u64,
+    ctx: &TxContext,
+) {
+    // Validator will make a special system call with sender set as 0x0.
+    assert!(tx_context::sender(ctx) == @0x0, ENotSystemAddress);
+
+    clock.timestamp_ms = timestamp_ms
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/coin.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/coin.md new file mode 100644 index 00000000..d473296f --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/coin.md @@ -0,0 +1,1293 @@ + + + +# Module `0x2::coin` + + + +- [Resource `Coin`](#0x2_coin_Coin) +- [Resource `CoinMetadata`](#0x2_coin_CoinMetadata) +- [Resource `RegulatedCoinMetadata`](#0x2_coin_RegulatedCoinMetadata) +- [Resource `TreasuryCap`](#0x2_coin_TreasuryCap) +- [Resource `DenyCap`](#0x2_coin_DenyCap) +- [Struct `CurrencyCreated`](#0x2_coin_CurrencyCreated) +- [Constants](#@Constants_0) +- [Function `total_supply`](#0x2_coin_total_supply) +- [Function `treasury_into_supply`](#0x2_coin_treasury_into_supply) +- [Function `supply_immut`](#0x2_coin_supply_immut) +- [Function `supply_mut`](#0x2_coin_supply_mut) +- [Function `value`](#0x2_coin_value) +- [Function `balance`](#0x2_coin_balance) +- [Function `balance_mut`](#0x2_coin_balance_mut) +- [Function `from_balance`](#0x2_coin_from_balance) +- [Function `into_balance`](#0x2_coin_into_balance) +- [Function `take`](#0x2_coin_take) +- [Function `put`](#0x2_coin_put) +- [Function `join`](#0x2_coin_join) +- [Function `split`](#0x2_coin_split) +- [Function `divide_into_n`](#0x2_coin_divide_into_n) +- [Function `zero`](#0x2_coin_zero) +- [Function `destroy_zero`](#0x2_coin_destroy_zero) +- [Function `create_currency`](#0x2_coin_create_currency) +- [Function `create_regulated_currency`](#0x2_coin_create_regulated_currency) +- [Function `mint`](#0x2_coin_mint) +- [Function `mint_balance`](#0x2_coin_mint_balance) +- [Function `burn`](#0x2_coin_burn) +- [Function `deny_list_add`](#0x2_coin_deny_list_add) +- [Function `deny_list_remove`](#0x2_coin_deny_list_remove) +- [Function `deny_list_contains`](#0x2_coin_deny_list_contains) +- [Function `mint_and_transfer`](#0x2_coin_mint_and_transfer) +- [Function `update_name`](#0x2_coin_update_name) +- [Function `update_symbol`](#0x2_coin_update_symbol) +- [Function `update_description`](#0x2_coin_update_description) +- [Function `update_icon_url`](#0x2_coin_update_icon_url) +- [Function `get_decimals`](#0x2_coin_get_decimals) +- [Function `get_name`](#0x2_coin_get_name) +- [Function `get_symbol`](#0x2_coin_get_symbol) +- [Function `get_description`](#0x2_coin_get_description) +- [Function `get_icon_url`](#0x2_coin_get_icon_url) +- [Function `supply`](#0x2_coin_supply) + + +
use 0x1::ascii;
+use 0x1::option;
+use 0x1::string;
+use 0x1::type_name;
+use 0x2::balance;
+use 0x2::deny_list;
+use 0x2::object;
+use 0x2::transfer;
+use 0x2::tx_context;
+use 0x2::types;
+use 0x2::url;
+
+ + + + + +## Resource `Coin` + + + +
struct Coin<T> has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+balance: balance::Balance<T> +
+
+ +
+
+ + +
+ + + +## Resource `CoinMetadata` + + + +
struct CoinMetadata<T> has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+decimals: u8 +
+
+ +
+
+name: string::String +
+
+ +
+
+symbol: ascii::String +
+
+ +
+
+description: string::String +
+
+ +
+
+icon_url: option::Option<url::Url> +
+
+ +
+
+ + +
+ + + +## Resource `RegulatedCoinMetadata` + + + +
struct RegulatedCoinMetadata<T> has key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+coin_metadata_object: object::ID +
+
+ +
+
+deny_cap_object: object::ID +
+
+ +
+
+ + +
+ + + +## Resource `TreasuryCap` + + + +
struct TreasuryCap<T> has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+total_supply: balance::Supply<T> +
+
+ +
+
+ + +
+ + + +## Resource `DenyCap` + + + +
struct DenyCap<T> has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+ + +
+ + + +## Struct `CurrencyCreated` + + + +
struct CurrencyCreated<T> has copy, drop
+
+ + + +
+Fields + + +
+
+decimals: u8 +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ENotEnough: u64 = 2;
+
+ + + + + + + +
const DENY_LIST_COIN_INDEX: u64 = 0;
+
+ + + + + + + +
const EBadWitness: u64 = 0;
+
+ + + + + + + +
const EInvalidArg: u64 = 1;
+
+ + + + + +## Function `total_supply` + + + +
public fun total_supply<T>(cap: &coin::TreasuryCap<T>): u64
+
+ + + +
+Implementation + + +
public fun total_supply<T>(cap: &TreasuryCap<T>): u64 {
+    balance::supply_value(&cap.total_supply)
+}
+
+ + + +
+ + + +## Function `treasury_into_supply` + + + +
public fun treasury_into_supply<T>(treasury: coin::TreasuryCap<T>): balance::Supply<T>
+
+ + + +
+Implementation + + +
public fun treasury_into_supply<T>(treasury: TreasuryCap<T>): Supply<T> {
+    let TreasuryCap { id, total_supply } = treasury;
+    object::delete(id);
+    total_supply
+}
+
+ + + +
+ + + +## Function `supply_immut` + + + +
public fun supply_immut<T>(treasury: &coin::TreasuryCap<T>): &balance::Supply<T>
+
+ + + +
+Implementation + + +
public fun supply_immut<T>(treasury: &TreasuryCap<T>): &Supply<T> {
+    &treasury.total_supply
+}
+
+ + + +
+ + + +## Function `supply_mut` + + + +
public fun supply_mut<T>(treasury: &mut coin::TreasuryCap<T>): &mut balance::Supply<T>
+
+ + + +
+Implementation + + +
public fun supply_mut<T>(treasury: &mut TreasuryCap<T>): &mut Supply<T> {
+    &mut treasury.total_supply
+}
+
+ + + +
+ + + +## Function `value` + + + +
public fun value<T>(self: &coin::Coin<T>): u64
+
+ + + +
+Implementation + + +
public fun value<T>(self: &Coin<T>): u64 {
+    balance::value(&self.balance)
+}
+
+ + + +
+ + + +## Function `balance` + + + +
public fun balance<T>(coin: &coin::Coin<T>): &balance::Balance<T>
+
+ + + +
+Implementation + + +
public fun balance<T>(coin: &Coin<T>): &Balance<T> {
+    &coin.balance
+}
+
+ + + +
+ + + +## Function `balance_mut` + + + +
public fun balance_mut<T>(coin: &mut coin::Coin<T>): &mut balance::Balance<T>
+
+ + + +
+Implementation + + +
public fun balance_mut<T>(coin: &mut Coin<T>): &mut Balance<T> {
+    &mut coin.balance
+}
+
+ + + +
+ + + +## Function `from_balance` + + + +
public fun from_balance<T>(balance: balance::Balance<T>, ctx: &mut tx_context::TxContext): coin::Coin<T>
+
+ + + +
+Implementation + + +
public fun from_balance<T>(balance: Balance<T>, ctx: &mut TxContext): Coin<T> {
+    Coin { id: object::new(ctx), balance }
+}
+
+ + + +
+ + + +## Function `into_balance` + + + +
public fun into_balance<T>(coin: coin::Coin<T>): balance::Balance<T>
+
+ + + +
+Implementation + + +
public fun into_balance<T>(coin: Coin<T>): Balance<T> {
+    let Coin { id, balance } = coin;
+    object::delete(id);
+    balance
+}
+
+ + + +
+ + + +## Function `take` + + + +
public fun take<T>(balance: &mut balance::Balance<T>, value: u64, ctx: &mut tx_context::TxContext): coin::Coin<T>
+
+ + + +
+Implementation + + +
public fun take<T>(
+    balance: &mut Balance<T>, value: u64, ctx: &mut TxContext,
+): Coin<T> {
+    Coin {
+        id: object::new(ctx),
+        balance: balance::split(balance, value)
+    }
+}
+
+ + + +
+ + + +## Function `put` + + + +
public fun put<T>(balance: &mut balance::Balance<T>, coin: coin::Coin<T>)
+
+ + + +
+Implementation + + +
public fun put<T>(balance: &mut Balance<T>, coin: Coin<T>) {
+    balance::join(balance, into_balance(coin));
+}
+
+ + + +
+ + + +## Function `join` + + + +
public entry fun join<T>(self: &mut coin::Coin<T>, c: coin::Coin<T>)
+
+ + + +
+Implementation + + +
public entry fun join<T>(self: &mut Coin<T>, c: Coin<T>) {
+    let Coin { id, balance } = c;
+    object::delete(id);
+    balance::join(&mut self.balance, balance);
+}
+
+ + + +
+ + + +## Function `split` + + + +
public fun split<T>(self: &mut coin::Coin<T>, split_amount: u64, ctx: &mut tx_context::TxContext): coin::Coin<T>
+
+ + + +
+Implementation + + +
public fun split<T>(
+    self: &mut Coin<T>, split_amount: u64, ctx: &mut TxContext
+): Coin<T> {
+    take(&mut self.balance, split_amount, ctx)
+}
+
+ + + +
+ + + +## Function `divide_into_n` + + + +
public fun divide_into_n<T>(self: &mut coin::Coin<T>, n: u64, ctx: &mut tx_context::TxContext): vector<coin::Coin<T>>
+
+ + + +
+Implementation + + +
public fun divide_into_n<T>(
+    self: &mut Coin<T>, n: u64, ctx: &mut TxContext
+): vector<Coin<T>> {
+    assert!(n > 0, EInvalidArg);
+    assert!(n <= value(self), ENotEnough);
+
+    let vec = vector::empty<Coin<T>>();
+    let i = 0;
+    let split_amount = value(self) / n;
+    while (i < n - 1) {
+        vector::push_back(&mut vec, split(self, split_amount, ctx));
+        i = i + 1;
+    };
+    vec
+}
+
+ + + +
+ + + +## Function `zero` + + + +
public fun zero<T>(ctx: &mut tx_context::TxContext): coin::Coin<T>
+
+ + + +
+Implementation + + +
public fun zero<T>(ctx: &mut TxContext): Coin<T> {
+    Coin { id: object::new(ctx), balance: balance::zero() }
+}
+
+ + + +
+ + + +## Function `destroy_zero` + + + +
public fun destroy_zero<T>(c: coin::Coin<T>)
+
+ + + +
+Implementation + + +
public fun destroy_zero<T>(c: Coin<T>) {
+    let Coin { id, balance } = c;
+    object::delete(id);
+    balance::destroy_zero(balance)
+}
+
+ + + +
+ + + +## Function `create_currency` + + + +
public fun create_currency<T: drop>(witness: T, decimals: u8, symbol: vector<u8>, name: vector<u8>, description: vector<u8>, icon_url: option::Option<url::Url>, ctx: &mut tx_context::TxContext): (coin::TreasuryCap<T>, coin::CoinMetadata<T>)
+
+ + + +
+Implementation + + +
public fun create_currency<T: drop>(
+    witness: T,
+    decimals: u8,
+    symbol: vector<u8>,
+    name: vector<u8>,
+    description: vector<u8>,
+    icon_url: Option<Url>,
+    ctx: &mut TxContext
+): (TreasuryCap<T>, CoinMetadata<T>) {
+    // Make sure there's only one instance of the type T
+    assert!(mgo::types::is_one_time_witness(&witness), EBadWitness);
+
+    (
+        TreasuryCap {
+            id: object::new(ctx),
+            total_supply: balance::create_supply(witness)
+        },
+        CoinMetadata {
+            id: object::new(ctx),
+            decimals,
+            name: string::utf8(name),
+            symbol: ascii::string(symbol),
+            description: string::utf8(description),
+            icon_url
+        }
+    )
+}
+
+ + + +
+ + + +## Function `create_regulated_currency` + + + +
public fun create_regulated_currency<T: drop>(witness: T, decimals: u8, symbol: vector<u8>, name: vector<u8>, description: vector<u8>, icon_url: option::Option<url::Url>, ctx: &mut tx_context::TxContext): (coin::TreasuryCap<T>, coin::DenyCap<T>, coin::CoinMetadata<T>)
+
+ + + +
+Implementation + + +
public fun create_regulated_currency<T: drop>(
+    witness: T,
+    decimals: u8,
+    symbol: vector<u8>,
+    name: vector<u8>,
+    description: vector<u8>,
+    icon_url: Option<Url>,
+    ctx: &mut TxContext
+): (TreasuryCap<T>, DenyCap<T>, CoinMetadata<T>) {
+    let (treasury_cap, metadata) = create_currency(
+        witness,
+        decimals,
+        symbol,
+        name,
+        description,
+        icon_url,
+        ctx
+    );
+    let deny_cap = DenyCap {
+        id: object::new(ctx),
+    };
+    transfer::freeze_object(RegulatedCoinMetadata<T> {
+        id: object::new(ctx),
+        coin_metadata_object: object::id(&metadata),
+        deny_cap_object: object::id(&deny_cap),
+    });
+    (treasury_cap, deny_cap, metadata)
+}
+
+ + + +
+ + + +## Function `mint` + + + +
public fun mint<T>(cap: &mut coin::TreasuryCap<T>, value: u64, ctx: &mut tx_context::TxContext): coin::Coin<T>
+
+ + + +
+Implementation + + +
public fun mint<T>(
+    cap: &mut TreasuryCap<T>, value: u64, ctx: &mut TxContext,
+): Coin<T> {
+    Coin {
+        id: object::new(ctx),
+        balance: balance::increase_supply(&mut cap.total_supply, value)
+    }
+}
+
+ + + +
+ + + +## Function `mint_balance` + + + +
public fun mint_balance<T>(cap: &mut coin::TreasuryCap<T>, value: u64): balance::Balance<T>
+
+ + + +
+Implementation + + +
public fun mint_balance<T>(
+    cap: &mut TreasuryCap<T>, value: u64
+): Balance<T> {
+    balance::increase_supply(&mut cap.total_supply, value)
+}
+
+ + + +
+ + + +## Function `burn` + + + +
public entry fun burn<T>(cap: &mut coin::TreasuryCap<T>, c: coin::Coin<T>): u64
+
+ + + +
+Implementation + + +
public entry fun burn<T>(cap: &mut TreasuryCap<T>, c: Coin<T>): u64 {
+    let Coin { id, balance } = c;
+    object::delete(id);
+    balance::decrease_supply(&mut cap.total_supply, balance)
+}
+
+ + + +
+ + + +## Function `deny_list_add` + + + +
public fun deny_list_add<T>(deny_list: &mut deny_list::DenyList, _deny_cap: &mut coin::DenyCap<T>, addr: address, _ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public fun deny_list_add<T>(
+   deny_list: &mut DenyList,
+   _deny_cap: &mut DenyCap<T>,
+   addr: address,
+   _ctx: &mut TxContext
+) {
+    let type =
+        ascii::into_bytes(type_name::into_string(type_name::get_with_original_ids<T>()));
+    deny_list::add(
+        deny_list,
+        DENY_LIST_COIN_INDEX,
+        type,
+        addr,
+    )
+}
+
+ + + +
+ + + +## Function `deny_list_remove` + + + +
public fun deny_list_remove<T>(deny_list: &mut deny_list::DenyList, _deny_cap: &mut coin::DenyCap<T>, addr: address, _ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public fun deny_list_remove<T>(
+   deny_list: &mut DenyList,
+   _deny_cap: &mut DenyCap<T>,
+   addr: address,
+   _ctx: &mut TxContext
+) {
+    let type =
+        ascii::into_bytes(type_name::into_string(type_name::get_with_original_ids<T>()));
+    deny_list::remove(
+        deny_list,
+        DENY_LIST_COIN_INDEX,
+        type,
+        addr,
+    )
+}
+
+ + + +
+ + + +## Function `deny_list_contains` + + + +
public fun deny_list_contains<T>(freezer: &deny_list::DenyList, addr: address): bool
+
+ + + +
+Implementation + + +
public fun deny_list_contains<T>(
+   freezer: &DenyList,
+   addr: address,
+): bool {
+    let name = type_name::get_with_original_ids<T>();
+    if (type_name::is_primitive(&name)) return false;
+
+    let type = ascii::into_bytes(type_name::into_string(name));
+    deny_list::contains(
+        freezer,
+        DENY_LIST_COIN_INDEX,
+        type,
+        addr,
+    )
+}
+
+ + + +
+ + + +## Function `mint_and_transfer` + + + +
public entry fun mint_and_transfer<T>(c: &mut coin::TreasuryCap<T>, amount: u64, recipient: address, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun mint_and_transfer<T>(
+    c: &mut TreasuryCap<T>, amount: u64, recipient: address, ctx: &mut TxContext
+) {
+    transfer::public_transfer(mint(c, amount, ctx), recipient)
+}
+
+ + + +
+ + + +## Function `update_name` + + + +
public entry fun update_name<T>(_treasury: &coin::TreasuryCap<T>, metadata: &mut coin::CoinMetadata<T>, name: string::String)
+
+ + + +
+Implementation + + +
public entry fun update_name<T>(
+    _treasury: &TreasuryCap<T>, metadata: &mut CoinMetadata<T>, name: string::String
+) {
+    metadata.name = name;
+}
+
+ + + +
+ + + +## Function `update_symbol` + + + +
public entry fun update_symbol<T>(_treasury: &coin::TreasuryCap<T>, metadata: &mut coin::CoinMetadata<T>, symbol: ascii::String)
+
+ + + +
+Implementation + + +
public entry fun update_symbol<T>(
+    _treasury: &TreasuryCap<T>, metadata: &mut CoinMetadata<T>, symbol: ascii::String
+) {
+    metadata.symbol = symbol;
+}
+
+ + + +
+ + + +## Function `update_description` + + + +
public entry fun update_description<T>(_treasury: &coin::TreasuryCap<T>, metadata: &mut coin::CoinMetadata<T>, description: string::String)
+
+ + + +
+Implementation + + +
public entry fun update_description<T>(
+    _treasury: &TreasuryCap<T>, metadata: &mut CoinMetadata<T>, description: string::String
+) {
+    metadata.description = description;
+}
+
+ + + +
+ + + +## Function `update_icon_url` + + + +
public entry fun update_icon_url<T>(_treasury: &coin::TreasuryCap<T>, metadata: &mut coin::CoinMetadata<T>, url: ascii::String)
+
+ + + +
+Implementation + + +
public entry fun update_icon_url<T>(
+    _treasury: &TreasuryCap<T>, metadata: &mut CoinMetadata<T>, url: ascii::String
+) {
+    metadata.icon_url = option::some(url::new_unsafe(url));
+}
+
+ + + +
+ + + +## Function `get_decimals` + + + +
public fun get_decimals<T>(metadata: &coin::CoinMetadata<T>): u8
+
+ + + +
+Implementation + + +
public fun get_decimals<T>(metadata: &CoinMetadata<T>): u8 {
+    metadata.decimals
+}
+
+ + + +
+ + + +## Function `get_name` + + + +
public fun get_name<T>(metadata: &coin::CoinMetadata<T>): string::String
+
+ + + +
+Implementation + + +
public fun get_name<T>(metadata: &CoinMetadata<T>): string::String {
+    metadata.name
+}
+
+ + + +
+ + + +## Function `get_symbol` + + + +
public fun get_symbol<T>(metadata: &coin::CoinMetadata<T>): ascii::String
+
+ + + +
+Implementation + + +
public fun get_symbol<T>(metadata: &CoinMetadata<T>): ascii::String {
+    metadata.symbol
+}
+
+ + + +
+ + + +## Function `get_description` + + + +
public fun get_description<T>(metadata: &coin::CoinMetadata<T>): string::String
+
+ + + +
+Implementation + + +
public fun get_description<T>(metadata: &CoinMetadata<T>): string::String {
+    metadata.description
+}
+
+ + + +
+ + + +## Function `get_icon_url` + + + +
public fun get_icon_url<T>(metadata: &coin::CoinMetadata<T>): option::Option<url::Url>
+
+ + + +
+Implementation + + +
public fun get_icon_url<T>(metadata: &CoinMetadata<T>): Option<Url> {
+    metadata.icon_url
+}
+
+ + + +
+ + + +## Function `supply` + + + +
public fun supply<T>(treasury: &mut coin::TreasuryCap<T>): &balance::Supply<T>
+
+ + + +
+Implementation + + +
public fun supply<T>(treasury: &mut TreasuryCap<T>): &Supply<T> {
+    &treasury.total_supply
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/deny_list.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/deny_list.md new file mode 100644 index 00000000..9a4376fc --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/deny_list.md @@ -0,0 +1,391 @@ + + + +# Module `0x2::deny_list` + + + +- [Resource `DenyList`](#0x2_deny_list_DenyList) +- [Resource `PerTypeList`](#0x2_deny_list_PerTypeList) +- [Constants](#@Constants_0) +- [Function `add`](#0x2_deny_list_add) +- [Function `per_type_list_add`](#0x2_deny_list_per_type_list_add) +- [Function `remove`](#0x2_deny_list_remove) +- [Function `per_type_list_remove`](#0x2_deny_list_per_type_list_remove) +- [Function `contains`](#0x2_deny_list_contains) +- [Function `per_type_list_contains`](#0x2_deny_list_per_type_list_contains) +- [Function `create`](#0x2_deny_list_create) +- [Function `per_type_list`](#0x2_deny_list_per_type_list) + + +
use 0x2::bag;
+use 0x2::object;
+use 0x2::table;
+use 0x2::transfer;
+use 0x2::tx_context;
+use 0x2::vec_set;
+
+ + + + + +## Resource `DenyList` + + + +
struct DenyList has key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+lists: bag::Bag +
+
+ +
+
+ + +
+ + + +## Resource `PerTypeList` + + + +
struct PerTypeList has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+denied_count: table::Table<address, u64> +
+
+ +
+
+denied_addresses: table::Table<vector<u8>, vec_set::VecSet<address>> +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ENotSystemAddress: u64 = 0;
+
+ + + + + + + +
const COIN_INDEX: u64 = 0;
+
+ + + + + + + +
const ENotDenied: u64 = 1;
+
+ + + + + +## Function `add` + + + +
public(friend) fun add(deny_list: &mut deny_list::DenyList, per_type_index: u64, type: vector<u8>, addr: address)
+
+ + + +
+Implementation + + +
public(friend) fun add(
+    deny_list: &mut DenyList,
+    per_type_index: u64,
+    type: vector<u8>,
+    addr: address,
+) {
+    per_type_list_add(bag::borrow_mut(&mut deny_list.lists, per_type_index), type, addr)
+}
+
+ + + +
+ + + +## Function `per_type_list_add` + + + +
fun per_type_list_add(list: &mut deny_list::PerTypeList, type: vector<u8>, addr: address)
+
+ + + +
+Implementation + + +
fun per_type_list_add(
+    list: &mut PerTypeList,
+    type: vector<u8>,
+    addr: address,
+) {
+    if (!table::contains(&list.denied_addresses, type)) {
+        table::add(&mut list.denied_addresses, type, vec_set::empty());
+    };
+    let denied_addresses = table::borrow_mut(&mut list.denied_addresses, type);
+    let already_denied = vec_set::contains(denied_addresses, &addr);
+    if (already_denied) return;
+
+    vec_set::insert(denied_addresses, addr);
+    if (!table::contains(&list.denied_count, addr)) {
+        table::add(&mut list.denied_count, addr, 0);
+    };
+    let denied_count = table::borrow_mut(&mut list.denied_count, addr);
+    *denied_count = *denied_count + 1;
+}
+
+ + + +
+ + + +## Function `remove` + + + +
public(friend) fun remove(deny_list: &mut deny_list::DenyList, per_type_index: u64, type: vector<u8>, addr: address)
+
+ + + +
+Implementation + + +
public(friend) fun remove(
+    deny_list: &mut DenyList,
+    per_type_index: u64,
+    type: vector<u8>,
+    addr: address,
+) {
+    per_type_list_remove(bag::borrow_mut(&mut deny_list.lists, per_type_index), type, addr)
+}
+
+ + + +
+ + + +## Function `per_type_list_remove` + + + +
fun per_type_list_remove(list: &mut deny_list::PerTypeList, type: vector<u8>, addr: address)
+
+ + + +
+Implementation + + +
fun per_type_list_remove(
+    list: &mut PerTypeList,
+    type: vector<u8>,
+    addr: address,
+) {
+    let denied_addresses = table::borrow_mut(&mut list.denied_addresses, type);
+    assert!(vec_set::contains(denied_addresses, &addr), ENotDenied);
+    vec_set::remove(denied_addresses, &addr);
+    let denied_count = table::borrow_mut(&mut list.denied_count, addr);
+    *denied_count = *denied_count - 1;
+    if (*denied_count == 0) {
+        table::remove(&mut list.denied_count, addr);
+    }
+}
+
+ + + +
+ + + +## Function `contains` + + + +
public(friend) fun contains(deny_list: &deny_list::DenyList, per_type_index: u64, type: vector<u8>, addr: address): bool
+
+ + + +
+Implementation + + +
public(friend) fun contains(
+    deny_list: &DenyList,
+    per_type_index: u64,
+    type: vector<u8>,
+    addr: address,
+): bool {
+    per_type_list_contains(bag::borrow(&deny_list.lists, per_type_index), type, addr)
+}
+
+ + + +
+ + + +## Function `per_type_list_contains` + + + +
fun per_type_list_contains(list: &deny_list::PerTypeList, type: vector<u8>, addr: address): bool
+
+ + + +
+Implementation + + +
fun per_type_list_contains(
+    list: &PerTypeList,
+    type: vector<u8>,
+    addr: address,
+): bool {
+    if (!table::contains(&list.denied_count, addr)) return false;
+
+    let denied_count = table::borrow(&list.denied_count, addr);
+    if (*denied_count == 0) return false;
+
+    if (!table::contains(&list.denied_addresses, type)) return false;
+
+    let denied_addresses = table::borrow(&list.denied_addresses, type);
+    vec_set::contains(denied_addresses, &addr)
+}
+
+ + + +
+ + + +## Function `create` + + + +
fun create(ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
fun create(ctx: &mut TxContext) {
+    assert!(tx_context::sender(ctx) == @0x0, ENotSystemAddress);
+
+    let lists = bag::new(ctx);
+    bag::add(&mut lists, COIN_INDEX, per_type_list(ctx));
+    let deny_list_object = DenyList {
+        id: object::mgo_deny_list_object_id(),
+        lists,
+    };
+    transfer::share_object(deny_list_object);
+}
+
+ + + +
+ + + +## Function `per_type_list` + + + +
fun per_type_list(ctx: &mut tx_context::TxContext): deny_list::PerTypeList
+
+ + + +
+Implementation + + +
fun per_type_list(ctx: &mut TxContext): PerTypeList {
+    PerTypeList {
+        id: object::new(ctx),
+        denied_count: table::new(ctx),
+        denied_addresses: table::new(ctx),
+    }
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/display.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/display.md new file mode 100644 index 00000000..95e1780a --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/display.md @@ -0,0 +1,516 @@ + + + +# Module `0x2::display` + + + +- [Resource `Display`](#0x2_display_Display) +- [Struct `DisplayCreated`](#0x2_display_DisplayCreated) +- [Struct `VersionUpdated`](#0x2_display_VersionUpdated) +- [Constants](#@Constants_0) +- [Function `new`](#0x2_display_new) +- [Function `new_with_fields`](#0x2_display_new_with_fields) +- [Function `create_and_keep`](#0x2_display_create_and_keep) +- [Function `update_version`](#0x2_display_update_version) +- [Function `add`](#0x2_display_add) +- [Function `add_multiple`](#0x2_display_add_multiple) +- [Function `edit`](#0x2_display_edit) +- [Function `remove`](#0x2_display_remove) +- [Function `is_authorized`](#0x2_display_is_authorized) +- [Function `version`](#0x2_display_version) +- [Function `fields`](#0x2_display_fields) +- [Function `create_internal`](#0x2_display_create_internal) +- [Function `add_internal`](#0x2_display_add_internal) + + +
use 0x1::string;
+use 0x2::event;
+use 0x2::object;
+use 0x2::package;
+use 0x2::transfer;
+use 0x2::tx_context;
+use 0x2::vec_map;
+
+ + + + + +## Resource `Display` + + + +
struct Display<T: key> has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+fields: vec_map::VecMap<string::String, string::String> +
+
+ +
+
+version: u16 +
+
+ +
+
+ + +
+ + + +## Struct `DisplayCreated` + + + +
struct DisplayCreated<T: key> has copy, drop
+
+ + + +
+Fields + + +
+
+id: object::ID +
+
+ +
+
+ + +
+ + + +## Struct `VersionUpdated` + + + +
struct VersionUpdated<T: key> has copy, drop
+
+ + + +
+Fields + + +
+
+id: object::ID +
+
+ +
+
+version: u16 +
+
+ +
+
+fields: vec_map::VecMap<string::String, string::String> +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ENotOwner: u64 = 0;
+
+ + + + + + + +
const EVecLengthMismatch: u64 = 1;
+
+ + + + + +## Function `new` + + + +
public fun new<T: key>(pub: &package::Publisher, ctx: &mut tx_context::TxContext): display::Display<T>
+
+ + + +
+Implementation + + +
public fun new<T: key>(pub: &Publisher, ctx: &mut TxContext): Display<T> {
+    assert!(is_authorized<T>(pub), ENotOwner);
+    create_internal(ctx)
+}
+
+ + + +
+ + + +## Function `new_with_fields` + + + +
public fun new_with_fields<T: key>(pub: &package::Publisher, fields: vector<string::String>, values: vector<string::String>, ctx: &mut tx_context::TxContext): display::Display<T>
+
+ + + +
+Implementation + + +
public fun new_with_fields<T: key>(
+    pub: &Publisher, fields: vector<String>, values: vector<String>, ctx: &mut TxContext
+): Display<T> {
+    let len = vector::length(&fields);
+    assert!(len == vector::length(&values), EVecLengthMismatch);
+
+    let i = 0;
+    let display = new<T>(pub, ctx);
+    while (i < len) {
+        add_internal(&mut display, *vector::borrow(&fields, i), *vector::borrow(&values, i));
+        i = i + 1;
+    };
+
+    display
+}
+
+ + + +
+ + + +## Function `create_and_keep` + + + +
public entry fun create_and_keep<T: key>(pub: &package::Publisher, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
entry public fun create_and_keep<T: key>(pub: &Publisher, ctx: &mut TxContext) {
+    transfer::public_transfer(new<T>(pub, ctx), sender(ctx))
+}
+
+ + + +
+ + + +## Function `update_version` + + + +
public entry fun update_version<T: key>(display: &mut display::Display<T>)
+
+ + + +
+Implementation + + +
entry public fun update_version<T: key>(
+    display: &mut Display<T>
+) {
+    display.version = display.version + 1;
+    event::emit(VersionUpdated<T> {
+        version: display.version,
+        fields: *&display.fields,
+        id: object::uid_to_inner(&display.id),
+    })
+}
+
+ + + +
+ + + +## Function `add` + + + +
public entry fun add<T: key>(self: &mut display::Display<T>, name: string::String, value: string::String)
+
+ + + +
+Implementation + + +
entry public fun add<T: key>(self: &mut Display<T>, name: String, value: String) {
+    add_internal(self, name, value)
+}
+
+ + + +
+ + + +## Function `add_multiple` + + + +
public entry fun add_multiple<T: key>(self: &mut display::Display<T>, fields: vector<string::String>, values: vector<string::String>)
+
+ + + +
+Implementation + + +
entry public fun add_multiple<T: key>(
+    self: &mut Display<T>, fields: vector<String>, values: vector<String>
+) {
+    let len = vector::length(&fields);
+    assert!(len == vector::length(&values), EVecLengthMismatch);
+
+    let i = 0;
+    while (i < len) {
+        add_internal(self, *vector::borrow(&fields, i), *vector::borrow(&values, i));
+        i = i + 1;
+    };
+}
+
+ + + +
+ + + +## Function `edit` + + + +
public entry fun edit<T: key>(self: &mut display::Display<T>, name: string::String, value: string::String)
+
+ + + +
+Implementation + + +
entry public fun edit<T: key>(self: &mut Display<T>, name: String, value: String) {
+    let (_, _) = vec_map::remove(&mut self.fields, &name);
+    add_internal(self, name, value)
+}
+
+ + + +
+ + + +## Function `remove` + + + +
public entry fun remove<T: key>(self: &mut display::Display<T>, name: string::String)
+
+ + + +
+Implementation + + +
entry public fun remove<T: key>(self: &mut Display<T>, name: String) {
+    vec_map::remove(&mut self.fields, &name);
+}
+
+ + + +
+ + + +## Function `is_authorized` + + + +
public fun is_authorized<T: key>(pub: &package::Publisher): bool
+
+ + + +
+Implementation + + +
public fun is_authorized<T: key>(pub: &Publisher): bool {
+    from_package<T>(pub)
+}
+
+ + + +
+ + + +## Function `version` + + + +
public fun version<T: key>(d: &display::Display<T>): u16
+
+ + + +
+Implementation + + +
public fun version<T: key>(d: &Display<T>): u16 {
+    d.version
+}
+
+ + + +
+ + + +## Function `fields` + + + +
public fun fields<T: key>(d: &display::Display<T>): &vec_map::VecMap<string::String, string::String>
+
+ + + +
+Implementation + + +
public fun fields<T: key>(d: &Display<T>): &VecMap<String, String> {
+    &d.fields
+}
+
+ + + +
+ + + +## Function `create_internal` + + + +
fun create_internal<T: key>(ctx: &mut tx_context::TxContext): display::Display<T>
+
+ + + +
+Implementation + + +
fun create_internal<T: key>(ctx: &mut TxContext): Display<T> {
+    let uid = object::new(ctx);
+
+    event::emit(DisplayCreated<T> {
+        id: object::uid_to_inner(&uid)
+    });
+
+    Display {
+        id: uid,
+        fields: vec_map::empty(),
+        version: 0,
+    }
+}
+
+ + + +
+ + + +## Function `add_internal` + + + +
fun add_internal<T: key>(display: &mut display::Display<T>, name: string::String, value: string::String)
+
+ + + +
+Implementation + + +
fun add_internal<T: key>(display: &mut Display<T>, name: String, value: String) {
+    vec_map::insert(&mut display.fields, name, value)
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/dynamic_field.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/dynamic_field.md new file mode 100644 index 00000000..ed89efed --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/dynamic_field.md @@ -0,0 +1,552 @@ + + + +# Module `0x2::dynamic_field` + + + +- [Resource `Field`](#0x2_dynamic_field_Field) +- [Constants](#@Constants_0) +- [Function `add`](#0x2_dynamic_field_add) +- [Function `borrow`](#0x2_dynamic_field_borrow) +- [Function `borrow_mut`](#0x2_dynamic_field_borrow_mut) +- [Function `remove`](#0x2_dynamic_field_remove) +- [Function `exists_`](#0x2_dynamic_field_exists_) +- [Function `remove_if_exists`](#0x2_dynamic_field_remove_if_exists) +- [Function `exists_with_type`](#0x2_dynamic_field_exists_with_type) +- [Function `field_info`](#0x2_dynamic_field_field_info) +- [Function `field_info_mut`](#0x2_dynamic_field_field_info_mut) +- [Function `hash_type_and_key`](#0x2_dynamic_field_hash_type_and_key) +- [Function `add_child_object`](#0x2_dynamic_field_add_child_object) +- [Function `borrow_child_object`](#0x2_dynamic_field_borrow_child_object) +- [Function `borrow_child_object_mut`](#0x2_dynamic_field_borrow_child_object_mut) +- [Function `remove_child_object`](#0x2_dynamic_field_remove_child_object) +- [Function `has_child_object`](#0x2_dynamic_field_has_child_object) +- [Function `has_child_object_with_ty`](#0x2_dynamic_field_has_child_object_with_ty) + + +
use 0x1::option;
+use 0x2::object;
+
+ + + + + +## Resource `Field` + + + +
struct Field<Name: copy, drop, store, Value: store> has key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+name: Name +
+
+ +
+
+value: Value +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const EBCSSerializationFailure: u64 = 3;
+
+ + + + + + + +
const ESharedObjectOperationNotSupported: u64 = 4;
+
+ + + + + + + +
const EFieldAlreadyExists: u64 = 0;
+
+ + + + + + + +
const EFieldDoesNotExist: u64 = 1;
+
+ + + + + + + +
const EFieldTypeMismatch: u64 = 2;
+
+ + + + + +## Function `add` + + + +
public fun add<Name: copy, drop, store, Value: store>(object: &mut object::UID, name: Name, value: Value)
+
+ + + +
+Implementation + + +
public fun add<Name: copy + drop + store, Value: store>(
+    // we use &mut UID in several spots for access control
+    object: &mut UID,
+    name: Name,
+    value: Value,
+) {
+    let object_addr = object::uid_to_address(object);
+    let hash = hash_type_and_key(object_addr, name);
+    assert!(!has_child_object(object_addr, hash), EFieldAlreadyExists);
+    let field = Field {
+        id: object::new_uid_from_hash(hash),
+        name,
+        value,
+    };
+    add_child_object(object_addr, field)
+}
+
+ + + +
+ + + +## Function `borrow` + + + +
public fun borrow<Name: copy, drop, store, Value: store>(object: &object::UID, name: Name): &Value
+
+ + + +
+Implementation + + +
public fun borrow<Name: copy + drop + store, Value: store>(
+    object: &UID,
+    name: Name,
+): &Value {
+    let object_addr = object::uid_to_address(object);
+    let hash = hash_type_and_key(object_addr, name);
+    let field = borrow_child_object<Field<Name, Value>>(object, hash);
+    &field.value
+}
+
+ + + +
+ + + +## Function `borrow_mut` + + + +
public fun borrow_mut<Name: copy, drop, store, Value: store>(object: &mut object::UID, name: Name): &mut Value
+
+ + + +
+Implementation + + +
public fun borrow_mut<Name: copy + drop + store, Value: store>(
+    object: &mut UID,
+    name: Name,
+): &mut Value {
+    let object_addr = object::uid_to_address(object);
+    let hash = hash_type_and_key(object_addr, name);
+    let field = borrow_child_object_mut<Field<Name, Value>>(object, hash);
+    &mut field.value
+}
+
+ + + +
+ + + +## Function `remove` + + + +
public fun remove<Name: copy, drop, store, Value: store>(object: &mut object::UID, name: Name): Value
+
+ + + +
+Implementation + + +
public fun remove<Name: copy + drop + store, Value: store>(
+    object: &mut UID,
+    name: Name,
+): Value {
+    let object_addr = object::uid_to_address(object);
+    let hash = hash_type_and_key(object_addr, name);
+    let Field { id, name: _, value } = remove_child_object<Field<Name, Value>>(object_addr, hash);
+    object::delete(id);
+    value
+}
+
+ + + +
+ + + +## Function `exists_` + + + +
public fun exists_<Name: copy, drop, store>(object: &object::UID, name: Name): bool
+
+ + + +
+Implementation + + +
public fun exists_<Name: copy + drop + store>(
+    object: &UID,
+    name: Name,
+): bool {
+    let object_addr = object::uid_to_address(object);
+    let hash = hash_type_and_key(object_addr, name);
+    has_child_object(object_addr, hash)
+}
+
+ + + +
+ + + +## Function `remove_if_exists` + + + +
public fun remove_if_exists<Name: copy, drop, store, Value: store>(object: &mut object::UID, name: Name): option::Option<Value>
+
+ + + +
+Implementation + + +
public fun remove_if_exists<Name: copy + drop + store, Value: store>(
+    object: &mut UID,
+    name: Name
+): Option<Value> {
+    if (exists_<Name>(object, name)) {
+        option::some(remove(object, name))
+    } else {
+        option::none()
+    }
+}
+
+ + + +
+ + + +## Function `exists_with_type` + + + +
public fun exists_with_type<Name: copy, drop, store, Value: store>(object: &object::UID, name: Name): bool
+
+ + + +
+Implementation + + +
public fun exists_with_type<Name: copy + drop + store, Value: store>(
+    object: &UID,
+    name: Name,
+): bool {
+    let object_addr = object::uid_to_address(object);
+    let hash = hash_type_and_key(object_addr, name);
+    has_child_object_with_ty<Field<Name, Value>>(object_addr, hash)
+}
+
+ + + +
+ + + +## Function `field_info` + + + +
public(friend) fun field_info<Name: copy, drop, store>(object: &object::UID, name: Name): (&object::UID, address)
+
+ + + +
+Implementation + + +
public(friend) fun field_info<Name: copy + drop + store>(
+    object: &UID,
+    name: Name,
+): (&UID, address) {
+    let object_addr = object::uid_to_address(object);
+    let hash = hash_type_and_key(object_addr, name);
+    let Field { id, name: _, value } = borrow_child_object<Field<Name, ID>>(object, hash);
+    (id, object::id_to_address(value))
+}
+
+ + + +
+ + + +## Function `field_info_mut` + + + +
public(friend) fun field_info_mut<Name: copy, drop, store>(object: &mut object::UID, name: Name): (&mut object::UID, address)
+
+ + + +
+Implementation + + +
public(friend) fun field_info_mut<Name: copy + drop + store>(
+    object: &mut UID,
+    name: Name,
+): (&mut UID, address) {
+    let object_addr = object::uid_to_address(object);
+    let hash = hash_type_and_key(object_addr, name);
+    let Field { id, name: _, value } = borrow_child_object_mut<Field<Name, ID>>(object, hash);
+    (id, object::id_to_address(value))
+}
+
+ + + +
+ + + +## Function `hash_type_and_key` + + + +
public(friend) fun hash_type_and_key<K: copy, drop, store>(parent: address, k: K): address
+
+ + + +
+Implementation + + +
public(friend) native fun hash_type_and_key<K: copy + drop + store>(parent: address, k: K): address;
+
+ + + +
+ + + +## Function `add_child_object` + + + +
public(friend) fun add_child_object<Child: key>(parent: address, child: Child)
+
+ + + +
+Implementation + + +
public(friend) native fun add_child_object<Child: key>(parent: address, child: Child);
+
+ + + +
+ + + +## Function `borrow_child_object` + + + +
public(friend) fun borrow_child_object<Child: key>(object: &object::UID, id: address): &Child
+
+ + + +
+Implementation + + +
public(friend) native fun borrow_child_object<Child: key>(object: &UID, id: address): &Child;
+
+ + + +
+ + + +## Function `borrow_child_object_mut` + + + +
public(friend) fun borrow_child_object_mut<Child: key>(object: &mut object::UID, id: address): &mut Child
+
+ + + +
+Implementation + + +
public(friend) native fun borrow_child_object_mut<Child: key>(object: &mut UID, id: address): &mut Child;
+
+ + + +
+ + + +## Function `remove_child_object` + + + +
public(friend) fun remove_child_object<Child: key>(parent: address, id: address): Child
+
+ + + +
+Implementation + + +
public(friend) native fun remove_child_object<Child: key>(parent: address, id: address): Child;
+
+ + + +
+ + + +## Function `has_child_object` + + + +
public(friend) fun has_child_object(parent: address, id: address): bool
+
+ + + +
+Implementation + + +
public(friend) native fun has_child_object(parent: address, id: address): bool;
+
+ + + +
+ + + +## Function `has_child_object_with_ty` + + + +
public(friend) fun has_child_object_with_ty<Child: key>(parent: address, id: address): bool
+
+ + + +
+Implementation + + +
public(friend) native fun has_child_object_with_ty<Child: key>(parent: address, id: address): bool;
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/dynamic_object_field.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/dynamic_object_field.md new file mode 100644 index 00000000..56039f13 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/dynamic_object_field.md @@ -0,0 +1,260 @@ + + + +# Module `0x2::dynamic_object_field` + + + +- [Struct `Wrapper`](#0x2_dynamic_object_field_Wrapper) +- [Function `add`](#0x2_dynamic_object_field_add) +- [Function `borrow`](#0x2_dynamic_object_field_borrow) +- [Function `borrow_mut`](#0x2_dynamic_object_field_borrow_mut) +- [Function `remove`](#0x2_dynamic_object_field_remove) +- [Function `exists_`](#0x2_dynamic_object_field_exists_) +- [Function `exists_with_type`](#0x2_dynamic_object_field_exists_with_type) +- [Function `id`](#0x2_dynamic_object_field_id) + + +
use 0x1::option;
+use 0x2::dynamic_field;
+use 0x2::object;
+
+ + + + + +## Struct `Wrapper` + + + +
struct Wrapper<Name> has copy, drop, store
+
+ + + +
+Fields + + +
+
+name: Name +
+
+ +
+
+ + +
+ + + +## Function `add` + + + +
public fun add<Name: copy, drop, store, Value: store, key>(object: &mut object::UID, name: Name, value: Value)
+
+ + + +
+Implementation + + +
public fun add<Name: copy + drop + store, Value: key + store>(
+    // we use &mut UID in several spots for access control
+    object: &mut UID,
+    name: Name,
+    value: Value,
+) {
+    let key = Wrapper { name };
+    let id = object::id(&value);
+    field::add(object, key, id);
+    let (field, _) = field::field_info<Wrapper<Name>>(object, key);
+    add_child_object(object::uid_to_address(field), value);
+}
+
+ + + +
+ + + +## Function `borrow` + + + +
public fun borrow<Name: copy, drop, store, Value: store, key>(object: &object::UID, name: Name): &Value
+
+ + + +
+Implementation + + +
public fun borrow<Name: copy + drop + store, Value: key + store>(
+    object: &UID,
+    name: Name,
+): &Value {
+    let key = Wrapper { name };
+    let (field, value_id) = field::field_info<Wrapper<Name>>(object, key);
+    borrow_child_object<Value>(field, value_id)
+}
+
+ + + +
+ + + +## Function `borrow_mut` + + + +
public fun borrow_mut<Name: copy, drop, store, Value: store, key>(object: &mut object::UID, name: Name): &mut Value
+
+ + + +
+Implementation + + +
public fun borrow_mut<Name: copy + drop + store, Value: key + store>(
+    object: &mut UID,
+    name: Name,
+): &mut Value {
+    let key = Wrapper { name };
+    let (field, value_id) = field::field_info_mut<Wrapper<Name>>(object, key);
+    borrow_child_object_mut<Value>(field, value_id)
+}
+
+ + + +
+ + + +## Function `remove` + + + +
public fun remove<Name: copy, drop, store, Value: store, key>(object: &mut object::UID, name: Name): Value
+
+ + + +
+Implementation + + +
public fun remove<Name: copy + drop + store, Value: key + store>(
+    object: &mut UID,
+    name: Name,
+): Value {
+    let key = Wrapper { name };
+    let (field, value_id) = field::field_info<Wrapper<Name>>(object, key);
+    let value = remove_child_object<Value>(object::uid_to_address(field), value_id);
+    field::remove<Wrapper<Name>, ID>(object, key);
+    value
+}
+
+ + + +
+ + + +## Function `exists_` + + + +
public fun exists_<Name: copy, drop, store>(object: &object::UID, name: Name): bool
+
+ + + +
+Implementation + + +
public fun exists_<Name: copy + drop + store>(
+    object: &UID,
+    name: Name,
+): bool {
+    let key = Wrapper { name };
+    field::exists_with_type<Wrapper<Name>, ID>(object, key)
+}
+
+ + + +
+ + + +## Function `exists_with_type` + + + +
public fun exists_with_type<Name: copy, drop, store, Value: store, key>(object: &object::UID, name: Name): bool
+
+ + + +
+Implementation + + +
public fun exists_with_type<Name: copy + drop + store, Value: key + store>(
+    object: &UID,
+    name: Name,
+): bool {
+    let key = Wrapper { name };
+    if (!field::exists_with_type<Wrapper<Name>, ID>(object, key)) return false;
+    let (field, value_id) = field::field_info<Wrapper<Name>>(object, key);
+    field::has_child_object_with_ty<Value>(object::uid_to_address(field), value_id)
+}
+
+ + + +
+ + + +## Function `id` + + + +
public fun id<Name: copy, drop, store>(object: &object::UID, name: Name): option::Option<object::ID>
+
+ + + +
+Implementation + + +
public fun id<Name: copy + drop + store>(
+    object: &UID,
+    name: Name,
+): Option<ID> {
+    let key = Wrapper { name };
+    if (!field::exists_with_type<Wrapper<Name>, ID>(object, key)) return option::none();
+    let (_field, value_id) = field::field_info<Wrapper<Name>>(object, key);
+    option::some(object::id_from_address(value_id))
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/event.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/event.md new file mode 100644 index 00000000..e87b4dc7 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/event.md @@ -0,0 +1,35 @@ + + + +# Module `0x2::event` + + + +- [Function `emit`](#0x2_event_emit) + + +
+ + + + + +## Function `emit` + + + +
public fun emit<T: copy, drop>(event: T)
+
+ + + +
+Implementation + + +
public native fun emit<T: copy + drop>(event: T);
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/hex.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/hex.md new file mode 100644 index 00000000..77a41599 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/hex.md @@ -0,0 +1,146 @@ + + + +# Module `0x2::hex` + + + +- [Constants](#@Constants_0) +- [Function `encode`](#0x2_hex_encode) +- [Function `decode`](#0x2_hex_decode) +- [Function `decode_byte`](#0x2_hex_decode_byte) + + +
use 0x1::vector;
+
+ + + + + +## Constants + + + + + + +
const EInvalidHexLength: u64 = 0;
+
+ + + + + + + +
const ENotValidHexCharacter: u64 = 1;
+
+ + + + + + + +
const HEX: vector<vector<u8>> = [ByteArray([48, 48]), ByteArray([48, 49]), ByteArray([48, 50]), ByteArray([48, 51]), ByteArray([48, 52]), ByteArray([48, 53]), ByteArray([48, 54]), ByteArray([48, 55]), ByteArray([48, 56]), ByteArray([48, 57]), ByteArray([48, 97]), ByteArray([48, 98]), ByteArray([48, 99]), ByteArray([48, 100]), ByteArray([48, 101]), ByteArray([48, 102]), ByteArray([49, 48]), ByteArray([49, 49]), ByteArray([49, 50]), ByteArray([49, 51]), ByteArray([49, 52]), ByteArray([49, 53]), ByteArray([49, 54]), ByteArray([49, 55]), ByteArray([49, 56]), ByteArray([49, 57]), ByteArray([49, 97]), ByteArray([49, 98]), ByteArray([49, 99]), ByteArray([49, 100]), ByteArray([49, 101]), ByteArray([49, 102]), ByteArray([50, 48]), ByteArray([50, 49]), ByteArray([50, 50]), ByteArray([50, 51]), ByteArray([50, 52]), ByteArray([50, 53]), ByteArray([50, 54]), ByteArray([50, 55]), ByteArray([50, 56]), ByteArray([50, 57]), ByteArray([50, 97]), ByteArray([50, 98]), ByteArray([50, 99]), ByteArray([50, 100]), ByteArray([50, 101]), ByteArray([50, 102]), ByteArray([51, 48]), ByteArray([51, 49]), ByteArray([51, 50]), ByteArray([51, 51]), ByteArray([51, 52]), ByteArray([51, 53]), ByteArray([51, 54]), ByteArray([51, 55]), ByteArray([51, 56]), ByteArray([51, 57]), ByteArray([51, 97]), ByteArray([51, 98]), ByteArray([51, 99]), ByteArray([51, 100]), ByteArray([51, 101]), ByteArray([51, 102]), ByteArray([52, 48]), ByteArray([52, 49]), ByteArray([52, 50]), ByteArray([52, 51]), ByteArray([52, 52]), ByteArray([52, 53]), ByteArray([52, 54]), ByteArray([52, 55]), ByteArray([52, 56]), ByteArray([52, 57]), ByteArray([52, 97]), ByteArray([52, 98]), ByteArray([52, 99]), ByteArray([52, 100]), ByteArray([52, 101]), ByteArray([52, 102]), ByteArray([53, 48]), ByteArray([53, 49]), ByteArray([53, 50]), ByteArray([53, 51]), ByteArray([53, 52]), ByteArray([53, 53]), ByteArray([53, 54]), ByteArray([53, 55]), ByteArray([53, 56]), ByteArray([53, 57]), ByteArray([53, 97]), ByteArray([53, 98]), ByteArray([53, 99]), ByteArray([53, 100]), ByteArray([53, 101]), ByteArray([53, 102]), ByteArray([54, 48]), ByteArray([54, 49]), ByteArray([54, 50]), ByteArray([54, 51]), ByteArray([54, 52]), ByteArray([54, 53]), ByteArray([54, 54]), ByteArray([54, 55]), ByteArray([54, 56]), ByteArray([54, 57]), ByteArray([54, 97]), ByteArray([54, 98]), ByteArray([54, 99]), ByteArray([54, 100]), ByteArray([54, 101]), ByteArray([54, 102]), ByteArray([55, 48]), ByteArray([55, 49]), ByteArray([55, 50]), ByteArray([55, 51]), ByteArray([55, 52]), ByteArray([55, 53]), ByteArray([55, 54]), ByteArray([55, 55]), ByteArray([55, 56]), ByteArray([55, 57]), ByteArray([55, 97]), ByteArray([55, 98]), ByteArray([55, 99]), ByteArray([55, 100]), ByteArray([55, 101]), ByteArray([55, 102]), ByteArray([56, 48]), ByteArray([56, 49]), ByteArray([56, 50]), ByteArray([56, 51]), ByteArray([56, 52]), ByteArray([56, 53]), ByteArray([56, 54]), ByteArray([56, 55]), ByteArray([56, 56]), ByteArray([56, 57]), ByteArray([56, 97]), ByteArray([56, 98]), ByteArray([56, 99]), ByteArray([56, 100]), ByteArray([56, 101]), ByteArray([56, 102]), ByteArray([57, 48]), ByteArray([57, 49]), ByteArray([57, 50]), ByteArray([57, 51]), ByteArray([57, 52]), ByteArray([57, 53]), ByteArray([57, 54]), ByteArray([57, 55]), ByteArray([57, 56]), ByteArray([57, 57]), ByteArray([57, 97]), ByteArray([57, 98]), ByteArray([57, 99]), ByteArray([57, 100]), ByteArray([57, 101]), ByteArray([57, 102]), ByteArray([97, 48]), ByteArray([97, 49]), ByteArray([97, 50]), ByteArray([97, 51]), ByteArray([97, 52]), ByteArray([97, 53]), ByteArray([97, 54]), ByteArray([97, 55]), ByteArray([97, 56]), ByteArray([97, 57]), ByteArray([97, 97]), ByteArray([97, 98]), ByteArray([97, 99]), ByteArray([97, 100]), ByteArray([97, 101]), ByteArray([97, 102]), ByteArray([98, 48]), ByteArray([98, 49]), ByteArray([98, 50]), ByteArray([98, 51]), ByteArray([98, 52]), ByteArray([98, 53]), ByteArray([98, 54]), ByteArray([98, 55]), ByteArray([98, 56]), ByteArray([98, 57]), ByteArray([98, 97]), ByteArray([98, 98]), ByteArray([98, 99]), ByteArray([98, 100]), ByteArray([98, 101]), ByteArray([98, 102]), ByteArray([99, 48]), ByteArray([99, 49]), ByteArray([99, 50]), ByteArray([99, 51]), ByteArray([99, 52]), ByteArray([99, 53]), ByteArray([99, 54]), ByteArray([99, 55]), ByteArray([99, 56]), ByteArray([99, 57]), ByteArray([99, 97]), ByteArray([99, 98]), ByteArray([99, 99]), ByteArray([99, 100]), ByteArray([99, 101]), ByteArray([99, 102]), ByteArray([100, 48]), ByteArray([100, 49]), ByteArray([100, 50]), ByteArray([100, 51]), ByteArray([100, 52]), ByteArray([100, 53]), ByteArray([100, 54]), ByteArray([100, 55]), ByteArray([100, 56]), ByteArray([100, 57]), ByteArray([100, 97]), ByteArray([100, 98]), ByteArray([100, 99]), ByteArray([100, 100]), ByteArray([100, 101]), ByteArray([100, 102]), ByteArray([101, 48]), ByteArray([101, 49]), ByteArray([101, 50]), ByteArray([101, 51]), ByteArray([101, 52]), ByteArray([101, 53]), ByteArray([101, 54]), ByteArray([101, 55]), ByteArray([101, 56]), ByteArray([101, 57]), ByteArray([101, 97]), ByteArray([101, 98]), ByteArray([101, 99]), ByteArray([101, 100]), ByteArray([101, 101]), ByteArray([101, 102]), ByteArray([102, 48]), ByteArray([102, 49]), ByteArray([102, 50]), ByteArray([102, 51]), ByteArray([102, 52]), ByteArray([102, 53]), ByteArray([102, 54]), ByteArray([102, 55]), ByteArray([102, 56]), ByteArray([102, 57]), ByteArray([102, 97]), ByteArray([102, 98]), ByteArray([102, 99]), ByteArray([102, 100]), ByteArray([102, 101]), ByteArray([102, 102])];
+
+ + + + + +## Function `encode` + + + +
public fun encode(bytes: vector<u8>): vector<u8>
+
+ + + +
+Implementation + + +
public fun encode(bytes: vector<u8>): vector<u8> {
+    let (i, r, l) = (0, vector[], vector::length(&bytes));
+    let hex_vector = HEX;
+    while (i < l) {
+        vector::append(
+            &mut r,
+            *vector::borrow(&hex_vector, (*vector::borrow(&bytes, i) as u64))
+        );
+        i = i + 1;
+    };
+    r
+}
+
+ + + +
+ + + +## Function `decode` + + + +
public fun decode(hex: vector<u8>): vector<u8>
+
+ + + +
+Implementation + + +
public fun decode(hex: vector<u8>): vector<u8> {
+    let (i, r, l) = (0, vector[], vector::length(&hex));
+    assert!(l % 2 == 0, EInvalidHexLength);
+    while (i < l) {
+        let decimal = (decode_byte(*vector::borrow(&hex, i)) * 16) +
+                      decode_byte(*vector::borrow(&hex, i + 1));
+        vector::push_back(&mut r, decimal);
+        i = i + 2;
+    };
+    r
+}
+
+ + + +
+ + + +## Function `decode_byte` + + + +
fun decode_byte(hex: u8): u8
+
+ + + +
+Implementation + + +
fun decode_byte(hex: u8): u8 {
+    if (/* 0 .. 9 */ 48 <= hex && hex < 58) {
+        hex - 48
+    } else if (/* A .. F */ 65 <= hex && hex < 71) {
+        10 + hex - 65
+    } else if (/* a .. f */ 97 <= hex && hex < 103) {
+        10 + hex - 97
+    } else {
+        abort ENotValidHexCharacter
+    }
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/math.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/math.md new file mode 100644 index 00000000..39997112 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/math.md @@ -0,0 +1,242 @@ + + + +# Module `0x2::math` + + + +- [Function `max`](#0x2_math_max) +- [Function `min`](#0x2_math_min) +- [Function `diff`](#0x2_math_diff) +- [Function `pow`](#0x2_math_pow) +- [Function `sqrt`](#0x2_math_sqrt) +- [Function `sqrt_u128`](#0x2_math_sqrt_u128) +- [Function `divide_and_round_up`](#0x2_math_divide_and_round_up) + + +
+ + + + + +## Function `max` + + + +
public fun max(x: u64, y: u64): u64
+
+ + + +
+Implementation + + +
public fun max(x: u64, y: u64): u64 {
+    if (x > y) {
+        x
+    } else {
+        y
+    }
+}
+
+ + + +
+ + + +## Function `min` + + + +
public fun min(x: u64, y: u64): u64
+
+ + + +
+Implementation + + +
public fun min(x: u64, y: u64): u64 {
+    if (x < y) {
+        x
+    } else {
+        y
+    }
+}
+
+ + + +
+ + + +## Function `diff` + + + +
public fun diff(x: u64, y: u64): u64
+
+ + + +
+Implementation + + +
public fun diff(x: u64, y: u64): u64 {
+    if (x > y) {
+        x - y
+    } else {
+        y - x
+    }
+}
+
+ + + +
+ + + +## Function `pow` + + + +
public fun pow(base: u64, exponent: u8): u64
+
+ + + +
+Implementation + + +
public fun pow(base: u64, exponent: u8): u64 {
+    let res = 1;
+    while (exponent >= 1) {
+        if (exponent % 2 == 0) {
+            base = base * base;
+            exponent = exponent / 2;
+        } else {
+            res = res * base;
+            exponent = exponent - 1;
+        }
+    };
+
+    res
+}
+
+ + + +
+ + + +## Function `sqrt` + + + +
public fun sqrt(x: u64): u64
+
+ + + +
+Implementation + + +
public fun sqrt(x: u64): u64 {
+    let bit = 1u128 << 64;
+    let res = 0u128;
+    let x = (x as u128);
+
+    while (bit != 0) {
+        if (x >= res + bit) {
+            x = x - (res + bit);
+            res = (res >> 1) + bit;
+        } else {
+            res = res >> 1;
+        };
+        bit = bit >> 2;
+    };
+
+    (res as u64)
+}
+
+ + + +
+ + + +## Function `sqrt_u128` + + + +
public fun sqrt_u128(x: u128): u128
+
+ + + +
+Implementation + + +
public fun sqrt_u128(x: u128): u128 {
+    let bit = 1u256 << 128;
+    let res = 0u256;
+    let x = (x as u256);
+
+    while (bit != 0) {
+        if (x >= res + bit) {
+            x = x - (res + bit);
+            res = (res >> 1) + bit;
+        } else {
+            res = res >> 1;
+        };
+        bit = bit >> 2;
+    };
+
+    (res as u128)
+}
+
+ + + +
+ + + +## Function `divide_and_round_up` + + + +
public fun divide_and_round_up(x: u64, y: u64): u64
+
+ + + +
+Implementation + + +
public fun divide_and_round_up(x: u64, y: u64): u64 {
+    if (x % y == 0) {
+        x / y
+    } else {
+        x / y + 1
+    }
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/mgo.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/mgo.md new file mode 100644 index 00000000..57540c79 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/mgo.md @@ -0,0 +1,164 @@ + + + +# Module `0x2::mgo` + + + +- [Struct `MGO`](#0x2_mgo_MGO) +- [Constants](#@Constants_0) +- [Function `new`](#0x2_mgo_new) +- [Function `transfer`](#0x2_mgo_transfer) + + +
use 0x1::option;
+use 0x2::balance;
+use 0x2::coin;
+use 0x2::transfer;
+use 0x2::tx_context;
+use 0x2::url;
+
+ + + + + +## Struct `MGO` + + + +
struct MGO has drop
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ENotSystemAddress: u64 = 1;
+
+ + + + + + + +
const EAlreadyMinted: u64 = 0;
+
+ + + + + + + +
const MIST_PER_MGO: u64 = 1000000000;
+
+ + + + + + + +
const TOTAL_SUPPLY_MGO: u64 = 10000000000;
+
+ + + + + + + +
const TOTAL_SUPPLY_MIST: u64 = 10000000000000000000;
+
+ + + + + +## Function `new` + + + +
fun new(ctx: &mut tx_context::TxContext): balance::Balance<mgo::MGO>
+
+ + + +
+Implementation + + +
fun new(ctx: &mut TxContext): Balance<MGO> {
+    assert!(tx_context::sender(ctx) == @0x0, ENotSystemAddress);
+    assert!(tx_context::epoch(ctx) == 0, EAlreadyMinted);
+
+    let (treasury, metadata) = coin::create_currency(
+        MGO {},
+        9,
+        b"MGO",
+        b"Mgo",
+        // TODO: add appropriate description and logo url
+        b"",
+        option::none(),
+        ctx
+    );
+    transfer::public_freeze_object(metadata);
+    let supply = coin::treasury_into_supply(treasury);
+    let total_mgo = balance::increase_supply(&mut supply, TOTAL_SUPPLY_MIST);
+    balance::destroy_supply(supply);
+    total_mgo
+}
+
+ + + +
+ + + +## Function `transfer` + + + +
public entry fun transfer(c: coin::Coin<mgo::MGO>, recipient: address)
+
+ + + +
+Implementation + + +
public entry fun transfer(c: coin::Coin<MGO>, recipient: address) {
+    transfer::public_transfer(c, recipient)
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/object.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/object.md new file mode 100644 index 00000000..07b6ddf8 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/object.md @@ -0,0 +1,715 @@ + + + +# Module `0x2::object` + + + +- [Struct `ID`](#0x2_object_ID) +- [Struct `UID`](#0x2_object_UID) +- [Constants](#@Constants_0) +- [Function `id_to_bytes`](#0x2_object_id_to_bytes) +- [Function `id_to_address`](#0x2_object_id_to_address) +- [Function `id_from_bytes`](#0x2_object_id_from_bytes) +- [Function `id_from_address`](#0x2_object_id_from_address) +- [Function `mgo_system_state`](#0x2_object_mgo_system_state) +- [Function `clock`](#0x2_object_clock) +- [Function `authenticator_state`](#0x2_object_authenticator_state) +- [Function `randomness_state`](#0x2_object_randomness_state) +- [Function `mgo_deny_list_object_id`](#0x2_object_mgo_deny_list_object_id) +- [Function `uid_as_inner`](#0x2_object_uid_as_inner) +- [Function `uid_to_inner`](#0x2_object_uid_to_inner) +- [Function `uid_to_bytes`](#0x2_object_uid_to_bytes) +- [Function `uid_to_address`](#0x2_object_uid_to_address) +- [Function `new`](#0x2_object_new) +- [Function `delete`](#0x2_object_delete) +- [Function `id`](#0x2_object_id) +- [Function `borrow_id`](#0x2_object_borrow_id) +- [Function `id_bytes`](#0x2_object_id_bytes) +- [Function `id_address`](#0x2_object_id_address) +- [Function `borrow_uid`](#0x2_object_borrow_uid) +- [Function `new_uid_from_hash`](#0x2_object_new_uid_from_hash) +- [Function `delete_impl`](#0x2_object_delete_impl) +- [Function `record_new_uid`](#0x2_object_record_new_uid) + + +
use 0x1::bcs;
+use 0x2::address;
+use 0x2::tx_context;
+
+ + + + + +## Struct `ID` + + + +
struct ID has copy, drop, store
+
+ + + +
+Fields + + +
+
+bytes: address +
+
+ +
+
+ + +
+ + + +## Struct `UID` + + + +
struct UID has store
+
+ + + +
+Fields + + +
+
+id: object::ID +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ENotSystemAddress: u64 = 0;
+
+ + + + + + + +
const MGO_AUTHENTICATOR_STATE_ID: address = 7;
+
+ + + + + + + +
const MGO_CLOCK_OBJECT_ID: address = 6;
+
+ + + + + + + +
const MGO_DENY_LIST_OBJECT_ID: address = 403;
+
+ + + + + + + +
const MGO_RANDOM_ID: address = 8;
+
+ + + + + + + +
const MGO_SYSTEM_STATE_OBJECT_ID: address = 5;
+
+ + + + + +## Function `id_to_bytes` + + + +
public fun id_to_bytes(id: &object::ID): vector<u8>
+
+ + + +
+Implementation + + +
public fun id_to_bytes(id: &ID): vector<u8> {
+    bcs::to_bytes(&id.bytes)
+}
+
+ + + +
+ + + +## Function `id_to_address` + + + +
public fun id_to_address(id: &object::ID): address
+
+ + + +
+Implementation + + +
public fun id_to_address(id: &ID): address {
+    id.bytes
+}
+
+ + + +
+ + + +## Function `id_from_bytes` + + + +
public fun id_from_bytes(bytes: vector<u8>): object::ID
+
+ + + +
+Implementation + + +
public fun id_from_bytes(bytes: vector<u8>): ID {
+    id_from_address(address::from_bytes(bytes))
+}
+
+ + + +
+ + + +## Function `id_from_address` + + + +
public fun id_from_address(bytes: address): object::ID
+
+ + + +
+Implementation + + +
public fun id_from_address(bytes: address): ID {
+    ID { bytes }
+}
+
+ + + +
+ + + +## Function `mgo_system_state` + + + +
fun mgo_system_state(ctx: &tx_context::TxContext): object::UID
+
+ + + +
+Implementation + + +
fun mgo_system_state(ctx: &TxContext): UID {
+    assert!(tx_context::sender(ctx) == @0x0, ENotSystemAddress);
+    UID {
+        id: ID { bytes: MGO_SYSTEM_STATE_OBJECT_ID },
+    }
+}
+
+ + + +
+ + + +## Function `clock` + + + +
public(friend) fun clock(): object::UID
+
+ + + +
+Implementation + + +
public(friend) fun clock(): UID {
+    UID {
+        id: ID { bytes: MGO_CLOCK_OBJECT_ID }
+    }
+}
+
+ + + +
+ + + +## Function `authenticator_state` + + + +
public(friend) fun authenticator_state(): object::UID
+
+ + + +
+Implementation + + +
public(friend) fun authenticator_state(): UID {
+    UID {
+        id: ID { bytes: MGO_AUTHENTICATOR_STATE_ID }
+    }
+}
+
+ + + +
+ + + +## Function `randomness_state` + + + +
public(friend) fun randomness_state(): object::UID
+
+ + + +
+Implementation + + +
public(friend) fun randomness_state(): UID {
+    UID {
+        id: ID { bytes: MGO_RANDOM_ID }
+    }
+}
+
+ + + +
+ + + +## Function `mgo_deny_list_object_id` + + + +
public(friend) fun mgo_deny_list_object_id(): object::UID
+
+ + + +
+Implementation + + +
public(friend) fun mgo_deny_list_object_id(): UID {
+    UID {
+        id: ID { bytes: MGO_DENY_LIST_OBJECT_ID }
+    }
+}
+
+ + + +
+ + + +## Function `uid_as_inner` + + + +
public fun uid_as_inner(uid: &object::UID): &object::ID
+
+ + + +
+Implementation + + +
public fun uid_as_inner(uid: &UID): &ID {
+    &uid.id
+}
+
+ + + +
+ + + +## Function `uid_to_inner` + + + +
public fun uid_to_inner(uid: &object::UID): object::ID
+
+ + + +
+Implementation + + +
public fun uid_to_inner(uid: &UID): ID {
+    uid.id
+}
+
+ + + +
+ + + +## Function `uid_to_bytes` + + + +
public fun uid_to_bytes(uid: &object::UID): vector<u8>
+
+ + + +
+Implementation + + +
public fun uid_to_bytes(uid: &UID): vector<u8> {
+    bcs::to_bytes(&uid.id.bytes)
+}
+
+ + + +
+ + + +## Function `uid_to_address` + + + +
public fun uid_to_address(uid: &object::UID): address
+
+ + + +
+Implementation + + +
public fun uid_to_address(uid: &UID): address {
+    uid.id.bytes
+}
+
+ + + +
+ + + +## Function `new` + + + +
public fun new(ctx: &mut tx_context::TxContext): object::UID
+
+ + + +
+Implementation + + +
public fun new(ctx: &mut TxContext): UID {
+    UID {
+        id: ID { bytes: tx_context::fresh_object_address(ctx) },
+    }
+}
+
+ + + +
+ + + +## Function `delete` + + + +
public fun delete(id: object::UID)
+
+ + + +
+Implementation + + +
public fun delete(id: UID) {
+    let UID { id: ID { bytes } } = id;
+    delete_impl(bytes)
+}
+
+ + + +
+ + + +## Function `id` + + + +
public fun id<T: key>(obj: &T): object::ID
+
+ + + +
+Implementation + + +
public fun id<T: key>(obj: &T): ID {
+    borrow_uid(obj).id
+}
+
+ + + +
+ + + +## Function `borrow_id` + + + +
public fun borrow_id<T: key>(obj: &T): &object::ID
+
+ + + +
+Implementation + + +
public fun borrow_id<T: key>(obj: &T): &ID {
+    &borrow_uid(obj).id
+}
+
+ + + +
+ + + +## Function `id_bytes` + + + +
public fun id_bytes<T: key>(obj: &T): vector<u8>
+
+ + + +
+Implementation + + +
public fun id_bytes<T: key>(obj: &T): vector<u8> {
+    bcs::to_bytes(&borrow_uid(obj).id)
+}
+
+ + + +
+ + + +## Function `id_address` + + + +
public fun id_address<T: key>(obj: &T): address
+
+ + + +
+Implementation + + +
public fun id_address<T: key>(obj: &T): address {
+    borrow_uid(obj).id.bytes
+}
+
+ + + +
+ + + +## Function `borrow_uid` + + + +
fun borrow_uid<T: key>(obj: &T): &object::UID
+
+ + + +
+Implementation + + +
native fun borrow_uid<T: key>(obj: &T): &UID;
+
+ + + +
+ + + +## Function `new_uid_from_hash` + + + +
public(friend) fun new_uid_from_hash(bytes: address): object::UID
+
+ + + +
+Implementation + + +
public(friend) fun new_uid_from_hash(bytes: address): UID {
+    record_new_uid(bytes);
+    UID { id: ID { bytes } }
+}
+
+ + + +
+ + + +## Function `delete_impl` + + + +
fun delete_impl(id: address)
+
+ + + +
+Implementation + + +
native fun delete_impl(id: address);
+
+ + + +
+ + + +## Function `record_new_uid` + + + +
fun record_new_uid(id: address)
+
+ + + +
+Implementation + + +
native fun record_new_uid(id: address);
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/package.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/package.md new file mode 100644 index 00000000..083ffee2 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/package.md @@ -0,0 +1,897 @@ + + + +# Module `0x2::package` + + + +- [Resource `Publisher`](#0x2_package_Publisher) +- [Resource `UpgradeCap`](#0x2_package_UpgradeCap) +- [Struct `UpgradeTicket`](#0x2_package_UpgradeTicket) +- [Struct `UpgradeReceipt`](#0x2_package_UpgradeReceipt) +- [Constants](#@Constants_0) +- [Function `claim`](#0x2_package_claim) +- [Function `claim_and_keep`](#0x2_package_claim_and_keep) +- [Function `burn_publisher`](#0x2_package_burn_publisher) +- [Function `from_package`](#0x2_package_from_package) +- [Function `from_module`](#0x2_package_from_module) +- [Function `published_module`](#0x2_package_published_module) +- [Function `published_package`](#0x2_package_published_package) +- [Function `upgrade_package`](#0x2_package_upgrade_package) +- [Function `version`](#0x2_package_version) +- [Function `upgrade_policy`](#0x2_package_upgrade_policy) +- [Function `ticket_package`](#0x2_package_ticket_package) +- [Function `ticket_policy`](#0x2_package_ticket_policy) +- [Function `receipt_cap`](#0x2_package_receipt_cap) +- [Function `receipt_package`](#0x2_package_receipt_package) +- [Function `ticket_digest`](#0x2_package_ticket_digest) +- [Function `compatible_policy`](#0x2_package_compatible_policy) +- [Function `additive_policy`](#0x2_package_additive_policy) +- [Function `dep_only_policy`](#0x2_package_dep_only_policy) +- [Function `only_additive_upgrades`](#0x2_package_only_additive_upgrades) +- [Function `only_dep_upgrades`](#0x2_package_only_dep_upgrades) +- [Function `make_immutable`](#0x2_package_make_immutable) +- [Function `authorize_upgrade`](#0x2_package_authorize_upgrade) +- [Function `commit_upgrade`](#0x2_package_commit_upgrade) +- [Function `restrict`](#0x2_package_restrict) + + +
use 0x1::ascii;
+use 0x1::type_name;
+use 0x2::object;
+use 0x2::transfer;
+use 0x2::tx_context;
+use 0x2::types;
+
+ + + + + +## Resource `Publisher` + + + +
struct Publisher has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+package: ascii::String +
+
+ +
+
+module_name: ascii::String +
+
+ +
+
+ + +
+ + + +## Resource `UpgradeCap` + + + +
struct UpgradeCap has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+package: object::ID +
+
+ +
+
+version: u64 +
+
+ +
+
+policy: u8 +
+
+ +
+
+ + +
+ + + +## Struct `UpgradeTicket` + + + +
struct UpgradeTicket
+
+ + + +
+Fields + + +
+
+cap: object::ID +
+
+ +
+
+package: object::ID +
+
+ +
+
+policy: u8 +
+
+ +
+
+digest: vector<u8> +
+
+ +
+
+ + +
+ + + +## Struct `UpgradeReceipt` + + + +
struct UpgradeReceipt
+
+ + + +
+Fields + + +
+
+cap: object::ID +
+
+ +
+
+package: object::ID +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ADDITIVE: u8 = 128;
+
+ + + + + + + +
const COMPATIBLE: u8 = 0;
+
+ + + + + + + +
const DEP_ONLY: u8 = 192;
+
+ + + + + + + +
const EAlreadyAuthorized: u64 = 2;
+
+ + + + + + + +
const ENotAuthorized: u64 = 3;
+
+ + + + + + + +
const ENotOneTimeWitness: u64 = 0;
+
+ + + + + + + +
const ETooPermissive: u64 = 1;
+
+ + + + + + + +
const EWrongUpgradeCap: u64 = 4;
+
+ + + + + +## Function `claim` + + + +
public fun claim<OTW: drop>(otw: OTW, ctx: &mut tx_context::TxContext): package::Publisher
+
+ + + +
+Implementation + + +
public fun claim<OTW: drop>(otw: OTW, ctx: &mut TxContext): Publisher {
+    assert!(types::is_one_time_witness(&otw), ENotOneTimeWitness);
+
+    let type = type_name::get_with_original_ids<OTW>();
+
+    Publisher {
+        id: object::new(ctx),
+        package: type_name::get_address(&type),
+        module_name: type_name::get_module(&type),
+    }
+}
+
+ + + +
+ + + +## Function `claim_and_keep` + + + +
public fun claim_and_keep<OTW: drop>(otw: OTW, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public fun claim_and_keep<OTW: drop>(otw: OTW, ctx: &mut TxContext) {
+    mgo::transfer::public_transfer(claim(otw, ctx), sender(ctx))
+}
+
+ + + +
+ + + +## Function `burn_publisher` + + + +
public fun burn_publisher(self: package::Publisher)
+
+ + + +
+Implementation + + +
public fun burn_publisher(self: Publisher) {
+    let Publisher { id, package: _, module_name: _ } = self;
+    object::delete(id);
+}
+
+ + + +
+ + + +## Function `from_package` + + + +
public fun from_package<T>(self: &package::Publisher): bool
+
+ + + +
+Implementation + + +
public fun from_package<T>(self: &Publisher): bool {
+    let type = type_name::get_with_original_ids<T>();
+
+    (type_name::get_address(&type) == self.package)
+}
+
+ + + +
+ + + +## Function `from_module` + + + +
public fun from_module<T>(self: &package::Publisher): bool
+
+ + + +
+Implementation + + +
public fun from_module<T>(self: &Publisher): bool {
+    let type = type_name::get_with_original_ids<T>();
+
+    (type_name::get_address(&type) == self.package)
+        && (type_name::get_module(&type) == self.module_name)
+}
+
+ + + +
+ + + +## Function `published_module` + + + +
public fun published_module(self: &package::Publisher): &ascii::String
+
+ + + +
+Implementation + + +
public fun published_module(self: &Publisher): &String {
+    &self.module_name
+}
+
+ + + +
+ + + +## Function `published_package` + + + +
public fun published_package(self: &package::Publisher): &ascii::String
+
+ + + +
+Implementation + + +
public fun published_package(self: &Publisher): &String {
+    &self.package
+}
+
+ + + +
+ + + +## Function `upgrade_package` + + + +
public fun upgrade_package(cap: &package::UpgradeCap): object::ID
+
+ + + +
+Implementation + + +
public fun upgrade_package(cap: &UpgradeCap): ID {
+    cap.package
+}
+
+ + + +
+ + + +## Function `version` + + + +
public fun version(cap: &package::UpgradeCap): u64
+
+ + + +
+Implementation + + +
public fun version(cap: &UpgradeCap): u64 {
+    cap.version
+}
+
+ + + +
+ + + +## Function `upgrade_policy` + + + +
public fun upgrade_policy(cap: &package::UpgradeCap): u8
+
+ + + +
+Implementation + + +
public fun upgrade_policy(cap: &UpgradeCap): u8 {
+    cap.policy
+}
+
+ + + +
+ + + +## Function `ticket_package` + + + +
public fun ticket_package(ticket: &package::UpgradeTicket): object::ID
+
+ + + +
+Implementation + + +
public fun ticket_package(ticket: &UpgradeTicket): ID {
+    ticket.package
+}
+
+ + + +
+ + + +## Function `ticket_policy` + + + +
public fun ticket_policy(ticket: &package::UpgradeTicket): u8
+
+ + + +
+Implementation + + +
public fun ticket_policy(ticket: &UpgradeTicket): u8 {
+    ticket.policy
+}
+
+ + + +
+ + + +## Function `receipt_cap` + + + +
public fun receipt_cap(receipt: &package::UpgradeReceipt): object::ID
+
+ + + +
+Implementation + + +
public fun receipt_cap(receipt: &UpgradeReceipt): ID {
+    receipt.cap
+}
+
+ + + +
+ + + +## Function `receipt_package` + + + +
public fun receipt_package(receipt: &package::UpgradeReceipt): object::ID
+
+ + + +
+Implementation + + +
public fun receipt_package(receipt: &UpgradeReceipt): ID {
+    receipt.package
+}
+
+ + + +
+ + + +## Function `ticket_digest` + + + +
public fun ticket_digest(ticket: &package::UpgradeTicket): &vector<u8>
+
+ + + +
+Implementation + + +
public fun ticket_digest(ticket: &UpgradeTicket): &vector<u8> {
+    &ticket.digest
+}
+
+ + + +
+ + + +## Function `compatible_policy` + + + +
public fun compatible_policy(): u8
+
+ + + +
+Implementation + + +
public fun compatible_policy(): u8 { COMPATIBLE }
+
+ + + +
+ + + +## Function `additive_policy` + + + +
public fun additive_policy(): u8
+
+ + + +
+Implementation + + +
public fun additive_policy(): u8 { ADDITIVE }
+
+ + + +
+ + + +## Function `dep_only_policy` + + + +
public fun dep_only_policy(): u8
+
+ + + +
+Implementation + + +
public fun dep_only_policy(): u8 { DEP_ONLY }
+
+ + + +
+ + + +## Function `only_additive_upgrades` + + + +
public entry fun only_additive_upgrades(cap: &mut package::UpgradeCap)
+
+ + + +
+Implementation + + +
public entry fun only_additive_upgrades(cap: &mut UpgradeCap) {
+    restrict(cap, ADDITIVE)
+}
+
+ + + +
+ + + +## Function `only_dep_upgrades` + + + +
public entry fun only_dep_upgrades(cap: &mut package::UpgradeCap)
+
+ + + +
+Implementation + + +
public entry fun only_dep_upgrades(cap: &mut UpgradeCap) {
+    restrict(cap, DEP_ONLY)
+}
+
+ + + +
+ + + +## Function `make_immutable` + + + +
public entry fun make_immutable(cap: package::UpgradeCap)
+
+ + + +
+Implementation + + +
public entry fun make_immutable(cap: UpgradeCap) {
+    let UpgradeCap { id, package: _, version: _, policy: _ } = cap;
+    object::delete(id);
+}
+
+ + + +
+ + + +## Function `authorize_upgrade` + + + +
public fun authorize_upgrade(cap: &mut package::UpgradeCap, policy: u8, digest: vector<u8>): package::UpgradeTicket
+
+ + + +
+Implementation + + +
public fun authorize_upgrade(
+    cap: &mut UpgradeCap,
+    policy: u8,
+    digest: vector<u8>
+): UpgradeTicket {
+    let id_zero = object::id_from_address(@0x0);
+    assert!(cap.package != id_zero, EAlreadyAuthorized);
+    assert!(policy >= cap.policy, ETooPermissive);
+
+    let package = cap.package;
+    cap.package = id_zero;
+
+    UpgradeTicket {
+        cap: object::id(cap),
+        package,
+        policy,
+        digest,
+    }
+}
+
+ + + +
+ + + +## Function `commit_upgrade` + + + +
public fun commit_upgrade(cap: &mut package::UpgradeCap, receipt: package::UpgradeReceipt)
+
+ + + +
+Implementation + + +
public fun commit_upgrade(
+    cap: &mut UpgradeCap,
+    receipt: UpgradeReceipt,
+) {
+    let UpgradeReceipt { cap: cap_id, package } = receipt;
+
+    assert!(object::id(cap) == cap_id, EWrongUpgradeCap);
+    assert!(object::id_to_address(&cap.package) == @0x0, ENotAuthorized);
+
+    cap.package = package;
+    cap.version = cap.version + 1;
+}
+
+ + + +
+ + + +## Function `restrict` + + + +
fun restrict(cap: &mut package::UpgradeCap, policy: u8)
+
+ + + +
+Implementation + + +
fun restrict(cap: &mut UpgradeCap, policy: u8) {
+    assert!(cap.policy <= policy, ETooPermissive);
+    cap.policy = policy;
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/random.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/random.md new file mode 100644 index 00000000..41fb685b --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/random.md @@ -0,0 +1,296 @@ + + + +# Module `0x2::random` + + + +- [Resource `Random`](#0x2_random_Random) +- [Struct `RandomInner`](#0x2_random_RandomInner) +- [Constants](#@Constants_0) +- [Function `create`](#0x2_random_create) +- [Function `load_inner_mut`](#0x2_random_load_inner_mut) +- [Function `load_inner`](#0x2_random_load_inner) +- [Function `update_randomness_state`](#0x2_random_update_randomness_state) + + +
use 0x1::vector;
+use 0x2::object;
+use 0x2::transfer;
+use 0x2::tx_context;
+use 0x2::versioned;
+
+ + + + + +## Resource `Random` + + + +
struct Random has key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+inner: versioned::Versioned +
+
+ +
+
+ + +
+ + + +## Struct `RandomInner` + + + +
struct RandomInner has store
+
+ + + +
+Fields + + +
+
+version: u64 +
+
+ +
+
+epoch: u64 +
+
+ +
+
+randomness_round: u64 +
+
+ +
+
+random_bytes: vector<u8> +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ENotSystemAddress: u64 = 0;
+
+ + + + + + + +
const EWrongInnerVersion: u64 = 1;
+
+ + + + + + + +
const CURRENT_VERSION: u64 = 1;
+
+ + + + + + + +
const EInvalidRandomnessUpdate: u64 = 2;
+
+ + + + + +## Function `create` + + + +
fun create(ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
fun create(ctx: &mut TxContext) {
+    assert!(tx_context::sender(ctx) == @0x0, ENotSystemAddress);
+
+    let version = CURRENT_VERSION;
+
+    let inner = RandomInner {
+        version,
+        epoch: tx_context::epoch(ctx),
+        randomness_round: 0,
+        random_bytes: vector[],
+    };
+
+    let self = Random {
+        id: object::randomness_state(),
+        inner: versioned::create(version, inner, ctx),
+    };
+    transfer::share_object(self);
+}
+
+ + + +
+ + + +## Function `load_inner_mut` + + + +
fun load_inner_mut(self: &mut random::Random): &mut random::RandomInner
+
+ + + +
+Implementation + + +
fun load_inner_mut(
+    self: &mut Random,
+): &mut RandomInner {
+    let version = versioned::version(&self.inner);
+
+    // Replace this with a lazy update function when we add a new version of the inner object.
+    assert!(version == CURRENT_VERSION, EWrongInnerVersion);
+    let inner: &mut RandomInner = versioned::load_value_mut(&mut self.inner);
+    assert!(inner.version == version, EWrongInnerVersion);
+    inner
+}
+
+ + + +
+ + + +## Function `load_inner` + + + +
fun load_inner(self: &random::Random): &random::RandomInner
+
+ + + +
+Implementation + + +
fun load_inner(
+    self: &Random,
+): &RandomInner {
+    let version = versioned::version(&self.inner);
+
+    // Replace this with a lazy update function when we add a new version of the inner object.
+    assert!(version == CURRENT_VERSION, EWrongInnerVersion);
+    let inner: &RandomInner = versioned::load_value(&self.inner);
+    assert!(inner.version == version, EWrongInnerVersion);
+    inner
+}
+
+ + + +
+ + + +## Function `update_randomness_state` + + + +
fun update_randomness_state(self: &mut random::Random, new_round: u64, new_bytes: vector<u8>, ctx: &tx_context::TxContext)
+
+ + + +
+Implementation + + +
fun update_randomness_state(
+    self: &mut Random,
+    new_round: u64,
+    new_bytes: vector<u8>,
+    ctx: &TxContext,
+) {
+    // Validator will make a special system call with sender set as 0x0.
+    assert!(tx_context::sender(ctx) == @0x0, ENotSystemAddress);
+
+    // Randomness should only be incremented.
+    let epoch = tx_context::epoch(ctx);
+    let inner = load_inner_mut(self);
+    if (inner.randomness_round == 0 && inner.epoch == 0 &&
+            vector::is_empty(&inner.random_bytes)) {
+        // First update should be for round zero.
+        assert!(new_round == 0, EInvalidRandomnessUpdate);
+    } else {
+        // Subsequent updates should increment either epoch or randomness_round.
+        assert!(
+            (epoch == inner.epoch + 1 && new_round == 0) ||
+                (new_round == inner.randomness_round + 1),
+            EInvalidRandomnessUpdate
+        );
+    };
+
+    inner.epoch = tx_context::epoch(ctx);
+    inner.randomness_round = new_round;
+    inner.random_bytes = new_bytes;
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/table.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/table.md new file mode 100644 index 00000000..80afac83 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/table.md @@ -0,0 +1,323 @@ + + + +# Module `0x2::table` + + + +- [Resource `Table`](#0x2_table_Table) +- [Constants](#@Constants_0) +- [Function `new`](#0x2_table_new) +- [Function `add`](#0x2_table_add) +- [Function `borrow`](#0x2_table_borrow) +- [Function `borrow_mut`](#0x2_table_borrow_mut) +- [Function `remove`](#0x2_table_remove) +- [Function `contains`](#0x2_table_contains) +- [Function `length`](#0x2_table_length) +- [Function `is_empty`](#0x2_table_is_empty) +- [Function `destroy_empty`](#0x2_table_destroy_empty) +- [Function `drop`](#0x2_table_drop) + + +
use 0x2::dynamic_field;
+use 0x2::object;
+use 0x2::tx_context;
+
+ + + + + +## Resource `Table` + + + +
struct Table<K: copy, drop, store, V: store> has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+size: u64 +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ETableNotEmpty: u64 = 0;
+
+ + + + + +## Function `new` + + + +
public fun new<K: copy, drop, store, V: store>(ctx: &mut tx_context::TxContext): table::Table<K, V>
+
+ + + +
+Implementation + + +
public fun new<K: copy + drop + store, V: store>(ctx: &mut TxContext): Table<K, V> {
+    Table {
+        id: object::new(ctx),
+        size: 0,
+    }
+}
+
+ + + +
+ + + +## Function `add` + + + +
public fun add<K: copy, drop, store, V: store>(table: &mut table::Table<K, V>, k: K, v: V)
+
+ + + +
+Implementation + + +
public fun add<K: copy + drop + store, V: store>(table: &mut Table<K, V>, k: K, v: V) {
+    field::add(&mut table.id, k, v);
+    table.size = table.size + 1;
+}
+
+ + + +
+ + + +## Function `borrow` + + + +
public fun borrow<K: copy, drop, store, V: store>(table: &table::Table<K, V>, k: K): &V
+
+ + + +
+Implementation + + +
public fun borrow<K: copy + drop + store, V: store>(table: &Table<K, V>, k: K): &V {
+    field::borrow(&table.id, k)
+}
+
+ + + +
+ + + +## Function `borrow_mut` + + + +
public fun borrow_mut<K: copy, drop, store, V: store>(table: &mut table::Table<K, V>, k: K): &mut V
+
+ + + +
+Implementation + + +
public fun borrow_mut<K: copy + drop + store, V: store>(table: &mut Table<K, V>, k: K): &mut V {
+    field::borrow_mut(&mut table.id, k)
+}
+
+ + + +
+ + + +## Function `remove` + + + +
public fun remove<K: copy, drop, store, V: store>(table: &mut table::Table<K, V>, k: K): V
+
+ + + +
+Implementation + + +
public fun remove<K: copy + drop + store, V: store>(table: &mut Table<K, V>, k: K): V {
+    let v = field::remove(&mut table.id, k);
+    table.size = table.size - 1;
+    v
+}
+
+ + + +
+ + + +## Function `contains` + + + +
public fun contains<K: copy, drop, store, V: store>(table: &table::Table<K, V>, k: K): bool
+
+ + + +
+Implementation + + +
public fun contains<K: copy + drop + store, V: store>(table: &Table<K, V>, k: K): bool {
+    field::exists_with_type<K, V>(&table.id, k)
+}
+
+ + + +
+ + + +## Function `length` + + + +
public fun length<K: copy, drop, store, V: store>(table: &table::Table<K, V>): u64
+
+ + + +
+Implementation + + +
public fun length<K: copy + drop + store, V: store>(table: &Table<K, V>): u64 {
+    table.size
+}
+
+ + + +
+ + + +## Function `is_empty` + + + +
public fun is_empty<K: copy, drop, store, V: store>(table: &table::Table<K, V>): bool
+
+ + + +
+Implementation + + +
public fun is_empty<K: copy + drop + store, V: store>(table: &Table<K, V>): bool {
+    table.size == 0
+}
+
+ + + +
+ + + +## Function `destroy_empty` + + + +
public fun destroy_empty<K: copy, drop, store, V: store>(table: table::Table<K, V>)
+
+ + + +
+Implementation + + +
public fun destroy_empty<K: copy + drop + store, V: store>(table: Table<K, V>) {
+    let Table { id, size } = table;
+    assert!(size == 0, ETableNotEmpty);
+    object::delete(id)
+}
+
+ + + +
+ + + +## Function `drop` + + + +
public fun drop<K: copy, drop, store, V: drop, store>(table: table::Table<K, V>)
+
+ + + +
+Implementation + + +
public fun drop<K: copy + drop + store, V: drop + store>(table: Table<K, V>) {
+    let Table { id, size: _ } = table;
+    object::delete(id)
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/transfer.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/transfer.md new file mode 100644 index 00000000..818b9401 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/transfer.md @@ -0,0 +1,423 @@ + + + +# Module `0x2::transfer` + + + +- [Struct `Receiving`](#0x2_transfer_Receiving) +- [Constants](#@Constants_0) +- [Function `transfer`](#0x2_transfer_transfer) +- [Function `public_transfer`](#0x2_transfer_public_transfer) +- [Function `freeze_object`](#0x2_transfer_freeze_object) +- [Function `public_freeze_object`](#0x2_transfer_public_freeze_object) +- [Function `share_object`](#0x2_transfer_share_object) +- [Function `public_share_object`](#0x2_transfer_public_share_object) +- [Function `receive`](#0x2_transfer_receive) +- [Function `public_receive`](#0x2_transfer_public_receive) +- [Function `receiving_object_id`](#0x2_transfer_receiving_object_id) +- [Function `freeze_object_impl`](#0x2_transfer_freeze_object_impl) +- [Function `share_object_impl`](#0x2_transfer_share_object_impl) +- [Function `transfer_impl`](#0x2_transfer_transfer_impl) +- [Function `receive_impl`](#0x2_transfer_receive_impl) + + +
use 0x2::object;
+
+ + + + + +## Struct `Receiving` + + + +
struct Receiving<T: key> has drop
+
+ + + +
+Fields + + +
+
+id: object::ID +
+
+ +
+
+version: u64 +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const EBCSSerializationFailure: u64 = 1;
+
+ + + + + + + +
const EReceivingObjectTypeMismatch: u64 = 2;
+
+ + + + + + + +
const ESharedNonNewObject: u64 = 0;
+
+ + + + + + + +
const ESharedObjectOperationNotSupported: u64 = 4;
+
+ + + + + + + +
const EUnableToReceiveObject: u64 = 3;
+
+ + + + + +## Function `transfer` + + + +
public fun transfer<T: key>(obj: T, recipient: address)
+
+ + + +
+Implementation + + +
public fun transfer<T: key>(obj: T, recipient: address) {
+    transfer_impl(obj, recipient)
+}
+
+ + + +
+ + + +## Function `public_transfer` + + + +
public fun public_transfer<T: store, key>(obj: T, recipient: address)
+
+ + + +
+Implementation + + +
public fun public_transfer<T: key + store>(obj: T, recipient: address) {
+    transfer_impl(obj, recipient)
+}
+
+ + + +
+ + + +## Function `freeze_object` + + + +
public fun freeze_object<T: key>(obj: T)
+
+ + + +
+Implementation + + +
public fun freeze_object<T: key>(obj: T) {
+    freeze_object_impl(obj)
+}
+
+ + + +
+ + + +## Function `public_freeze_object` + + + +
public fun public_freeze_object<T: store, key>(obj: T)
+
+ + + +
+Implementation + + +
public fun public_freeze_object<T: key + store>(obj: T) {
+    freeze_object_impl(obj)
+}
+
+ + + +
+ + + +## Function `share_object` + + + +
public fun share_object<T: key>(obj: T)
+
+ + + +
+Implementation + + +
public fun share_object<T: key>(obj: T) {
+    share_object_impl(obj)
+}
+
+ + + +
+ + + +## Function `public_share_object` + + + +
public fun public_share_object<T: store, key>(obj: T)
+
+ + + +
+Implementation + + +
public fun public_share_object<T: key + store>(obj: T) {
+    share_object_impl(obj)
+}
+
+ + + +
+ + + +## Function `receive` + + + +
public fun receive<T: key>(parent: &mut object::UID, to_receive: transfer::Receiving<T>): T
+
+ + + +
+Implementation + + +
public fun receive<T: key>(parent: &mut UID, to_receive: Receiving<T>): T {
+    let Receiving {
+        id,
+        version,
+    } = to_receive;
+    receive_impl(object::uid_to_address(parent), id, version)
+}
+
+ + + +
+ + + +## Function `public_receive` + + + +
public fun public_receive<T: store, key>(parent: &mut object::UID, to_receive: transfer::Receiving<T>): T
+
+ + + +
+Implementation + + +
public fun public_receive<T: key + store>(parent: &mut UID, to_receive: Receiving<T>): T {
+    let Receiving {
+        id,
+        version,
+    } = to_receive;
+    receive_impl(object::uid_to_address(parent), id, version)
+}
+
+ + + +
+ + + +## Function `receiving_object_id` + + + +
public fun receiving_object_id<T: key>(receiving: &transfer::Receiving<T>): object::ID
+
+ + + +
+Implementation + + +
public fun receiving_object_id<T: key>(receiving: &Receiving<T>): ID {
+    receiving.id
+}
+
+ + + +
+ + + +## Function `freeze_object_impl` + + + +
public(friend) fun freeze_object_impl<T: key>(obj: T)
+
+ + + +
+Implementation + + +
public(friend) native fun freeze_object_impl<T: key>(obj: T);
+
+ + + +
+ + + +## Function `share_object_impl` + + + +
public(friend) fun share_object_impl<T: key>(obj: T)
+
+ + + +
+Implementation + + +
public(friend) native fun share_object_impl<T: key>(obj: T);
+
+ + + +
+ + + +## Function `transfer_impl` + + + +
public(friend) fun transfer_impl<T: key>(obj: T, recipient: address)
+
+ + + +
+Implementation + + +
public(friend) native fun transfer_impl<T: key>(obj: T, recipient: address);
+
+ + + +
+ + + +## Function `receive_impl` + + + +
fun receive_impl<T: key>(parent: address, to_receive: object::ID, version: u64): T
+
+ + + +
+Implementation + + +
native fun receive_impl<T: key>(parent: address, to_receive: object::ID, version: u64): T;
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/tx_context.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/tx_context.md new file mode 100644 index 00000000..d7ce6f26 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/tx_context.md @@ -0,0 +1,240 @@ + + + +# Module `0x2::tx_context` + + + +- [Struct `TxContext`](#0x2_tx_context_TxContext) +- [Function `sender`](#0x2_tx_context_sender) +- [Function `digest`](#0x2_tx_context_digest) +- [Function `epoch`](#0x2_tx_context_epoch) +- [Function `epoch_timestamp_ms`](#0x2_tx_context_epoch_timestamp_ms) +- [Function `fresh_object_address`](#0x2_tx_context_fresh_object_address) +- [Function `ids_created`](#0x2_tx_context_ids_created) +- [Function `derive_id`](#0x2_tx_context_derive_id) + + +
+ + + + + +## Struct `TxContext` + + + +
struct TxContext has drop
+
+ + + +
+Fields + + +
+
+sender: address +
+
+ +
+
+tx_hash: vector<u8> +
+
+ +
+
+epoch: u64 +
+
+ +
+
+epoch_timestamp_ms: u64 +
+
+ +
+
+ids_created: u64 +
+
+ +
+
+ + +
+ + + +## Function `sender` + + + +
public fun sender(self: &tx_context::TxContext): address
+
+ + + +
+Implementation + + +
public fun sender(self: &TxContext): address {
+    self.sender
+}
+
+ + + +
+ + + +## Function `digest` + + + +
public fun digest(self: &tx_context::TxContext): &vector<u8>
+
+ + + +
+Implementation + + +
public fun digest(self: &TxContext): &vector<u8> {
+    &self.tx_hash
+}
+
+ + + +
+ + + +## Function `epoch` + + + +
public fun epoch(self: &tx_context::TxContext): u64
+
+ + + +
+Implementation + + +
public fun epoch(self: &TxContext): u64 {
+    self.epoch
+}
+
+ + + +
+ + + +## Function `epoch_timestamp_ms` + + + +
public fun epoch_timestamp_ms(self: &tx_context::TxContext): u64
+
+ + + +
+Implementation + + +
public fun epoch_timestamp_ms(self: &TxContext): u64 {
+   self.epoch_timestamp_ms
+}
+
+ + + +
+ + + +## Function `fresh_object_address` + + + +
public fun fresh_object_address(ctx: &mut tx_context::TxContext): address
+
+ + + +
+Implementation + + +
public fun fresh_object_address(ctx: &mut TxContext): address {
+    let ids_created = ctx.ids_created;
+    let id = derive_id(*&ctx.tx_hash, ids_created);
+    ctx.ids_created = ids_created + 1;
+    id
+}
+
+ + + +
+ + + +## Function `ids_created` + + + +
fun ids_created(self: &tx_context::TxContext): u64
+
+ + + +
+Implementation + + +
fun ids_created(self: &TxContext): u64 {
+    self.ids_created
+}
+
+ + + +
+ + + +## Function `derive_id` + + + +
fun derive_id(tx_hash: vector<u8>, ids_created: u64): address
+
+ + + +
+Implementation + + +
native fun derive_id(tx_hash: vector<u8>, ids_created: u64): address;
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/types.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/types.md new file mode 100644 index 00000000..f4a7038b --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/types.md @@ -0,0 +1,35 @@ + + + +# Module `0x2::types` + + + +- [Function `is_one_time_witness`](#0x2_types_is_one_time_witness) + + +
+ + + + + +## Function `is_one_time_witness` + + + +
public fun is_one_time_witness<T: drop>(_: &T): bool
+
+ + + +
+Implementation + + +
public native fun is_one_time_witness<T: drop>(_: &T): bool;
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/url.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/url.md new file mode 100644 index 00000000..8425bb60 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/url.md @@ -0,0 +1,142 @@ + + + +# Module `0x2::url` + + + +- [Struct `Url`](#0x2_url_Url) +- [Function `new_unsafe`](#0x2_url_new_unsafe) +- [Function `new_unsafe_from_bytes`](#0x2_url_new_unsafe_from_bytes) +- [Function `inner_url`](#0x2_url_inner_url) +- [Function `update`](#0x2_url_update) + + +
use 0x1::ascii;
+
+ + + + + +## Struct `Url` + + + +
struct Url has copy, drop, store
+
+ + + +
+Fields + + +
+
+url: ascii::String +
+
+ +
+
+ + +
+ + + +## Function `new_unsafe` + + + +
public fun new_unsafe(url: ascii::String): url::Url
+
+ + + +
+Implementation + + +
public fun new_unsafe(url: String): Url {
+    Url { url }
+}
+
+ + + +
+ + + +## Function `new_unsafe_from_bytes` + + + +
public fun new_unsafe_from_bytes(bytes: vector<u8>): url::Url
+
+ + + +
+Implementation + + +
public fun new_unsafe_from_bytes(bytes: vector<u8>): Url {
+    let url = ascii::string(bytes);
+    Url { url }
+}
+
+ + + +
+ + + +## Function `inner_url` + + + +
public fun inner_url(self: &url::Url): ascii::String
+
+ + + +
+Implementation + + +
public fun inner_url(self: &Url): String{
+    self.url
+}
+
+ + + +
+ + + +## Function `update` + + + +
public fun update(self: &mut url::Url, url: ascii::String)
+
+ + + +
+Implementation + + +
public fun update(self: &mut Url, url: String) {
+    self.url = url;
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/vec_map.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/vec_map.md new file mode 100644 index 00000000..746574a8 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/vec_map.md @@ -0,0 +1,630 @@ + + + +# Module `0x2::vec_map` + + + +- [Struct `VecMap`](#0x2_vec_map_VecMap) +- [Struct `Entry`](#0x2_vec_map_Entry) +- [Constants](#@Constants_0) +- [Function `empty`](#0x2_vec_map_empty) +- [Function `insert`](#0x2_vec_map_insert) +- [Function `remove`](#0x2_vec_map_remove) +- [Function `pop`](#0x2_vec_map_pop) +- [Function `get_mut`](#0x2_vec_map_get_mut) +- [Function `get`](#0x2_vec_map_get) +- [Function `try_get`](#0x2_vec_map_try_get) +- [Function `contains`](#0x2_vec_map_contains) +- [Function `size`](#0x2_vec_map_size) +- [Function `is_empty`](#0x2_vec_map_is_empty) +- [Function `destroy_empty`](#0x2_vec_map_destroy_empty) +- [Function `into_keys_values`](#0x2_vec_map_into_keys_values) +- [Function `keys`](#0x2_vec_map_keys) +- [Function `get_idx_opt`](#0x2_vec_map_get_idx_opt) +- [Function `get_idx`](#0x2_vec_map_get_idx) +- [Function `get_entry_by_idx`](#0x2_vec_map_get_entry_by_idx) +- [Function `get_entry_by_idx_mut`](#0x2_vec_map_get_entry_by_idx_mut) +- [Function `remove_entry_by_idx`](#0x2_vec_map_remove_entry_by_idx) + + +
use 0x1::option;
+use 0x1::vector;
+
+ + + + + +## Struct `VecMap` + + + +
struct VecMap<K: copy, V> has copy, drop, store
+
+ + + +
+Fields + + +
+
+contents: vector<vec_map::Entry<K, V>> +
+
+ +
+
+ + +
+ + + +## Struct `Entry` + + + +
struct Entry<K: copy, V> has copy, drop, store
+
+ + + +
+Fields + + +
+
+key: K +
+
+ +
+
+value: V +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const EKeyAlreadyExists: u64 = 0;
+
+ + + + + + + +
const EKeyDoesNotExist: u64 = 1;
+
+ + + + + + + +
const EIndexOutOfBounds: u64 = 3;
+
+ + + + + + + +
const EMapEmpty: u64 = 4;
+
+ + + + + + + +
const EMapNotEmpty: u64 = 2;
+
+ + + + + +## Function `empty` + + + +
public fun empty<K: copy, V>(): vec_map::VecMap<K, V>
+
+ + + +
+Implementation + + +
public fun empty<K: copy, V>(): VecMap<K,V> {
+    VecMap { contents: vector::empty() }
+}
+
+ + + +
+ + + +## Function `insert` + + + +
public fun insert<K: copy, V>(self: &mut vec_map::VecMap<K, V>, key: K, value: V)
+
+ + + +
+Implementation + + +
public fun insert<K: copy, V>(self: &mut VecMap<K,V>, key: K, value: V) {
+    assert!(!contains(self, &key), EKeyAlreadyExists);
+    vector::push_back(&mut self.contents, Entry { key, value })
+}
+
+ + + +
+ + + +## Function `remove` + + + +
public fun remove<K: copy, V>(self: &mut vec_map::VecMap<K, V>, key: &K): (K, V)
+
+ + + +
+Implementation + + +
public fun remove<K: copy, V>(self: &mut VecMap<K,V>, key: &K): (K, V) {
+    let idx = get_idx(self, key);
+    let Entry { key, value } = vector::remove(&mut self.contents, idx);
+    (key, value)
+}
+
+ + + +
+ + + +## Function `pop` + + + +
public fun pop<K: copy, V>(self: &mut vec_map::VecMap<K, V>): (K, V)
+
+ + + +
+Implementation + + +
public fun pop<K: copy, V>(self: &mut VecMap<K,V>): (K, V) {
+    assert!(!vector::is_empty(&self.contents), EMapEmpty);
+    let Entry { key, value } = vector::pop_back(&mut self.contents);
+    (key, value)
+}
+
+ + + +
+ + + +## Function `get_mut` + + + +
public fun get_mut<K: copy, V>(self: &mut vec_map::VecMap<K, V>, key: &K): &mut V
+
+ + + +
+Implementation + + +
public fun get_mut<K: copy, V>(self: &mut VecMap<K,V>, key: &K): &mut V {
+    let idx = get_idx(self, key);
+    let entry = vector::borrow_mut(&mut self.contents, idx);
+    &mut entry.value
+}
+
+ + + +
+ + + +## Function `get` + + + +
public fun get<K: copy, V>(self: &vec_map::VecMap<K, V>, key: &K): &V
+
+ + + +
+Implementation + + +
public fun get<K: copy, V>(self: &VecMap<K,V>, key: &K): &V {
+    let idx = get_idx(self, key);
+    let entry = vector::borrow(&self.contents, idx);
+    &entry.value
+}
+
+ + + +
+ + + +## Function `try_get` + + + +
public fun try_get<K: copy, V: copy>(self: &vec_map::VecMap<K, V>, key: &K): option::Option<V>
+
+ + + +
+Implementation + + +
public fun try_get<K: copy, V: copy>(self: &VecMap<K,V>, key: &K): Option<V> {
+    if (contains(self, key)) {
+        option::some(*get(self, key))
+    } else {
+        option::none()
+    }
+}
+
+ + + +
+ + + +## Function `contains` + + + +
public fun contains<K: copy, V>(self: &vec_map::VecMap<K, V>, key: &K): bool
+
+ + + +
+Implementation + + +
public fun contains<K: copy, V>(self: &VecMap<K, V>, key: &K): bool {
+    option::is_some(&get_idx_opt(self, key))
+}
+
+ + + +
+ + + +## Function `size` + + + +
public fun size<K: copy, V>(self: &vec_map::VecMap<K, V>): u64
+
+ + + +
+Implementation + + +
public fun size<K: copy, V>(self: &VecMap<K,V>): u64 {
+    vector::length(&self.contents)
+}
+
+ + + +
+ + + +## Function `is_empty` + + + +
public fun is_empty<K: copy, V>(self: &vec_map::VecMap<K, V>): bool
+
+ + + +
+Implementation + + +
public fun is_empty<K: copy, V>(self: &VecMap<K,V>): bool {
+    size(self) == 0
+}
+
+ + + +
+ + + +## Function `destroy_empty` + + + +
public fun destroy_empty<K: copy, V>(self: vec_map::VecMap<K, V>)
+
+ + + +
+Implementation + + +
public fun destroy_empty<K: copy, V>(self: VecMap<K, V>) {
+    let VecMap { contents } = self;
+    assert!(vector::is_empty(&contents), EMapNotEmpty);
+    vector::destroy_empty(contents)
+}
+
+ + + +
+ + + +## Function `into_keys_values` + + + +
public fun into_keys_values<K: copy, V>(self: vec_map::VecMap<K, V>): (vector<K>, vector<V>)
+
+ + + +
+Implementation + + +
public fun into_keys_values<K: copy, V>(self: VecMap<K, V>): (vector<K>, vector<V>) {
+    let VecMap { contents } = self;
+    // reverse the vector so the output keys and values will appear in insertion order
+    vector::reverse(&mut contents);
+    let i = 0;
+    let n = vector::length(&contents);
+    let keys = vector::empty();
+    let values = vector::empty();
+    while (i < n) {
+        let Entry { key, value } = vector::pop_back(&mut contents);
+        vector::push_back(&mut keys, key);
+        vector::push_back(&mut values, value);
+        i = i + 1;
+    };
+    vector::destroy_empty(contents);
+    (keys, values)
+}
+
+ + + +
+ + + +## Function `keys` + + + +
public fun keys<K: copy, V>(self: &vec_map::VecMap<K, V>): vector<K>
+
+ + + +
+Implementation + + +
public fun keys<K: copy, V>(self: &VecMap<K, V>): vector<K> {
+    let i = 0;
+    let n = vector::length(&self.contents);
+    let keys = vector::empty();
+    while (i < n) {
+        let entry = vector::borrow(&self.contents, i);
+        vector::push_back(&mut keys, entry.key);
+        i = i + 1;
+    };
+    keys
+}
+
+ + + +
+ + + +## Function `get_idx_opt` + + + +
public fun get_idx_opt<K: copy, V>(self: &vec_map::VecMap<K, V>, key: &K): option::Option<u64>
+
+ + + +
+Implementation + + +
public fun get_idx_opt<K: copy, V>(self: &VecMap<K,V>, key: &K): Option<u64> {
+    let i = 0;
+    let n = size(self);
+    while (i < n) {
+        if (&vector::borrow(&self.contents, i).key == key) {
+            return option::some(i)
+        };
+        i = i + 1;
+    };
+    option::none()
+}
+
+ + + +
+ + + +## Function `get_idx` + + + +
public fun get_idx<K: copy, V>(self: &vec_map::VecMap<K, V>, key: &K): u64
+
+ + + +
+Implementation + + +
public fun get_idx<K: copy, V>(self: &VecMap<K,V>, key: &K): u64 {
+    let idx_opt = get_idx_opt(self, key);
+    assert!(option::is_some(&idx_opt), EKeyDoesNotExist);
+    option::destroy_some(idx_opt)
+}
+
+ + + +
+ + + +## Function `get_entry_by_idx` + + + +
public fun get_entry_by_idx<K: copy, V>(self: &vec_map::VecMap<K, V>, idx: u64): (&K, &V)
+
+ + + +
+Implementation + + +
public fun get_entry_by_idx<K: copy, V>(self: &VecMap<K, V>, idx: u64): (&K, &V) {
+    assert!(idx < size(self), EIndexOutOfBounds);
+    let entry = vector::borrow(&self.contents, idx);
+    (&entry.key, &entry.value)
+}
+
+ + + +
+ + + +## Function `get_entry_by_idx_mut` + + + +
public fun get_entry_by_idx_mut<K: copy, V>(self: &mut vec_map::VecMap<K, V>, idx: u64): (&K, &mut V)
+
+ + + +
+Implementation + + +
public fun get_entry_by_idx_mut<K: copy, V>(self: &mut VecMap<K, V>, idx: u64): (&K, &mut V) {
+    assert!(idx < size(self), EIndexOutOfBounds);
+    let entry = vector::borrow_mut(&mut self.contents, idx);
+    (&entry.key, &mut entry.value)
+}
+
+ + + +
+ + + +## Function `remove_entry_by_idx` + + + +
public fun remove_entry_by_idx<K: copy, V>(self: &mut vec_map::VecMap<K, V>, idx: u64): (K, V)
+
+ + + +
+Implementation + + +
public fun remove_entry_by_idx<K: copy, V>(self: &mut VecMap<K, V>, idx: u64): (K, V) {
+    assert!(idx < size(self), EIndexOutOfBounds);
+    let Entry { key, value } = vector::remove(&mut self.contents, idx);
+    (key, value)
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/vec_set.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/vec_set.md new file mode 100644 index 00000000..2da9e7c7 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/vec_set.md @@ -0,0 +1,354 @@ + + + +# Module `0x2::vec_set` + + + +- [Struct `VecSet`](#0x2_vec_set_VecSet) +- [Constants](#@Constants_0) +- [Function `empty`](#0x2_vec_set_empty) +- [Function `singleton`](#0x2_vec_set_singleton) +- [Function `insert`](#0x2_vec_set_insert) +- [Function `remove`](#0x2_vec_set_remove) +- [Function `contains`](#0x2_vec_set_contains) +- [Function `size`](#0x2_vec_set_size) +- [Function `is_empty`](#0x2_vec_set_is_empty) +- [Function `into_keys`](#0x2_vec_set_into_keys) +- [Function `keys`](#0x2_vec_set_keys) +- [Function `get_idx_opt`](#0x2_vec_set_get_idx_opt) +- [Function `get_idx`](#0x2_vec_set_get_idx) + + +
use 0x1::option;
+use 0x1::vector;
+
+ + + + + +## Struct `VecSet` + + + +
struct VecSet<K: copy, drop> has copy, drop, store
+
+ + + +
+Fields + + +
+
+contents: vector<K> +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const EKeyAlreadyExists: u64 = 0;
+
+ + + + + + + +
const EKeyDoesNotExist: u64 = 1;
+
+ + + + + +## Function `empty` + + + +
public fun empty<K: copy, drop>(): vec_set::VecSet<K>
+
+ + + +
+Implementation + + +
public fun empty<K: copy + drop>(): VecSet<K> {
+    VecSet { contents: vector::empty() }
+}
+
+ + + +
+ + + +## Function `singleton` + + + +
public fun singleton<K: copy, drop>(key: K): vec_set::VecSet<K>
+
+ + + +
+Implementation + + +
public fun singleton<K: copy + drop>(key: K): VecSet<K> {
+    VecSet { contents: vector::singleton(key) }
+}
+
+ + + +
+ + + +## Function `insert` + + + +
public fun insert<K: copy, drop>(self: &mut vec_set::VecSet<K>, key: K)
+
+ + + +
+Implementation + + +
public fun insert<K: copy + drop>(self: &mut VecSet<K>, key: K) {
+    assert!(!contains(self, &key), EKeyAlreadyExists);
+    vector::push_back(&mut self.contents, key)
+}
+
+ + + +
+ + + +## Function `remove` + + + +
public fun remove<K: copy, drop>(self: &mut vec_set::VecSet<K>, key: &K)
+
+ + + +
+Implementation + + +
public fun remove<K: copy + drop>(self: &mut VecSet<K>, key: &K) {
+    let idx = get_idx(self, key);
+    vector::remove(&mut self.contents, idx);
+}
+
+ + + +
+ + + +## Function `contains` + + + +
public fun contains<K: copy, drop>(self: &vec_set::VecSet<K>, key: &K): bool
+
+ + + +
+Implementation + + +
public fun contains<K: copy + drop>(self: &VecSet<K>, key: &K): bool {
+    option::is_some(&get_idx_opt(self, key))
+}
+
+ + + +
+ + + +## Function `size` + + + +
public fun size<K: copy, drop>(self: &vec_set::VecSet<K>): u64
+
+ + + +
+Implementation + + +
public fun size<K: copy + drop>(self: &VecSet<K>): u64 {
+    vector::length(&self.contents)
+}
+
+ + + +
+ + + +## Function `is_empty` + + + +
public fun is_empty<K: copy, drop>(self: &vec_set::VecSet<K>): bool
+
+ + + +
+Implementation + + +
public fun is_empty<K: copy + drop>(self: &VecSet<K>): bool {
+    size(self) == 0
+}
+
+ + + +
+ + + +## Function `into_keys` + + + +
public fun into_keys<K: copy, drop>(self: vec_set::VecSet<K>): vector<K>
+
+ + + +
+Implementation + + +
public fun into_keys<K: copy + drop>(self: VecSet<K>): vector<K> {
+    let VecSet { contents } = self;
+    contents
+}
+
+ + + +
+ + + +## Function `keys` + + + +
public fun keys<K: copy, drop>(self: &vec_set::VecSet<K>): &vector<K>
+
+ + + +
+Implementation + + +
public fun keys<K: copy + drop>(self: &VecSet<K>): &vector<K> {
+    &self.contents
+}
+
+ + + +
+ + + +## Function `get_idx_opt` + + + +
fun get_idx_opt<K: copy, drop>(self: &vec_set::VecSet<K>, key: &K): option::Option<u64>
+
+ + + +
+Implementation + + +
fun get_idx_opt<K: copy + drop>(self: &VecSet<K>, key: &K): Option<u64> {
+    let i = 0;
+    let n = size(self);
+    while (i < n) {
+        if (vector::borrow(&self.contents, i) == key) {
+            return option::some(i)
+        };
+        i = i + 1;
+    };
+    option::none()
+}
+
+ + + +
+ + + +## Function `get_idx` + + + +
fun get_idx<K: copy, drop>(self: &vec_set::VecSet<K>, key: &K): u64
+
+ + + +
+Implementation + + +
fun get_idx<K: copy + drop>(self: &VecSet<K>, key: &K): u64 {
+    let idx_opt = get_idx_opt(self, key);
+    assert!(option::is_some(&idx_opt), EKeyDoesNotExist);
+    option::destroy_some(idx_opt)
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/versioned.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/versioned.md new file mode 100644 index 00000000..199b7346 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/mgo-framework/versioned.md @@ -0,0 +1,291 @@ + + + +# Module `0x2::versioned` + + + +- [Resource `Versioned`](#0x2_versioned_Versioned) +- [Struct `VersionChangeCap`](#0x2_versioned_VersionChangeCap) +- [Constants](#@Constants_0) +- [Function `create`](#0x2_versioned_create) +- [Function `version`](#0x2_versioned_version) +- [Function `load_value`](#0x2_versioned_load_value) +- [Function `load_value_mut`](#0x2_versioned_load_value_mut) +- [Function `remove_value_for_upgrade`](#0x2_versioned_remove_value_for_upgrade) +- [Function `upgrade`](#0x2_versioned_upgrade) +- [Function `destroy`](#0x2_versioned_destroy) + + +
use 0x2::dynamic_field;
+use 0x2::object;
+use 0x2::tx_context;
+
+ + + + + +## Resource `Versioned` + + + +
struct Versioned has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+version: u64 +
+
+ +
+
+ + +
+ + + +## Struct `VersionChangeCap` + + + +
struct VersionChangeCap
+
+ + + +
+Fields + + +
+
+versioned_id: object::ID +
+
+ +
+
+old_version: u64 +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const EInvalidUpgrade: u64 = 0;
+
+ + + + + +## Function `create` + + + +
public fun create<T: store>(init_version: u64, init_value: T, ctx: &mut tx_context::TxContext): versioned::Versioned
+
+ + + +
+Implementation + + +
public fun create<T: store>(init_version: u64, init_value: T, ctx: &mut TxContext): Versioned {
+    let self = Versioned {
+        id: object::new(ctx),
+        version: init_version,
+    };
+    dynamic_field::add(&mut self.id, init_version, init_value);
+    self
+}
+
+ + + +
+ + + +## Function `version` + + + +
public fun version(self: &versioned::Versioned): u64
+
+ + + +
+Implementation + + +
public fun version(self: &Versioned): u64 {
+    self.version
+}
+
+ + + +
+ + + +## Function `load_value` + + + +
public fun load_value<T: store>(self: &versioned::Versioned): &T
+
+ + + +
+Implementation + + +
public fun load_value<T: store>(self: &Versioned): &T {
+    dynamic_field::borrow(&self.id, self.version)
+}
+
+ + + +
+ + + +## Function `load_value_mut` + + + +
public fun load_value_mut<T: store>(self: &mut versioned::Versioned): &mut T
+
+ + + +
+Implementation + + +
public fun load_value_mut<T: store>(self: &mut Versioned): &mut T {
+    dynamic_field::borrow_mut(&mut self.id, self.version)
+}
+
+ + + +
+ + + +## Function `remove_value_for_upgrade` + + + +
public fun remove_value_for_upgrade<T: store>(self: &mut versioned::Versioned): (T, versioned::VersionChangeCap)
+
+ + + +
+Implementation + + +
public fun remove_value_for_upgrade<T: store>(self: &mut Versioned): (T, VersionChangeCap) {
+    (
+        dynamic_field::remove(&mut self.id, self.version),
+        VersionChangeCap {
+            versioned_id: object::id(self),
+            old_version: self.version,
+        }
+    )
+}
+
+ + + +
+ + + +## Function `upgrade` + + + +
public fun upgrade<T: store>(self: &mut versioned::Versioned, new_version: u64, new_value: T, cap: versioned::VersionChangeCap)
+
+ + + +
+Implementation + + +
public fun upgrade<T: store>(self: &mut Versioned, new_version: u64, new_value: T, cap: VersionChangeCap) {
+    let VersionChangeCap { versioned_id, old_version } = cap;
+    assert!(versioned_id == object::id(self), EInvalidUpgrade);
+    assert!(old_version < new_version, EInvalidUpgrade);
+    dynamic_field::add(&mut self.id, new_version, new_value);
+    self.version = new_version;
+}
+
+ + + +
+ + + +## Function `destroy` + + + +
public fun destroy<T: store>(self: versioned::Versioned): T
+
+ + + +
+Implementation + + +
public fun destroy<T: store>(self: Versioned): T {
+    let Versioned { id, version } = self;
+    let ret = dynamic_field::remove(&mut id, version);
+    object::delete(id);
+    ret
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/address.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/address.md new file mode 100644 index 00000000..dd10b7d1 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/address.md @@ -0,0 +1,37 @@ + + + +# Module `0x1::address` + + + +- [Function `length`](#0x1_address_length) + + +
+ + + + + +## Function `length` + + + +
public fun length(): u64
+
+ + + +
+Implementation + + +
public fun length(): u64 {
+    32
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/ascii.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/ascii.md new file mode 100644 index 00000000..bf876816 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/ascii.md @@ -0,0 +1,407 @@ + + + +# Module `0x1::ascii` + + + +- [Struct `String`](#0x1_ascii_String) +- [Struct `Char`](#0x1_ascii_Char) +- [Constants](#@Constants_0) +- [Function `char`](#0x1_ascii_char) +- [Function `string`](#0x1_ascii_string) +- [Function `try_string`](#0x1_ascii_try_string) +- [Function `all_characters_printable`](#0x1_ascii_all_characters_printable) +- [Function `push_char`](#0x1_ascii_push_char) +- [Function `pop_char`](#0x1_ascii_pop_char) +- [Function `length`](#0x1_ascii_length) +- [Function `as_bytes`](#0x1_ascii_as_bytes) +- [Function `into_bytes`](#0x1_ascii_into_bytes) +- [Function `byte`](#0x1_ascii_byte) +- [Function `is_valid_char`](#0x1_ascii_is_valid_char) +- [Function `is_printable_char`](#0x1_ascii_is_printable_char) + + +
use 0x1::option;
+
+ + + + + +## Struct `String` + + + +
struct String has copy, drop, store
+
+ + + +
+Fields + + +
+
+bytes: vector<u8> +
+
+ +
+
+ + +
+ + + +## Struct `Char` + + + +
struct Char has copy, drop, store
+
+ + + +
+Fields + + +
+
+byte: u8 +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const EINVALID_ASCII_CHARACTER: u64 = 65536;
+
+ + + + + +## Function `char` + + + +
public fun char(byte: u8): ascii::Char
+
+ + + +
+Implementation + + +
public fun char(byte: u8): Char {
+    assert!(is_valid_char(byte), EINVALID_ASCII_CHARACTER);
+    Char { byte }
+}
+
+ + + +
+ + + +## Function `string` + + + +
public fun string(bytes: vector<u8>): ascii::String
+
+ + + +
+Implementation + + +
public fun string(bytes: vector<u8>): String {
+   let x = try_string(bytes);
+   assert!(
+        option::is_some(&x),
+        EINVALID_ASCII_CHARACTER
+   );
+   option::destroy_some(x)
+}
+
+ + + +
+ + + +## Function `try_string` + + + +
public fun try_string(bytes: vector<u8>): option::Option<ascii::String>
+
+ + + +
+Implementation + + +
public fun try_string(bytes: vector<u8>): Option<String> {
+    let len = vector::length(&bytes);
+    let i = 0;
+    while (i < len) {
+        let possible_byte = *vector::borrow(&bytes, i);
+        if (!is_valid_char(possible_byte)) return option::none();
+        i = i + 1;
+    };
+    option::some(String { bytes })
+}
+
+ + + +
+ + + +## Function `all_characters_printable` + + + +
public fun all_characters_printable(string: &ascii::String): bool
+
+ + + +
+Implementation + + +
public fun all_characters_printable(string: &String): bool {
+    let len = vector::length(&string.bytes);
+    let i = 0;
+    while (i < len) {
+        let byte = *vector::borrow(&string.bytes, i);
+        if (!is_printable_char(byte)) return false;
+        i = i + 1;
+    };
+    true
+}
+
+ + + +
+ + + +## Function `push_char` + + + +
public fun push_char(string: &mut ascii::String, char: ascii::Char)
+
+ + + +
+Implementation + + +
public fun push_char(string: &mut String, char: Char) {
+    vector::push_back(&mut string.bytes, char.byte);
+}
+
+ + + +
+ + + +## Function `pop_char` + + + +
public fun pop_char(string: &mut ascii::String): ascii::Char
+
+ + + +
+Implementation + + +
public fun pop_char(string: &mut String): Char {
+    Char { byte: vector::pop_back(&mut string.bytes) }
+}
+
+ + + +
+ + + +## Function `length` + + + +
public fun length(string: &ascii::String): u64
+
+ + + +
+Implementation + + +
public fun length(string: &String): u64 {
+    vector::length(as_bytes(string))
+}
+
+ + + +
+ + + +## Function `as_bytes` + + + +
public fun as_bytes(string: &ascii::String): &vector<u8>
+
+ + + +
+Implementation + + +
public fun as_bytes(string: &String): &vector<u8> {
+   &string.bytes
+}
+
+ + + +
+ + + +## Function `into_bytes` + + + +
public fun into_bytes(string: ascii::String): vector<u8>
+
+ + + +
+Implementation + + +
public fun into_bytes(string: String): vector<u8> {
+   let String { bytes } = string;
+   bytes
+}
+
+ + + +
+ + + +## Function `byte` + + + +
public fun byte(char: ascii::Char): u8
+
+ + + +
+Implementation + + +
public fun byte(char: Char): u8 {
+   let Char { byte } = char;
+   byte
+}
+
+ + + +
+ + + +## Function `is_valid_char` + + + +
public fun is_valid_char(b: u8): bool
+
+ + + +
+Implementation + + +
public fun is_valid_char(b: u8): bool {
+   b <= 0x7F
+}
+
+ + + +
+ + + +## Function `is_printable_char` + + + +
public fun is_printable_char(byte: u8): bool
+
+ + + +
+Implementation + + +
public fun is_printable_char(byte: u8): bool {
+   byte >= 0x20 && // Disallow metacharacters
+   byte <= 0x7E // Don't allow DEL metacharacter
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/bcs.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/bcs.md new file mode 100644 index 00000000..28c8dcf4 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/bcs.md @@ -0,0 +1,35 @@ + + + +# Module `0x1::bcs` + + + +- [Function `to_bytes`](#0x1_bcs_to_bytes) + + +
+ + + + + +## Function `to_bytes` + + + +
public fun to_bytes<MoveValue>(v: &MoveValue): vector<u8>
+
+ + + +
+Implementation + + +
native public fun to_bytes<MoveValue>(v: &MoveValue): vector<u8>;
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/option.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/option.md new file mode 100644 index 00000000..f161bb1b --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/option.md @@ -0,0 +1,519 @@ + + + +# Module `0x1::option` + + + +- [Struct `Option`](#0x1_option_Option) +- [Constants](#@Constants_0) +- [Function `none`](#0x1_option_none) +- [Function `some`](#0x1_option_some) +- [Function `is_none`](#0x1_option_is_none) +- [Function `is_some`](#0x1_option_is_some) +- [Function `contains`](#0x1_option_contains) +- [Function `borrow`](#0x1_option_borrow) +- [Function `borrow_with_default`](#0x1_option_borrow_with_default) +- [Function `get_with_default`](#0x1_option_get_with_default) +- [Function `fill`](#0x1_option_fill) +- [Function `extract`](#0x1_option_extract) +- [Function `borrow_mut`](#0x1_option_borrow_mut) +- [Function `swap`](#0x1_option_swap) +- [Function `swap_or_fill`](#0x1_option_swap_or_fill) +- [Function `destroy_with_default`](#0x1_option_destroy_with_default) +- [Function `destroy_some`](#0x1_option_destroy_some) +- [Function `destroy_none`](#0x1_option_destroy_none) +- [Function `to_vec`](#0x1_option_to_vec) + + +
use 0x1::vector;
+
+ + + + + +## Struct `Option` + + + +
struct Option<Element> has copy, drop, store
+
+ + + +
+Fields + + +
+
+vec: vector<Element> +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const EOPTION_IS_SET: u64 = 262144;
+
+ + + + + + + +
const EOPTION_NOT_SET: u64 = 262145;
+
+ + + + + +## Function `none` + + + +
public fun none<Element>(): option::Option<Element>
+
+ + + +
+Implementation + + +
public fun none<Element>(): Option<Element> {
+    Option { vec: vector::empty() }
+}
+
+ + + +
+ + + +## Function `some` + + + +
public fun some<Element>(e: Element): option::Option<Element>
+
+ + + +
+Implementation + + +
public fun some<Element>(e: Element): Option<Element> {
+    Option { vec: vector::singleton(e) }
+}
+
+ + + +
+ + + +## Function `is_none` + + + +
public fun is_none<Element>(t: &option::Option<Element>): bool
+
+ + + +
+Implementation + + +
public fun is_none<Element>(t: &Option<Element>): bool {
+    vector::is_empty(&t.vec)
+}
+
+ + + +
+ + + +## Function `is_some` + + + +
public fun is_some<Element>(t: &option::Option<Element>): bool
+
+ + + +
+Implementation + + +
public fun is_some<Element>(t: &Option<Element>): bool {
+    !vector::is_empty(&t.vec)
+}
+
+ + + +
+ + + +## Function `contains` + + + +
public fun contains<Element>(t: &option::Option<Element>, e_ref: &Element): bool
+
+ + + +
+Implementation + + +
public fun contains<Element>(t: &Option<Element>, e_ref: &Element): bool {
+    vector::contains(&t.vec, e_ref)
+}
+
+ + + +
+ + + +## Function `borrow` + + + +
public fun borrow<Element>(t: &option::Option<Element>): &Element
+
+ + + +
+Implementation + + +
public fun borrow<Element>(t: &Option<Element>): &Element {
+    assert!(is_some(t), EOPTION_NOT_SET);
+    vector::borrow(&t.vec, 0)
+}
+
+ + + +
+ + + +## Function `borrow_with_default` + + + +
public fun borrow_with_default<Element>(t: &option::Option<Element>, default_ref: &Element): &Element
+
+ + + +
+Implementation + + +
public fun borrow_with_default<Element>(t: &Option<Element>, default_ref: &Element): &Element {
+    let vec_ref = &t.vec;
+    if (vector::is_empty(vec_ref)) default_ref
+    else vector::borrow(vec_ref, 0)
+}
+
+ + + +
+ + + +## Function `get_with_default` + + + +
public fun get_with_default<Element: copy, drop>(t: &option::Option<Element>, default: Element): Element
+
+ + + +
+Implementation + + +
public fun get_with_default<Element: copy + drop>(
+    t: &Option<Element>,
+    default: Element,
+): Element {
+    let vec_ref = &t.vec;
+    if (vector::is_empty(vec_ref)) default
+    else *vector::borrow(vec_ref, 0)
+}
+
+ + + +
+ + + +## Function `fill` + + + +
public fun fill<Element>(t: &mut option::Option<Element>, e: Element)
+
+ + + +
+Implementation + + +
public fun fill<Element>(t: &mut Option<Element>, e: Element) {
+    let vec_ref = &mut t.vec;
+    if (vector::is_empty(vec_ref)) vector::push_back(vec_ref, e)
+    else abort EOPTION_IS_SET
+}
+
+ + + +
+ + + +## Function `extract` + + + +
public fun extract<Element>(t: &mut option::Option<Element>): Element
+
+ + + +
+Implementation + + +
public fun extract<Element>(t: &mut Option<Element>): Element {
+    assert!(is_some(t), EOPTION_NOT_SET);
+    vector::pop_back(&mut t.vec)
+}
+
+ + + +
+ + + +## Function `borrow_mut` + + + +
public fun borrow_mut<Element>(t: &mut option::Option<Element>): &mut Element
+
+ + + +
+Implementation + + +
public fun borrow_mut<Element>(t: &mut Option<Element>): &mut Element {
+    assert!(is_some(t), EOPTION_NOT_SET);
+    vector::borrow_mut(&mut t.vec, 0)
+}
+
+ + + +
+ + + +## Function `swap` + + + +
public fun swap<Element>(t: &mut option::Option<Element>, e: Element): Element
+
+ + + +
+Implementation + + +
public fun swap<Element>(t: &mut Option<Element>, e: Element): Element {
+    assert!(is_some(t), EOPTION_NOT_SET);
+    let vec_ref = &mut t.vec;
+    let old_value = vector::pop_back(vec_ref);
+    vector::push_back(vec_ref, e);
+    old_value
+}
+
+ + + +
+ + + +## Function `swap_or_fill` + + + +
public fun swap_or_fill<Element>(t: &mut option::Option<Element>, e: Element): option::Option<Element>
+
+ + + +
+Implementation + + +
public fun swap_or_fill<Element>(t: &mut Option<Element>, e: Element): Option<Element> {
+    let vec_ref = &mut t.vec;
+    let old_value = if (vector::is_empty(vec_ref)) none()
+        else some(vector::pop_back(vec_ref));
+    vector::push_back(vec_ref, e);
+    old_value
+}
+
+ + + +
+ + + +## Function `destroy_with_default` + + + +
public fun destroy_with_default<Element: drop>(t: option::Option<Element>, default: Element): Element
+
+ + + +
+Implementation + + +
public fun destroy_with_default<Element: drop>(t: Option<Element>, default: Element): Element {
+    let Option { vec } = t;
+    if (vector::is_empty(&vec)) default
+    else vector::pop_back(&mut vec)
+}
+
+ + + +
+ + + +## Function `destroy_some` + + + +
public fun destroy_some<Element>(t: option::Option<Element>): Element
+
+ + + +
+Implementation + + +
public fun destroy_some<Element>(t: Option<Element>): Element {
+    assert!(is_some(&t), EOPTION_NOT_SET);
+    let Option { vec } = t;
+    let elem = vector::pop_back(&mut vec);
+    vector::destroy_empty(vec);
+    elem
+}
+
+ + + +
+ + + +## Function `destroy_none` + + + +
public fun destroy_none<Element>(t: option::Option<Element>)
+
+ + + +
+Implementation + + +
public fun destroy_none<Element>(t: Option<Element>) {
+    assert!(is_none(&t), EOPTION_IS_SET);
+    let Option { vec } = t;
+    vector::destroy_empty(vec)
+}
+
+ + + +
+ + + +## Function `to_vec` + + + +
public fun to_vec<Element>(t: option::Option<Element>): vector<Element>
+
+ + + +
+Implementation + + +
public fun to_vec<Element>(t: Option<Element>): vector<Element> {
+    let Option { vec } = t;
+    vec
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/string.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/string.md new file mode 100644 index 00000000..4a48dbc3 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/string.md @@ -0,0 +1,478 @@ + + + +# Module `0x1::string` + + + +- [Struct `String`](#0x1_string_String) +- [Constants](#@Constants_0) +- [Function `utf8`](#0x1_string_utf8) +- [Function `from_ascii`](#0x1_string_from_ascii) +- [Function `to_ascii`](#0x1_string_to_ascii) +- [Function `try_utf8`](#0x1_string_try_utf8) +- [Function `bytes`](#0x1_string_bytes) +- [Function `is_empty`](#0x1_string_is_empty) +- [Function `length`](#0x1_string_length) +- [Function `append`](#0x1_string_append) +- [Function `append_utf8`](#0x1_string_append_utf8) +- [Function `insert`](#0x1_string_insert) +- [Function `sub_string`](#0x1_string_sub_string) +- [Function `index_of`](#0x1_string_index_of) +- [Function `internal_check_utf8`](#0x1_string_internal_check_utf8) +- [Function `internal_is_char_boundary`](#0x1_string_internal_is_char_boundary) +- [Function `internal_sub_string`](#0x1_string_internal_sub_string) +- [Function `internal_index_of`](#0x1_string_internal_index_of) + + +
use 0x1::ascii;
+use 0x1::option;
+use 0x1::vector;
+
+ + + + + +## Struct `String` + + + +
struct String has copy, drop, store
+
+ + + +
+Fields + + +
+
+bytes: vector<u8> +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const EINVALID_INDEX: u64 = 2;
+
+ + + + + + + +
const EINVALID_UTF8: u64 = 1;
+
+ + + + + +## Function `utf8` + + + +
public fun utf8(bytes: vector<u8>): string::String
+
+ + + +
+Implementation + + +
public fun utf8(bytes: vector<u8>): String {
+    assert!(internal_check_utf8(&bytes), EINVALID_UTF8);
+    String{bytes}
+}
+
+ + + +
+ + + +## Function `from_ascii` + + + +
public fun from_ascii(s: ascii::String): string::String
+
+ + + +
+Implementation + + +
public fun from_ascii(s: ascii::String): String {
+    String { bytes: ascii::into_bytes(s) }
+}
+
+ + + +
+ + + +## Function `to_ascii` + + + +
public fun to_ascii(s: string::String): ascii::String
+
+ + + +
+Implementation + + +
public fun to_ascii(s: String): ascii::String {
+    let String { bytes } = s;
+    ascii::string(bytes)
+}
+
+ + + +
+ + + +## Function `try_utf8` + + + +
public fun try_utf8(bytes: vector<u8>): option::Option<string::String>
+
+ + + +
+Implementation + + +
public fun try_utf8(bytes: vector<u8>): Option<String> {
+    if (internal_check_utf8(&bytes)) {
+        option::some(String{bytes})
+    } else {
+        option::none()
+    }
+}
+
+ + + +
+ + + +## Function `bytes` + + + +
public fun bytes(s: &string::String): &vector<u8>
+
+ + + +
+Implementation + + +
public fun bytes(s: &String): &vector<u8> {
+    &s.bytes
+}
+
+ + + +
+ + + +## Function `is_empty` + + + +
public fun is_empty(s: &string::String): bool
+
+ + + +
+Implementation + + +
public fun is_empty(s: &String): bool {
+    vector::is_empty(&s.bytes)
+}
+
+ + + +
+ + + +## Function `length` + + + +
public fun length(s: &string::String): u64
+
+ + + +
+Implementation + + +
public fun length(s: &String): u64 {
+    vector::length(&s.bytes)
+}
+
+ + + +
+ + + +## Function `append` + + + +
public fun append(s: &mut string::String, r: string::String)
+
+ + + +
+Implementation + + +
public fun append(s: &mut String, r: String) {
+    vector::append(&mut s.bytes, r.bytes)
+}
+
+ + + +
+ + + +## Function `append_utf8` + + + +
public fun append_utf8(s: &mut string::String, bytes: vector<u8>)
+
+ + + +
+Implementation + + +
public fun append_utf8(s: &mut String, bytes: vector<u8>) {
+    append(s, utf8(bytes))
+}
+
+ + + +
+ + + +## Function `insert` + + + +
public fun insert(s: &mut string::String, at: u64, o: string::String)
+
+ + + +
+Implementation + + +
public fun insert(s: &mut String, at: u64, o: String) {
+    let bytes = &s.bytes;
+    assert!(at <= vector::length(bytes) && internal_is_char_boundary(bytes, at), EINVALID_INDEX);
+    let l = length(s);
+    let front = sub_string(s, 0, at);
+    let end = sub_string(s, at, l);
+    append(&mut front, o);
+    append(&mut front, end);
+    *s = front;
+}
+
+ + + +
+ + + +## Function `sub_string` + + + +
public fun sub_string(s: &string::String, i: u64, j: u64): string::String
+
+ + + +
+Implementation + + +
public fun sub_string(s: &String, i: u64, j: u64): String {
+    let bytes = &s.bytes;
+    let l = vector::length(bytes);
+    assert!(
+        j <= l && i <= j && internal_is_char_boundary(bytes, i) && internal_is_char_boundary(bytes, j),
+        EINVALID_INDEX
+    );
+    String{bytes: internal_sub_string(bytes, i, j)}
+}
+
+ + + +
+ + + +## Function `index_of` + + + +
public fun index_of(s: &string::String, r: &string::String): u64
+
+ + + +
+Implementation + + +
public fun index_of(s: &String, r: &String): u64 {
+    internal_index_of(&s.bytes, &r.bytes)
+}
+
+ + + +
+ + + +## Function `internal_check_utf8` + + + +
fun internal_check_utf8(v: &vector<u8>): bool
+
+ + + +
+Implementation + + +
native fun internal_check_utf8(v: &vector<u8>): bool;
+
+ + + +
+ + + +## Function `internal_is_char_boundary` + + + +
fun internal_is_char_boundary(v: &vector<u8>, i: u64): bool
+
+ + + +
+Implementation + + +
native fun internal_is_char_boundary(v: &vector<u8>, i: u64): bool;
+
+ + + +
+ + + +## Function `internal_sub_string` + + + +
fun internal_sub_string(v: &vector<u8>, i: u64, j: u64): vector<u8>
+
+ + + +
+Implementation + + +
native fun internal_sub_string(v: &vector<u8>, i: u64, j: u64): vector<u8>;
+
+ + + +
+ + + +## Function `internal_index_of` + + + +
fun internal_index_of(v: &vector<u8>, r: &vector<u8>): u64
+
+ + + +
+Implementation + + +
native fun internal_index_of(v: &vector<u8>, r: &vector<u8>): u64;
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/type_name.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/type_name.md new file mode 100644 index 00000000..48560570 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/type_name.md @@ -0,0 +1,341 @@ + + + +# Module `0x1::type_name` + + + +- [Struct `TypeName`](#0x1_type_name_TypeName) +- [Constants](#@Constants_0) +- [Function `get`](#0x1_type_name_get) +- [Function `get_with_original_ids`](#0x1_type_name_get_with_original_ids) +- [Function `is_primitive`](#0x1_type_name_is_primitive) +- [Function `borrow_string`](#0x1_type_name_borrow_string) +- [Function `get_address`](#0x1_type_name_get_address) +- [Function `get_module`](#0x1_type_name_get_module) +- [Function `into_string`](#0x1_type_name_into_string) + + +
use 0x1::address;
+use 0x1::ascii;
+
+ + + + + +## Struct `TypeName` + + + +
struct TypeName has copy, drop, store
+
+ + + +
+Fields + + +
+
+name: ascii::String +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ASCII_C: u8 = 99;
+
+ + + + + + + +
const ASCII_COLON: u8 = 58;
+
+ + + + + + + +
const ASCII_E: u8 = 101;
+
+ + + + + + + +
const ASCII_O: u8 = 111;
+
+ + + + + + + +
const ASCII_R: u8 = 114;
+
+ + + + + + + +
const ASCII_T: u8 = 116;
+
+ + + + + + + +
const ASCII_V: u8 = 118;
+
+ + + + + + + +
const ENonModuleType: u64 = 0;
+
+ + + + + +## Function `get` + + + +
public fun get<T>(): type_name::TypeName
+
+ + + +
+Implementation + + +
public native fun get<T>(): TypeName;
+
+ + + +
+ + + +## Function `get_with_original_ids` + + + +
public fun get_with_original_ids<T>(): type_name::TypeName
+
+ + + +
+Implementation + + +
public native fun get_with_original_ids<T>(): TypeName;
+
+ + + +
+ + + +## Function `is_primitive` + + + +
public fun is_primitive(self: &type_name::TypeName): bool
+
+ + + +
+Implementation + + +
public fun is_primitive(self: &TypeName): bool {
+    let bytes = ascii::as_bytes(&self.name);
+    bytes == &b"bool" ||
+    bytes == &b"u8" ||
+    bytes == &b"u16" ||
+    bytes == &b"u32" ||
+    bytes == &b"u64" ||
+    bytes == &b"u128" ||
+    bytes == &b"u256" ||
+    bytes == &b"address" ||
+    (vector::length(bytes) >= 6 &&
+    *vector::borrow(bytes, 0) == ASCII_V &&
+    *vector::borrow(bytes, 1) == ASCII_E &&
+    *vector::borrow(bytes, 2) == ASCII_C &&
+    *vector::borrow(bytes, 3) == ASCII_T &&
+    *vector::borrow(bytes, 4) == ASCII_O &&
+    *vector::borrow(bytes, 5) == ASCII_R)
+
+}
+
+ + + +
+ + + +## Function `borrow_string` + + + +
public fun borrow_string(self: &type_name::TypeName): &ascii::String
+
+ + + +
+Implementation + + +
public fun borrow_string(self: &TypeName): &String {
+    &self.name
+}
+
+ + + +
+ + + +## Function `get_address` + + + +
public fun get_address(self: &type_name::TypeName): ascii::String
+
+ + + +
+Implementation + + +
public fun get_address(self: &TypeName): String {
+    assert!(!is_primitive(self), ENonModuleType);
+
+    // Base16 (string) representation of an address has 2 symbols per byte.
+    let len = address::length() * 2;
+    let str_bytes = ascii::as_bytes(&self.name);
+    let addr_bytes = vector[];
+    let i = 0;
+
+    // Read `len` bytes from the type name and push them to addr_bytes.
+    while (i < len) {
+        vector::push_back(
+            &mut addr_bytes,
+            *vector::borrow(str_bytes, i)
+        );
+        i = i + 1;
+    };
+
+    ascii::string(addr_bytes)
+}
+
+ + + +
+ + + +## Function `get_module` + + + +
public fun get_module(self: &type_name::TypeName): ascii::String
+
+ + + +
+Implementation + + +
public fun get_module(self: &TypeName): String {
+    assert!(!is_primitive(self), ENonModuleType);
+
+    // Starts after address and a double colon: `<addr as HEX>::`
+    let i = address::length() * 2 + 2;
+    let str_bytes = ascii::as_bytes(&self.name);
+    let module_name = vector[];
+
+    loop {
+        let char = vector::borrow(str_bytes, i);
+        if (char != &ASCII_COLON) {
+            vector::push_back(&mut module_name, *char);
+            i = i + 1;
+        } else {
+            break
+        }
+    };
+
+    ascii::string(module_name)
+}
+
+ + + +
+ + + +## Function `into_string` + + + +
public fun into_string(self: type_name::TypeName): ascii::String
+
+ + + +
+Implementation + + +
public fun into_string(self: TypeName): String {
+    self.name
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/vector.md b/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/vector.md new file mode 100644 index 00000000..c7eb58dd --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/dependencies/move-stdlib/vector.md @@ -0,0 +1,478 @@ + + + +# Module `0x1::vector` + + + +- [Constants](#@Constants_0) +- [Function `empty`](#0x1_vector_empty) +- [Function `length`](#0x1_vector_length) +- [Function `borrow`](#0x1_vector_borrow) +- [Function `push_back`](#0x1_vector_push_back) +- [Function `borrow_mut`](#0x1_vector_borrow_mut) +- [Function `pop_back`](#0x1_vector_pop_back) +- [Function `destroy_empty`](#0x1_vector_destroy_empty) +- [Function `swap`](#0x1_vector_swap) +- [Function `singleton`](#0x1_vector_singleton) +- [Function `reverse`](#0x1_vector_reverse) +- [Function `append`](#0x1_vector_append) +- [Function `is_empty`](#0x1_vector_is_empty) +- [Function `contains`](#0x1_vector_contains) +- [Function `index_of`](#0x1_vector_index_of) +- [Function `remove`](#0x1_vector_remove) +- [Function `insert`](#0x1_vector_insert) +- [Function `swap_remove`](#0x1_vector_swap_remove) + + +
+ + + + + +## Constants + + + + + + +
const EINDEX_OUT_OF_BOUNDS: u64 = 131072;
+
+ + + + + +## Function `empty` + + + +
public fun empty<Element>(): vector<Element>
+
+ + + +
+Implementation + + +
native public fun empty<Element>(): vector<Element>;
+
+ + + +
+ + + +## Function `length` + + + +
public fun length<Element>(v: &vector<Element>): u64
+
+ + + +
+Implementation + + +
native public fun length<Element>(v: &vector<Element>): u64;
+
+ + + +
+ + + +## Function `borrow` + + + +
public fun borrow<Element>(v: &vector<Element>, i: u64): &Element
+
+ + + +
+Implementation + + +
native public fun borrow<Element>(v: &vector<Element>, i: u64): ∈
+
+ + + +
+ + + +## Function `push_back` + + + +
public fun push_back<Element>(v: &mut vector<Element>, e: Element)
+
+ + + +
+Implementation + + +
native public fun push_back<Element>(v: &mut vector<Element>, e: Element);
+
+ + + +
+ + + +## Function `borrow_mut` + + + +
public fun borrow_mut<Element>(v: &mut vector<Element>, i: u64): &mut Element
+
+ + + +
+Implementation + + +
native public fun borrow_mut<Element>(v: &mut vector<Element>, i: u64): &mut Element;
+
+ + + +
+ + + +## Function `pop_back` + + + +
public fun pop_back<Element>(v: &mut vector<Element>): Element
+
+ + + +
+Implementation + + +
native public fun pop_back<Element>(v: &mut vector<Element>): Element;
+
+ + + +
+ + + +## Function `destroy_empty` + + + +
public fun destroy_empty<Element>(v: vector<Element>)
+
+ + + +
+Implementation + + +
native public fun destroy_empty<Element>(v: vector<Element>);
+
+ + + +
+ + + +## Function `swap` + + + +
public fun swap<Element>(v: &mut vector<Element>, i: u64, j: u64)
+
+ + + +
+Implementation + + +
native public fun swap<Element>(v: &mut vector<Element>, i: u64, j: u64);
+
+ + + +
+ + + +## Function `singleton` + + + +
public fun singleton<Element>(e: Element): vector<Element>
+
+ + + +
+Implementation + + +
public fun singleton<Element>(e: Element): vector<Element> {
+    let v = empty();
+    push_back(&mut v, e);
+    v
+}
+
+ + + +
+ + + +## Function `reverse` + + + +
public fun reverse<Element>(v: &mut vector<Element>)
+
+ + + +
+Implementation + + +
public fun reverse<Element>(v: &mut vector<Element>) {
+    let len = length(v);
+    if (len == 0) return ();
+
+    let front_index = 0;
+    let back_index = len -1;
+    while (front_index < back_index) {
+        swap(v, front_index, back_index);
+        front_index = front_index + 1;
+        back_index = back_index - 1;
+    }
+}
+
+ + + +
+ + + +## Function `append` + + + +
public fun append<Element>(lhs: &mut vector<Element>, other: vector<Element>)
+
+ + + +
+Implementation + + +
public fun append<Element>(lhs: &mut vector<Element>, other: vector<Element>) {
+    reverse(&mut other);
+    while (!is_empty(&other)) push_back(lhs, pop_back(&mut other));
+    destroy_empty(other);
+}
+
+ + + +
+ + + +## Function `is_empty` + + + +
public fun is_empty<Element>(v: &vector<Element>): bool
+
+ + + +
+Implementation + + +
public fun is_empty<Element>(v: &vector<Element>): bool {
+    length(v) == 0
+}
+
+ + + +
+ + + +## Function `contains` + + + +
public fun contains<Element>(v: &vector<Element>, e: &Element): bool
+
+ + + +
+Implementation + + +
public fun contains<Element>(v: &vector<Element>, e: &Element): bool {
+    let i = 0;
+    let len = length(v);
+    while (i < len) {
+        if (borrow(v, i) == e) return true;
+        i = i + 1;
+    };
+    false
+}
+
+ + + +
+ + + +## Function `index_of` + + + +
public fun index_of<Element>(v: &vector<Element>, e: &Element): (bool, u64)
+
+ + + +
+Implementation + + +
public fun index_of<Element>(v: &vector<Element>, e: &Element): (bool, u64) {
+    let i = 0;
+    let len = length(v);
+    while (i < len) {
+        if (borrow(v, i) == e) return (true, i);
+        i = i + 1;
+    };
+    (false, 0)
+}
+
+ + + +
+ + + +## Function `remove` + + + +
public fun remove<Element>(v: &mut vector<Element>, i: u64): Element
+
+ + + +
+Implementation + + +
public fun remove<Element>(v: &mut vector<Element>, i: u64): Element {
+    let len = length(v);
+    // i out of bounds; abort
+    if (i >= len) abort EINDEX_OUT_OF_BOUNDS;
+
+    len = len - 1;
+    while (i < len) swap(v, i, { i = i + 1; i });
+    pop_back(v)
+}
+
+ + + +
+ + + +## Function `insert` + + + +
public fun insert<Element>(v: &mut vector<Element>, e: Element, i: u64)
+
+ + + +
+Implementation + + +
public fun insert<Element>(v: &mut vector<Element>, e: Element, i: u64) {
+    let len = length(v);
+    // i too big abort
+    if (i > len) abort EINDEX_OUT_OF_BOUNDS;
+
+    push_back(v, e);
+    while (i < len) {
+        swap(v, i, len);
+        i = i + 1
+    }
+}
+
+ + + +
+ + + +## Function `swap_remove` + + + +
public fun swap_remove<Element>(v: &mut vector<Element>, i: u64): Element
+
+ + + +
+Implementation + + +
public fun swap_remove<Element>(v: &mut vector<Element>, i: u64): Element {
+    assert!(!is_empty(v), EINDEX_OUT_OF_BOUNDS);
+    let last_idx = length(v) - 1;
+    swap(v, i, last_idx);
+    pop_back(v)
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/inscription.md b/crates/mgo-framework/docs/mgo-inscription/inscription.md new file mode 100644 index 00000000..8adad650 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/inscription.md @@ -0,0 +1,302 @@ + + + +# Module `0x4::inscription` + + + +- [Function `coinscription_new_tick`](#0x4_inscription_coinscription_new_tick) +- [Function `coinscription_mint`](#0x4_inscription_coinscription_mint) +- [Function `coinscription_transfer`](#0x4_inscription_coinscription_transfer) +- [Function `coinscription_split`](#0x4_inscription_coinscription_split) +- [Function `coinscription_merge`](#0x4_inscription_coinscription_merge) +- [Function `coinscription_burn`](#0x4_inscription_coinscription_burn) +- [Function `singlescription_new_copyright`](#0x4_inscription_singlescription_new_copyright) +- [Function `singlescription_mint`](#0x4_inscription_singlescription_mint) +- [Function `singlescription_transfer`](#0x4_inscription_singlescription_transfer) +- [Function `singlescription_burn`](#0x4_inscription_singlescription_burn) + + +
use 0x1::option;
+use 0x1::string;
+use 0x2::transfer;
+use 0x2::tx_context;
+use 0x4::coinscription;
+use 0x4::singlescription;
+
+ + + + + +## Function `coinscription_new_tick` + + + +
public entry fun coinscription_new_tick(tick_pool_record: &mut coinscription::TickPoolRecord, tick: string::String, total_supply: u64, burnable: bool, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun coinscription_new_tick(tick_pool_record: &mut TickPoolRecord,
+                                        tick: String,
+                                        total_supply: u64,
+                                        burnable: bool,
+                                        ctx: &mut TxContext) {
+    let tick_record = coinscription::new_tick(
+        tick_pool_record,
+        tick,
+        total_supply,
+        burnable,
+        ctx
+    );
+    public_share_object(tick_record)
+}
+
+ + + +
+ + + +## Function `coinscription_mint` + + + +
public entry fun coinscription_mint(tick_record: &mut coinscription::TickRecord, amount: u64, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun coinscription_mint(tick_record: &mut TickRecord,
+                                    amount: u64,
+                                    ctx: &mut TxContext) {
+    let coinscription = coinscription::do_mint(tick_record, amount, ctx);
+    public_transfer(coinscription, tx_context::sender(ctx))
+}
+
+ + + +
+ + + +## Function `coinscription_transfer` + + + +
public entry fun coinscription_transfer(scription: coinscription::CoinScription, receipt: address, _: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun coinscription_transfer(scription: CoinScription, receipt: address, _: &mut TxContext) {
+    public_transfer(scription, receipt)
+}
+
+ + + +
+ + + +## Function `coinscription_split` + + + +
public entry fun coinscription_split(scription: &mut coinscription::CoinScription, amount: u64, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun coinscription_split(scription: &mut CoinScription, amount: u64, ctx: &mut TxContext) {
+    let scription = coinscription::do_split(scription, amount, ctx);
+    public_transfer(scription, tx_context::sender(ctx));
+}
+
+ + + +
+ + + +## Function `coinscription_merge` + + + +
public entry fun coinscription_merge(scription1: &mut coinscription::CoinScription, scription2: coinscription::CoinScription, _: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun coinscription_merge(scription1: &mut CoinScription, scription2: CoinScription, _: &mut TxContext) {
+    coinscription::do_merge(scription1, scription2)
+}
+
+ + + +
+ + + +## Function `coinscription_burn` + + + +
public entry fun coinscription_burn(tick_record: &mut coinscription::TickRecord, inscription: coinscription::CoinScription, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun coinscription_burn(tick_record: &mut TickRecord,
+                                    inscription: CoinScription,
+                                    ctx: &mut TxContext) {
+    coinscription::do_burn(tick_record, inscription, ctx)
+}
+
+ + + +
+ + + +## Function `singlescription_new_copyright` + + + +
public entry fun singlescription_new_copyright(copyright_pool_record: &mut singlescription::CopyrightPoolRecord, copr: string::String, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun singlescription_new_copyright(copyright_pool_record: &mut CopyrightPoolRecord,
+                                               copr: String,
+                                               ctx: &mut TxContext) {
+    let sender = tx_context::sender(ctx);
+    let record = singlescription::new_copright(copyright_pool_record, copr, ctx);
+    public_transfer(record, sender);
+}
+
+ + + +
+ + + +## Function `singlescription_mint` + + + +
public entry fun singlescription_mint(record: &mut singlescription::SingleScriptionRecord, name: string::String, typ: string::String, sub_typ: string::String, content: string::String, link: string::String, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun singlescription_mint(record: &mut SingleScriptionRecord,
+                                      name: String,
+                                      typ: String,
+                                      sub_typ: String,
+                                      content: String,
+                                      link: String,
+                                      ctx: &mut TxContext) {
+    let link_opt = option::none<String>();
+    if (!string::is_empty(&link)) {
+        option::fill(&mut link_opt, link);
+    };
+    let scription = singlescription::do_mint(record, name, typ, sub_typ, content, link_opt, ctx);
+    public_transfer(scription, tx_context::sender(ctx));
+}
+
+ + + +
+ + + +## Function `singlescription_transfer` + + + +
public entry fun singlescription_transfer(scription: singlescription::SingleScription, receipt: address, _: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun singlescription_transfer(scription: SingleScription, receipt: address, _: &mut TxContext) {
+    public_transfer(scription, receipt);
+}
+
+ + + +
+ + + +## Function `singlescription_burn` + + + +
public entry fun singlescription_burn(record: &mut singlescription::SingleScriptionRecord, scription: singlescription::SingleScription, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun singlescription_burn(record: &mut SingleScriptionRecord,
+                                      scription: SingleScription,
+                                      ctx: &mut TxContext) {
+    singlescription::do_burn(record, scription, ctx);
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/singlescription.md b/crates/mgo-framework/docs/mgo-inscription/singlescription.md new file mode 100644 index 00000000..8f9820ce --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/singlescription.md @@ -0,0 +1,648 @@ + + + +# Module `0x4::singlescription` + + + +- [Resource `CopyrightPoolRecord`](#0x4_singlescription_CopyrightPoolRecord) +- [Resource `SingleScriptionRecord`](#0x4_singlescription_SingleScriptionRecord) +- [Resource `SingleScription`](#0x4_singlescription_SingleScription) +- [Struct `SINGLESCRIPTION`](#0x4_singlescription_SINGLESCRIPTION) +- [Struct `NewCopyright`](#0x4_singlescription_NewCopyright) +- [Struct `MintSingleScription`](#0x4_singlescription_MintSingleScription) +- [Struct `BurnSingleScription`](#0x4_singlescription_BurnSingleScription) +- [Constants](#@Constants_0) +- [Function `init`](#0x4_singlescription_init) +- [Function `init_display`](#0x4_singlescription_init_display) +- [Function `new_copright`](#0x4_singlescription_new_copright) +- [Function `find_copyright`](#0x4_singlescription_find_copyright) +- [Function `copyright_record_address_list`](#0x4_singlescription_copyright_record_address_list) +- [Function `do_mint`](#0x4_singlescription_do_mint) +- [Function `do_burn`](#0x4_singlescription_do_burn) + + +
use 0x1::option;
+use 0x1::string;
+use 0x2::display;
+use 0x2::event;
+use 0x2::object;
+use 0x2::package;
+use 0x2::table;
+use 0x2::transfer;
+use 0x2::tx_context;
+use 0x2::vec_set;
+use 0x4::string_util;
+use 0x4::svg;
+
+ + + + + +## Resource `CopyrightPoolRecord` + + + +
struct CopyrightPoolRecord has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+record: table::Table<string::String, address> +
+
+ The Copyright name -> SingleScriptionRecord object id +
+
+display: display::Display<singlescription::SingleScription> +
+
+ +
+
+ + +
+ + + +## Resource `SingleScriptionRecord` + + + +
struct SingleScriptionRecord has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+copyright: string::String +
+
+ +
+
+record: vec_set::VecSet<address> +
+
+ +
+
+ + +
+ + + +## Resource `SingleScription` + + + +
struct SingleScription has store, key
+
+ + + +
+Fields + + +
+
+id: object::UID +
+
+ +
+
+name: string::String +
+
+ +
+
+typ: string::String +
+
+ +
+
+sub_typ: string::String +
+
+ +
+
+copyright: string::String +
+
+ +
+
+content: string::String +
+
+ +
+
+link: option::Option<string::String> +
+
+ +
+
+ + +
+ + + +## Struct `SINGLESCRIPTION` + + + +
struct SINGLESCRIPTION has drop
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `NewCopyright` + + + +
struct NewCopyright has copy, drop
+
+ + + +
+Fields + + +
+
+id: object::ID +
+
+ +
+
+deployer: address +
+
+ +
+
+copyright: string::String +
+
+ +
+
+ + +
+ + + +## Struct `MintSingleScription` + + + +
struct MintSingleScription has copy, drop
+
+ + + +
+Fields + + +
+
+id: object::ID +
+
+ +
+
+sender: address +
+
+ +
+
+name: string::String +
+
+ +
+
+copyright: string::String +
+
+ +
+
+ + +
+ + + +## Struct `BurnSingleScription` + + + +
struct BurnSingleScription has copy, drop
+
+ + + +
+Fields + + +
+
+id: object::ID +
+
+ +
+
+sender: address +
+
+ +
+
+copyright: string::String +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ErrorDisplayInited: u64 = 3;
+
+ + + + + + + +
const ErrorCoprAlreadyExists: u64 = 1;
+
+ + + + + + + +
const ErrorInvalidCopyright: u64 = 2;
+
+ + + + + +## Function `init` + + + +
fun init(otw: singlescription::SINGLESCRIPTION, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
fun init(otw: SINGLESCRIPTION, ctx: &mut TxContext) {
+    let publisher = package::claim(otw, ctx);
+
+    let keys = vector[
+        std::string::utf8(b"name"),
+        std::string::utf8(b"image_url"),
+    ];
+
+    let p = b"mrc-721";
+    let na = b"{name}";
+    let typ = b"{typ}";
+    let copr = b"{copyright}";
+
+    let img_metadata = svg::generate_singlescription_svg(p, na, typ, copr);
+
+    let values = vector[
+        std::string::utf8(b"{name}"),
+        std::string::utf8(img_metadata),
+    ];
+
+
+    let display = display::new_with_fields<SingleScription>(
+        &publisher, keys, values, ctx
+    );
+
+    let copyright_pool_record = CopyrightPoolRecord {
+        id: object::new(ctx), record: table::new(ctx), display
+    };
+    transfer::share_object(copyright_pool_record);
+
+    package::burn_publisher(publisher);
+}
+
+ + + +
+ + + +## Function `init_display` + + + +
public entry fun init_display(copyright_pool_record: &mut singlescription::CopyrightPoolRecord, _ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public entry fun init_display(copyright_pool_record: &mut CopyrightPoolRecord, _ctx: &mut TxContext) {
+    assert!(display::version(©right_pool_record.display) == 0, ErrorDisplayInited);
+    display::update_version(&mut copyright_pool_record.display);
+}
+
+ + + +
+ + + +## Function `new_copright` + + + +
public fun new_copright(copyright_pool_record: &mut singlescription::CopyrightPoolRecord, copr: string::String, ctx: &mut tx_context::TxContext): singlescription::SingleScriptionRecord
+
+ + + +
+Implementation + + +
public fun new_copright(
+    copyright_pool_record: &mut CopyrightPoolRecord,
+    copr: String,
+    ctx: &mut TxContext
+): (SingleScriptionRecord) {
+    assert!(!string_util::is_empty_str(&copr), ErrorInvalidCopyright);
+    assert!(!table::contains(©right_pool_record.record, copr), ErrorCoprAlreadyExists);
+
+    let scription_record = SingleScriptionRecord {
+        id: object::new(ctx),
+        copyright: copr,
+        record: vec_set::empty(),
+    };
+    table::add(&mut copyright_pool_record.record, copr, uid_to_address(&scription_record.id));
+    emit(NewCopyright {
+        id: uid_to_inner(&scription_record.id),
+        deployer: tx_context::sender(ctx),
+        copyright: copr,
+    });
+    scription_record
+}
+
+ + + +
+ + + +## Function `find_copyright` + + + +
public fun find_copyright(copyright_pool_record: &mut singlescription::CopyrightPoolRecord, copr: string::String): option::Option<address>
+
+ + + +
+Implementation + + +
public fun find_copyright(
+    copyright_pool_record: &mut CopyrightPoolRecord,
+    copr: String
+): (Option<address>) {
+    let record_addr = option::none<address>();
+    if (table::contains(©right_pool_record.record, copr)) {
+        let addr = table::borrow(©right_pool_record.record, copr);
+        record_addr = option::some(*addr);
+    };
+    (record_addr)
+}
+
+ + + +
+ + + +## Function `copyright_record_address_list` + + + +
public fun copyright_record_address_list(copyright_pool_record: &mut singlescription::CopyrightPoolRecord, coprs: vector<string::String>): vector<address>
+
+ + + +
+Implementation + + +
public fun copyright_record_address_list(
+    copyright_pool_record: &mut CopyrightPoolRecord,
+    coprs: vector<String>
+): vector<address> {
+    let vec_addrs = vector::empty<address>();
+
+    let i = 0;
+    let end = vector::length(&coprs);
+    while (i < end) {
+        let key = vector::borrow(&coprs, i);
+        let value = table::borrow(©right_pool_record.record, *key);
+        vector::push_back(&mut vec_addrs, *value);
+        i = i + 1;
+    };
+
+    vec_addrs
+}
+
+ + + +
+ + + +## Function `do_mint` + + + +
public fun do_mint(record: &mut singlescription::SingleScriptionRecord, name: string::String, typ: string::String, sub_typ: string::String, content: string::String, link: option::Option<string::String>, ctx: &mut tx_context::TxContext): singlescription::SingleScription
+
+ + + +
+Implementation + + +
public fun do_mint(
+    record: &mut SingleScriptionRecord,
+    name: String,
+    typ: String,
+    sub_typ: String,
+    content: String,
+    link: Option<String>,
+    ctx: &mut TxContext
+): SingleScription {
+    let scription_uid = object::new(ctx);
+    let scription_id = object::uid_to_inner(&scription_uid);
+
+    let scription = SingleScription {
+        id: scription_uid,
+        name,
+        typ,
+        sub_typ,
+        content,
+        copyright: record.copyright,
+        link
+    };
+
+    let scription_address = object::id_address(&scription);
+    vec_set::insert(&mut record.record, scription_address);
+    emit(MintSingleScription {
+        id: scription_id,
+        sender: tx_context::sender(ctx),
+        name,
+        copyright: record.copyright
+    });
+    scription
+}
+
+ + + +
+ + + +## Function `do_burn` + + + +
public fun do_burn(record: &mut singlescription::SingleScriptionRecord, scription: singlescription::SingleScription, ctx: &mut tx_context::TxContext)
+
+ + + +
+Implementation + + +
public fun do_burn(
+    record: &mut SingleScriptionRecord,
+    scription: SingleScription,
+    ctx: &mut TxContext
+) {
+    assert!(record.copyright == scription.copyright, ErrorInvalidCopyright);
+
+    let address = object::id_address(&scription);
+    let SingleScription { id: uid, name: _, typ: _, sub_typ: _, copyright, content: _, link: _ } = scription;
+    let id = object::uid_to_inner(&uid);
+
+    vec_set::remove(&mut record.record, &address);
+    object::delete(uid);
+
+    emit({
+        BurnSingleScription {
+            id,
+            sender: tx_context::sender(ctx),
+            copyright,
+        }
+    });
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/string_util.md b/crates/mgo-framework/docs/mgo-inscription/string_util.md new file mode 100644 index 00000000..94043b09 --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/string_util.md @@ -0,0 +1,459 @@ + + + +# Module `0x4::string_util` + + + +- [Function `is_empty_str`](#0x4_string_util_is_empty_str) +- [Function `is_empty`](#0x4_string_util_is_empty) +- [Function `is_tick_valid`](#0x4_string_util_is_tick_valid) +- [Function `to_uppercase`](#0x4_string_util_to_uppercase) +- [Function `to_lowercase`](#0x4_string_util_to_lowercase) +- [Function `is_number`](#0x4_string_util_is_number) +- [Function `is_lowercase`](#0x4_string_util_is_lowercase) +- [Function `is_uppercase`](#0x4_string_util_is_uppercase) +- [Function `starts_with`](#0x4_string_util_starts_with) +- [Function `index_of`](#0x4_string_util_index_of) +- [Function `last_index_of`](#0x4_string_util_last_index_of) +- [Function `substring`](#0x4_string_util_substring) +- [Function `contains_any`](#0x4_string_util_contains_any) + + +
use 0x1::string;
+use 0x1::vector;
+
+ + + + + +## Function `is_empty_str` + + + +
public fun is_empty_str(input: &string::String): bool
+
+ + + +
+Implementation + + +
public fun is_empty_str(input: &String): bool {
+    is_empty(string::bytes(input))
+}
+
+ + + +
+ + + +## Function `is_empty` + + + +
public fun is_empty(input: &vector<u8>): bool
+
+ + + +
+Implementation + + +
public fun is_empty(input: &vector<u8>): bool {
+    vector::is_empty(input)
+}
+
+ + + +
+ + + +## Function `is_tick_valid` + + + +
public fun is_tick_valid(input: &string::String): bool
+
+ + + +
+Implementation + + +
public fun is_tick_valid(input: &String): bool {
+    let bytes = string::bytes(input);
+    let len = vector::length(bytes);
+    let i = 0;
+    let res = len > 0;
+    while (i < len) {
+        let b = *vector::borrow(bytes, i);
+        res = is_number(b) || is_uppercase(b);
+        if (!res) {
+            break
+        };
+        i = i + 1;
+    };
+    res
+}
+
+ + + +
+ + + +## Function `to_uppercase` + + + +
public fun to_uppercase(input: &mut vector<u8>)
+
+ + + +
+Implementation + + +
public fun to_uppercase(input: &mut vector<u8>) {
+    let length = vector::length(input);
+    let i = 0;
+    while (i < length) {
+        let letter = vector::borrow_mut(input, i);
+        if (is_lowercase(*letter)) {
+            *letter = *letter - 32;
+        };
+        i = i + 1;
+    }
+}
+
+ + + +
+ + + +## Function `to_lowercase` + + + +
public fun to_lowercase(input: &mut vector<u8>)
+
+ + + +
+Implementation + + +
public fun to_lowercase(input: &mut vector<u8>) {
+    let length = vector::length(input);
+    let i = 0;
+    while (i < length) {
+        let letter = vector::borrow_mut(input, i);
+        if (is_uppercase(*letter)) {
+            *letter = *letter + 32;
+        };
+        i = i + 1;
+    }
+}
+
+ + + +
+ + + +## Function `is_number` + + + +
public fun is_number(letter: u8): bool
+
+ + + +
+Implementation + + +
public fun is_number(letter: u8): bool {
+    letter >= 48 && letter <= 57
+}
+
+ + + +
+ + + +## Function `is_lowercase` + + + +
public fun is_lowercase(letter: u8): bool
+
+ + + +
+Implementation + + +
public fun is_lowercase(letter: u8): bool {
+    letter >= 97 && letter <= 122
+}
+
+ + + +
+ + + +## Function `is_uppercase` + + + +
public fun is_uppercase(letter: u8): bool
+
+ + + +
+Implementation + + +
public fun is_uppercase(letter: u8): bool {
+    letter >= 65 && letter <= 90
+}
+
+ + + +
+ + + +## Function `starts_with` + + + +
public fun starts_with(input: &vector<u8>, prefix: &vector<u8>): bool
+
+ + + +
+Implementation + + +
public fun starts_with(input: &vector<u8>, prefix: &vector<u8>): bool {
+    let input_length = vector::length(input);
+    let prefix_length = vector::length(prefix);
+    if (input_length < prefix_length) {
+        return false
+    };
+    let i = 0;
+    while (i < prefix_length) {
+        if (vector::borrow(input, i) != vector::borrow(prefix, i)) {
+            return false
+        };
+        i = i + 1;
+    };
+    true
+}
+
+ + + +
+ + + +## Function `index_of` + +Returns if the input contains the search string and the index of the first match + + +
public fun index_of(input: &vector<u8>, search: &vector<u8>): (bool, u64)
+
+ + + +
+Implementation + + +
public fun index_of(input: &vector<u8>, search: &vector<u8>): (bool, u64) {
+    let input_length = vector::length(input);
+    let search_length = vector::length(search);
+    if (input_length < search_length) {
+        return (false, 0)
+    };
+    let i = 0;
+    while (i < input_length) {
+        let j = 0;
+        while (j < search_length) {
+            let idx = i + j;
+            if (idx >= input_length) {
+                break
+            };
+            if (vector::borrow(input, idx) != vector::borrow(search, j)) {
+                break
+            };
+            j = j + 1;
+        };
+        if (j == search_length) {
+            return (true, i)
+        };
+        i = i + 1;
+    };
+    (false, 0)
+}
+
+ + + +
+ + + +## Function `last_index_of` + +Returns if the input contains the search string and the index of the last match + + +
public fun last_index_of(input: &vector<u8>, search: &vector<u8>): (bool, u64)
+
+ + + +
+Implementation + + +
public fun last_index_of(input: &vector<u8>, search: &vector<u8>): (bool, u64) {
+    let input_length = vector::length(input);
+    let search_length = vector::length(search);
+    if (input_length < search_length) {
+        return (false, 0)
+    };
+    let i = input_length - search_length;
+    while (i >= 0) {
+        let j = 0;
+        while (j < search_length) {
+            let idx = i + j;
+            if (idx >= input_length) {
+                break
+            };
+            if (vector::borrow(input, idx) != vector::borrow(search, j)) {
+                break
+            };
+            j = j + 1;
+        };
+        if (j == search_length) {
+            return (true, i)
+        };
+        if (i == 0) {
+            break
+        };
+        i = i - 1;
+    };
+    (false, 0)
+}
+
+ + + +
+ + + +## Function `substring` + + + +
public fun substring(input: &vector<u8>, start: u64, end: u64): vector<u8>
+
+ + + +
+Implementation + + +
public fun substring(input: &vector<u8>, start: u64, end: u64): vector<u8> {
+    let length = vector::length(input);
+    if (start >= length) {
+        return vector::empty()
+    };
+    let end = if (end > length) {
+        length
+    } else {
+        end
+    };
+    let result = vector::empty();
+    let i = start;
+    while (i < end) {
+        vector::push_back(&mut result, *vector::borrow(input, i));
+        i = i + 1;
+    };
+    result
+}
+
+ + + +
+ + + +## Function `contains_any` + +Returns if the input contains any of the chars + + +
public fun contains_any(input: &vector<u8>, chars: &vector<u8>): bool
+
+ + + +
+Implementation + + +
public fun contains_any(input: &vector<u8>, chars: &vector<u8>): bool {
+    let length = vector::length(input);
+    let chars_length = vector::length(chars);
+    let i = 0;
+    while (i < length) {
+        let j = 0;
+        while (j < chars_length) {
+            if (vector::borrow(input, i) == vector::borrow(chars, j)) {
+                return true
+            };
+            j = j + 1;
+        };
+        i = i + 1;
+    };
+    false
+}
+
+ + + +
diff --git a/crates/mgo-framework/docs/mgo-inscription/svg.md b/crates/mgo-framework/docs/mgo-inscription/svg.md new file mode 100644 index 00000000..8b32f93e --- /dev/null +++ b/crates/mgo-framework/docs/mgo-inscription/svg.md @@ -0,0 +1,189 @@ + + + +# Module `0x4::svg` + + + +- [Constants](#@Constants_0) +- [Function `generate_coinscription_svg`](#0x4_svg_generate_coinscription_svg) +- [Function `generate_singlescription_svg`](#0x4_svg_generate_singlescription_svg) + + +
use 0x1::vector;
+
+ + + + + +## Constants + + + + + + +
const SVG_PATH_COIN_1: vector<u8> = [100, 97, 116, 97, 58, 105, 109, 97, 103, 101, 47, 115, 118, 103, 43, 120, 109, 108, 44, 37, 51, 67, 115, 118, 103, 37, 50, 48, 119, 105, 100, 116, 104, 37, 51, 68, 37, 50, 50, 49, 50, 48, 37, 50, 50, 37, 50, 48, 104, 101, 105, 103, 104, 116, 37, 51, 68, 37, 50, 50, 49, 50, 48, 37, 50, 50, 37, 50, 48, 118, 105, 101, 119, 66, 111, 120, 37, 51, 68, 37, 50, 50, 48, 37, 50, 48, 48, 37, 50, 48, 49, 50, 48, 37, 50, 48, 49, 50, 48, 37, 50, 50, 37, 50, 48, 102, 105, 108, 108, 37, 51, 68, 37, 50, 50, 110, 111, 110, 101, 37, 50, 50, 37, 50, 48, 120, 109, 108, 110, 115, 37, 51, 68, 37, 50, 50, 104, 116, 116, 112, 37, 51, 65, 37, 50, 70, 37, 50, 70, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 37, 50, 70, 50, 48, 48, 48, 37, 50, 70, 115, 118, 103, 37, 50, 50, 37, 51, 69, 37, 51, 67, 114, 101, 99, 116, 37, 50, 48, 119, 105, 100, 116, 104, 37, 51, 68, 37, 50, 50, 49, 50, 48, 37, 50, 50, 37, 50, 48, 104, 101, 105, 103, 104, 116, 37, 51, 68, 37, 50, 50, 49, 50, 48, 37, 50, 50, 37, 50, 48, 102, 105, 108, 108, 37, 51, 68, 37, 50, 50, 37, 50, 51, 52, 54, 65, 68, 66, 51, 37, 50, 50, 37, 50, 70, 37, 51, 69, 37, 51, 67, 116, 101, 120, 116, 37, 50, 48, 102, 105, 108, 108, 37, 51, 68, 37, 50, 50, 37, 50, 51, 69, 65, 70, 55, 70, 70, 37, 50, 50, 37, 50, 48, 120, 109, 108, 37, 51, 65, 115, 112, 97, 99, 101, 37, 51, 68, 37, 50, 50, 112, 114, 101, 115, 101, 114, 118, 101, 37, 50, 50, 37, 50, 48, 115, 116, 121, 108, 101, 37, 51, 68, 37, 50, 50, 119, 104, 105, 116, 101, 45, 115, 112, 97, 99, 101, 37, 51, 65, 37, 50, 48, 112, 114, 101, 37, 50, 50, 37, 50, 48, 102, 111, 110, 116, 45, 102, 97, 109, 105, 108, 121, 37, 51, 68, 37, 50, 50, 73, 110, 116, 101, 114, 37, 50, 50, 37, 50, 48, 102, 111, 110, 116, 45, 115, 105, 122, 101, 37, 51, 68, 37, 50, 50, 49, 48, 37, 50, 50, 37, 50, 48, 108, 101, 116, 116, 101, 114, 45, 115, 112, 97, 99, 105, 110, 103, 37, 51, 68, 37, 50, 50, 48, 101, 109, 37, 50, 50, 37, 51, 69, 37, 51, 67, 116, 115, 112, 97, 110, 37, 50, 48, 120, 37, 51, 68, 37, 50, 50, 49, 53, 37, 50, 50, 37, 50, 48, 121, 37, 51, 68, 37, 50, 50, 50, 54, 46, 56, 54, 51, 54, 37, 50, 50, 37, 51, 69, 37, 55, 66, 37, 50, 54, 37, 50, 51, 49, 48, 37, 51, 66, 37, 51, 67, 37, 50, 70, 116, 115, 112, 97, 110, 37, 51, 69, 37, 51, 67, 116, 115, 112, 97, 110, 37, 50, 48, 120, 37, 51, 68, 37, 50, 50, 49, 53, 37, 50, 50, 37, 50, 48, 121, 37, 51, 68, 37, 50, 50, 52, 49, 46, 56, 54, 51, 54, 37, 50, 50, 37, 51, 69, 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48, 112, 37, 51, 65, 37, 50, 48, 37, 50, 54, 37, 50, 51, 51, 57, 37, 51, 66];
+
+ + + + + + + +
const SVG_PATH_COIN_2: vector<u8> = [37, 50, 54, 37, 50, 51, 51, 57, 37, 51, 66, 37, 50, 67, 37, 50, 54, 37, 50, 51, 49, 48, 37, 51, 66, 37, 51, 67, 37, 50, 70, 116, 115, 112, 97, 110, 37, 51, 69, 37, 51, 67, 116, 115, 112, 97, 110, 37, 50, 48, 120, 37, 51, 68, 37, 50, 50, 49, 53, 37, 50, 50, 37, 50, 48, 121, 37, 51, 68, 37, 50, 50, 53, 54, 46, 56, 54, 51, 54, 37, 50, 50, 37, 51, 69, 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48, 111, 112, 37, 51, 65, 37, 50, 48, 37, 50, 54, 37, 50, 51, 51, 57, 37, 51, 66];
+
+ + + + + + + +
const SVG_PATH_COIN_3: vector<u8> = [37, 50, 54, 37, 50, 51, 51, 57, 37, 51, 66, 37, 50, 67, 37, 50, 54, 37, 50, 51, 49, 48, 37, 51, 66, 37, 51, 67, 37, 50, 70, 116, 115, 112, 97, 110, 37, 51, 69, 37, 51, 67, 116, 115, 112, 97, 110, 37, 50, 48, 120, 37, 51, 68, 37, 50, 50, 49, 53, 37, 50, 50, 37, 50, 48, 121, 37, 51, 68, 37, 50, 50, 55, 49, 46, 56, 54, 51, 54, 37, 50, 50, 37, 51, 69, 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48, 116, 105, 99, 107, 37, 51, 65, 37, 50, 48, 37, 50, 54, 37, 50, 51, 51, 57, 37, 51, 66];
+
+ + + + + + + +
const SVG_PATH_COIN_4: vector<u8> = [37, 50, 54, 37, 50, 51, 51, 57, 37, 51, 66, 37, 50, 67, 37, 50, 54, 37, 50, 51, 49, 48, 37, 51, 66, 37, 51, 67, 37, 50, 70, 116, 115, 112, 97, 110, 37, 51, 69, 37, 51, 67, 116, 115, 112, 97, 110, 37, 50, 48, 120, 37, 51, 68, 37, 50, 50, 49, 53, 37, 50, 50, 37, 50, 48, 121, 37, 51, 68, 37, 50, 50, 56, 54, 46, 56, 54, 51, 54, 37, 50, 50, 37, 51, 69, 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48, 97, 109, 116, 37, 51, 65, 37, 50, 48];
+
+ + + + + + + +
const SVG_PATH_COIN_5: vector<u8> = [37, 50, 54, 37, 50, 51, 49, 48, 37, 51, 66, 37, 51, 67, 37, 50, 70, 116, 115, 112, 97, 110, 37, 51, 69, 37, 51, 67, 116, 115, 112, 97, 110, 37, 50, 48, 120, 37, 51, 68, 37, 50, 50, 49, 53, 37, 50, 50, 37, 50, 48, 121, 37, 51, 68, 37, 50, 50, 49, 48, 49, 46, 56, 54, 52, 37, 50, 50, 37, 51, 69, 37, 55, 68, 37, 51, 67, 37, 50, 70, 116, 115, 112, 97, 110, 37, 51, 69, 37, 51, 67, 37, 50, 70, 116, 101, 120, 116, 37, 51, 69, 37, 51, 67, 37, 50, 70, 115, 118, 103, 37, 51, 69];
+
+ + + + + + + +
const SVG_PATH_SINGLE_1: vector<u8> = [100, 97, 116, 97, 58, 105, 109, 97, 103, 101, 47, 115, 118, 103, 43, 120, 109, 108, 44, 37, 51, 67, 115, 118, 103, 37, 50, 48, 119, 105, 100, 116, 104, 37, 51, 68, 37, 50, 50, 49, 50, 48, 37, 50, 50, 37, 50, 48, 104, 101, 105, 103, 104, 116, 37, 51, 68, 37, 50, 50, 49, 50, 48, 37, 50, 50, 37, 50, 48, 118, 105, 101, 119, 66, 111, 120, 37, 51, 68, 37, 50, 50, 48, 37, 50, 48, 48, 37, 50, 48, 49, 50, 48, 37, 50, 48, 49, 50, 48, 37, 50, 50, 37, 50, 48, 102, 105, 108, 108, 37, 51, 68, 37, 50, 50, 110, 111, 110, 101, 37, 50, 50, 37, 50, 48, 120, 109, 108, 110, 115, 37, 51, 68, 37, 50, 50, 104, 116, 116, 112, 37, 51, 65, 37, 50, 70, 37, 50, 70, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 37, 50, 70, 50, 48, 48, 48, 37, 50, 70, 115, 118, 103, 37, 50, 50, 37, 51, 69, 37, 51, 67, 114, 101, 99, 116, 37, 50, 48, 119, 105, 100, 116, 104, 37, 51, 68, 37, 50, 50, 49, 50, 48, 37, 50, 50, 37, 50, 48, 104, 101, 105, 103, 104, 116, 37, 51, 68, 37, 50, 50, 49, 50, 48, 37, 50, 50, 37, 50, 48, 102, 105, 108, 108, 37, 51, 68, 37, 50, 50, 37, 50, 51, 52, 54, 65, 68, 66, 51, 37, 50, 50, 37, 50, 70, 37, 51, 69, 37, 51, 67, 116, 101, 120, 116, 37, 50, 48, 102, 105, 108, 108, 37, 51, 68, 37, 50, 50, 37, 50, 51, 69, 65, 70, 55, 70, 70, 37, 50, 50, 37, 50, 48, 120, 109, 108, 37, 51, 65, 115, 112, 97, 99, 101, 37, 51, 68, 37, 50, 50, 112, 114, 101, 115, 101, 114, 118, 101, 37, 50, 50, 37, 50, 48, 115, 116, 121, 108, 101, 37, 51, 68, 37, 50, 50, 119, 104, 105, 116, 101, 45, 115, 112, 97, 99, 101, 37, 51, 65, 37, 50, 48, 112, 114, 101, 37, 50, 50, 37, 50, 48, 102, 111, 110, 116, 45, 102, 97, 109, 105, 108, 121, 37, 51, 68, 37, 50, 50, 73, 110, 116, 101, 114, 37, 50, 50, 37, 50, 48, 102, 111, 110, 116, 45, 115, 105, 122, 101, 37, 51, 68, 37, 50, 50, 49, 48, 37, 50, 50, 37, 50, 48, 108, 101, 116, 116, 101, 114, 45, 115, 112, 97, 99, 105, 110, 103, 37, 51, 68, 37, 50, 50, 48, 101, 109, 37, 50, 50, 37, 51, 69, 37, 51, 67, 116, 115, 112, 97, 110, 37, 50, 48, 120, 37, 51, 68, 37, 50, 50, 49, 53, 37, 50, 50, 37, 50, 48, 121, 37, 51, 68, 37, 50, 50, 50, 54, 46, 56, 54, 51, 54, 37, 50, 50, 37, 51, 69, 37, 55, 66, 37, 50, 54, 37, 50, 51, 49, 48, 37, 51, 66, 37, 51, 67, 37, 50, 70, 116, 115, 112, 97, 110, 37, 51, 69, 37, 51, 67, 116, 115, 112, 97, 110, 37, 50, 48, 120, 37, 51, 68, 37, 50, 50, 49, 53, 37, 50, 50, 37, 50, 48, 121, 37, 51, 68, 37, 50, 50, 52, 49, 46, 56, 54, 51, 54, 37, 50, 50, 37, 51, 69, 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48, 112, 37, 51, 65, 37, 50, 48, 37, 50, 54, 37, 50, 51, 51, 57, 37, 51, 66];
+
+ + + + + + + +
const SVG_PATH_SINGLE_2: vector<u8> = [37, 50, 54, 37, 50, 51, 51, 57, 37, 51, 66, 37, 50, 67, 37, 50, 54, 37, 50, 51, 49, 48, 37, 51, 66, 37, 51, 67, 37, 50, 70, 116, 115, 112, 97, 110, 37, 51, 69, 37, 51, 67, 116, 115, 112, 97, 110, 37, 50, 48, 120, 37, 51, 68, 37, 50, 50, 49, 53, 37, 50, 50, 37, 50, 48, 121, 37, 51, 68, 37, 50, 50, 53, 54, 46, 56, 54, 51, 54, 37, 50, 50, 37, 51, 69, 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48, 110, 97, 37, 51, 65, 37, 50, 48, 37, 50, 54, 37, 50, 51, 51, 57, 37, 51, 66];
+
+ + + + + + + +
const SVG_PATH_SINGLE_3: vector<u8> = [37, 50, 54, 37, 50, 51, 51, 57, 37, 51, 66, 37, 50, 67, 37, 50, 54, 37, 50, 51, 49, 48, 37, 51, 66, 37, 51, 67, 37, 50, 70, 116, 115, 112, 97, 110, 37, 51, 69, 37, 51, 67, 116, 115, 112, 97, 110, 37, 50, 48, 120, 37, 51, 68, 37, 50, 50, 49, 53, 37, 50, 50, 37, 50, 48, 121, 37, 51, 68, 37, 50, 50, 55, 49, 46, 56, 54, 51, 54, 37, 50, 50, 37, 51, 69, 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48, 116, 121, 112, 37, 51, 65, 37, 50, 48, 37, 50, 54, 37, 50, 51, 51, 57, 37, 51, 66];
+
+ + + + + + + +
const SVG_PATH_SINGLE_4: vector<u8> = [37, 50, 54, 37, 50, 51, 51, 57, 37, 51, 66, 37, 50, 67, 37, 50, 54, 37, 50, 51, 49, 48, 37, 51, 66, 37, 51, 67, 37, 50, 70, 116, 115, 112, 97, 110, 37, 51, 69, 37, 51, 67, 116, 115, 112, 97, 110, 37, 50, 48, 120, 37, 51, 68, 37, 50, 50, 49, 53, 37, 50, 50, 37, 50, 48, 121, 37, 51, 68, 37, 50, 50, 56, 54, 46, 56, 54, 51, 54, 37, 50, 50, 37, 51, 69, 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48, 99, 111, 112, 114, 37, 51, 65, 37, 50, 48, 37, 50, 54, 37, 50, 51, 51, 57, 37, 51, 66, 37, 67, 50, 37, 65, 57];
+
+ + + + + + + +
const SVG_PATH_SINGLE_5: vector<u8> = [37, 50, 54, 37, 50, 51, 51, 57, 37, 51, 66, 37, 50, 54, 37, 50, 51, 49, 48, 37, 51, 66, 37, 51, 67, 37, 50, 70, 116, 115, 112, 97, 110, 37, 51, 69, 37, 51, 67, 116, 115, 112, 97, 110, 37, 50, 48, 120, 37, 51, 68, 37, 50, 50, 49, 53, 37, 50, 50, 37, 50, 48, 121, 37, 51, 68, 37, 50, 50, 49, 48, 49, 46, 56, 54, 52, 37, 50, 50, 37, 51, 69, 37, 55, 68, 37, 51, 67, 37, 50, 70, 116, 115, 112, 97, 110, 37, 51, 69, 37, 51, 67, 37, 50, 70, 116, 101, 120, 116, 37, 51, 69, 37, 51, 67, 37, 50, 70, 115, 118, 103, 37, 51, 69];
+
+ + + + + +## Function `generate_coinscription_svg` + + + +
public fun generate_coinscription_svg(p: vector<u8>, op: vector<u8>, tick: vector<u8>, amt: vector<u8>): vector<u8>
+
+ + + +
+Implementation + + +
public fun generate_coinscription_svg(
+    p: vector<u8>,
+    op: vector<u8>,
+    tick: vector<u8>,
+    amt: vector<u8>
+): vector<u8> {
+    let metadata = SVG_PATH_COIN_1;
+    vector::append(&mut metadata, p);
+    vector::append(&mut metadata, SVG_PATH_COIN_2);
+    vector::append(&mut metadata, op);
+    vector::append(&mut metadata, SVG_PATH_COIN_3);
+    vector::append(&mut metadata, tick);
+    vector::append(&mut metadata, SVG_PATH_COIN_4);
+    vector::append(&mut metadata, amt);
+    vector::append(&mut metadata, SVG_PATH_COIN_5);
+
+    metadata
+}
+
+ + + +
+ + + +## Function `generate_singlescription_svg` + + + +
public fun generate_singlescription_svg(p: vector<u8>, na: vector<u8>, typ: vector<u8>, copr: vector<u8>): vector<u8>
+
+ + + +
+Implementation + + +
public fun generate_singlescription_svg(
+    p: vector<u8>,
+    na: vector<u8>,
+    typ: vector<u8>,
+    copr: vector<u8>
+): vector<u8> {
+    let metadata = SVG_PATH_SINGLE_1;
+    vector::append(&mut metadata, p);
+    vector::append(&mut metadata, SVG_PATH_SINGLE_2);
+    vector::append(&mut metadata, na);
+    vector::append(&mut metadata, SVG_PATH_SINGLE_3);
+    vector::append(&mut metadata, typ);
+    vector::append(&mut metadata, SVG_PATH_SINGLE_4);
+    vector::append(&mut metadata, copr);
+    vector::append(&mut metadata, SVG_PATH_SINGLE_5);
+
+    metadata
+}
+
+ + + +
diff --git a/crates/mgo-framework/packages/mgo-inscription/Move.lock b/crates/mgo-framework/packages/mgo-inscription/Move.lock new file mode 100644 index 00000000..8a235f86 --- /dev/null +++ b/crates/mgo-framework/packages/mgo-inscription/Move.lock @@ -0,0 +1,28 @@ +# @generated by Move, please check-in and do not edit manually. + +[move] +version = 0 +manifest_digest = "F96CC14D775E9ACB8FF2D5282E890A94FBFF4F4B74C94C0AFEF25E451F9C8C70" +deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" + +dependencies = [ + { name = "Mgo" }, + { name = "MoveStdlib" }, +] + +[[move.package]] +name = "Mgo" +source = { local = "../mgo-framework" } + +dependencies = [ + { name = "MoveStdlib" }, +] + +[[move.package]] +name = "MoveStdlib" +source = { local = "../move-stdlib" } + +[move.toolchain-version] +compiler-version = "1.0.0" +edition = "legacy" +flavor = "mgo" diff --git a/crates/mgo-framework/packages/mgo-inscription/Move.toml b/crates/mgo-framework/packages/mgo-inscription/Move.toml new file mode 100644 index 00000000..d631f04c --- /dev/null +++ b/crates/mgo-framework/packages/mgo-inscription/Move.toml @@ -0,0 +1,11 @@ +[package] +name = "MgoInscription" +version = "0.0.1" +published-at = "0x4" + +[dependencies] +MoveStdlib = { local = "../move-stdlib" } +Mgo = { local = "../mgo-framework" } + +[addresses] +mgo_inscription = "0x4" diff --git a/crates/mgo-framework/packages/mgo-inscription/sources/coinscription.move b/crates/mgo-framework/packages/mgo-inscription/sources/coinscription.move new file mode 100644 index 00000000..1a04857b --- /dev/null +++ b/crates/mgo-framework/packages/mgo-inscription/sources/coinscription.move @@ -0,0 +1,298 @@ +module mgo_inscription::coinscription { + use std::option; + use std::option::Option; + use std::string::String; + use std::vector; + + use mgo::display; + use mgo::display::Display; + use mgo::event::emit; + use mgo::object::{Self, ID, id_to_address, UID}; + use mgo::package; + use mgo::table; + use mgo::table::Table; + use mgo::transfer; + use mgo::tx_context; + use mgo::tx_context::TxContext; + + use mgo_inscription::string_util; + use mgo_inscription::svg; + + // ======== Errors ========= + const ErrorTickAlreadyExists: u64 = 1; + const ErrorNotEnoughSupply: u64 = 2; + const ErrorNotEnoughToMint: u64 = 3; + const EInvalidAmount: u64 = 4; + const ErrorNotSameTick: u64 = 5; + const ErrorCannotBurn: u64 = 6; + const ErrorNotZero: u64 = 7; + const ErrorInvalidTick: u64 = 8; + const ErrorDisplayInited: u64 = 9; + + struct TickPoolRecord has key, store { + id: UID, + /// The Tick name -> TickRecord object id + record: Table, + display: Display + } + + struct TickRecord has key, store { + id: UID, + tick: String, + total_supply: u64, + burnable: bool, + remain: u64, + current_supply: u64, + } + + struct CoinScription has key, store { + id: UID, + amount: u64, + tick: String, + } + + struct COINSCRIPTION has drop {} + + // ======== Events ========= + struct NewTick has copy, drop { + id: ID, + deployer: address, + tick: String, + total_supply: u64, + burnable: bool, + } + + struct MintCoinScription has copy, drop { + id: ID, + sender: address, + tick: String, + amount: u64, + } + + struct BurnCoinScription has copy, drop { + sender: address, + tick: String, + amount: u64, + } + + + fun init(otw: COINSCRIPTION, ctx: &mut TxContext) { + let publisher = package::claim(otw, ctx); + + let keys = vector[ + std::string::utf8(b"tick"), + std::string::utf8(b"amount"), + std::string::utf8(b"image_url"), + ]; + + let p = b"mrc-20"; + let op = b"mint"; + let tick = b"{tick}"; + let amt = b"{amount}"; + + let img_metadata = svg::generate_coinscription_svg(p, op, tick, amt); + + let values = vector[ + std::string::utf8(b"{tick}"), + std::string::utf8(b"{amount}"), + std::string::utf8(img_metadata), + ]; + let display = display::new_with_fields( + &publisher, keys, values, ctx + ); + + let tick_pool_record = TickPoolRecord { + id: object::new(ctx), record: table::new( + ctx + ), display + }; + transfer::share_object(tick_pool_record); + + package::burn_publisher(publisher); + } + + public entry fun init_display(tick_pool_record: &mut TickPoolRecord, _ctx: &mut TxContext) { + assert!(display::version(&tick_pool_record.display) == 0, ErrorDisplayInited); + display::update_version(&mut tick_pool_record.display); + } + + public fun new_tick( + tick_pool_record: &mut TickPoolRecord, + tick: String, + total_supply: u64, + burnable: bool, + ctx: &mut TxContext + ): TickRecord { + assert!(string_util::is_tick_valid(&tick), ErrorInvalidTick); + assert!(!table::contains(&tick_pool_record.record, tick), ErrorTickAlreadyExists); + assert!(total_supply > 0, ErrorNotEnoughSupply); + + let tick_uid = object::new(ctx); + let tick_id = object::uid_to_inner(&tick_uid); + let tick_record: TickRecord = TickRecord { + id: tick_uid, + tick, + total_supply, + burnable, + remain: total_supply, + current_supply: 0, + }; + table::add(&mut tick_pool_record.record, tick, id_to_address(&tick_id)); + emit(NewTick { + id: tick_id, + deployer: tx_context::sender(ctx), + tick, + total_supply, + burnable + }); + tick_record + } + + public fun find_tick(tick_pool_record: &mut TickPoolRecord, tick: String): Option
{ + if (table::contains(&tick_pool_record.record, tick)) { + let id_tick = table::borrow(&tick_pool_record.record, tick); + option::some(*id_tick) + } else { + option::none() + } + } + + public fun tick_record_address_list( + tick_pool_record: &TickPoolRecord, + ticks: vector, + ): vector
{ + let vec_addrs = vector::empty
(); + + let i = 0; + let end = vector::length(&ticks); + while (i < end) { + let key = *vector::borrow(&ticks, i); + let value = table::borrow(&tick_pool_record.record, key); + vector::push_back(&mut vec_addrs, *value); + i = i + 1; + }; + + vec_addrs + } + + public fun do_mint( + tick_record: &mut TickRecord, + amount: u64, + ctx: &mut TxContext + ): CoinScription { + assert!(tick_record.remain > 0, ErrorNotEnoughToMint); + assert!(tick_record.remain >= amount, ErrorNotEnoughToMint); + + tick_record.remain = tick_record.remain - amount; + tick_record.current_supply = tick_record.current_supply + amount; + + let tick: String = tick_record.tick; + let sender = tx_context::sender(ctx); + let coinscription = CoinScription { + id: object::new(ctx), + amount, + tick, + }; + emit(MintCoinScription { + id: object::id(&coinscription), + sender, + tick, + amount, + }); + coinscription + } + + // ======= Merge functions ======== + + public fun is_mergeable(inscription1: &CoinScription, inscription2: &CoinScription): bool { + inscription1.tick == inscription2.tick + } + + public fun do_merge( + inscription1: &mut CoinScription, + inscription2: CoinScription, + ) { + assert!(inscription1.tick == inscription2.tick, ErrorNotSameTick); + let CoinScription { id, amount, tick: _ } = inscription2; + inscription1.amount = inscription1.amount + amount; + object::delete(id); + } + + + // ======= Split functions ======== + + /// Check if the inscription can be split + public fun is_splitable(inscription: &CoinScription): bool { + inscription.amount > 1 + } + + /// Split the inscription and return the new inscription + public fun do_split( + inscription: &mut CoinScription, + amount: u64, + ctx: &mut TxContext + ): CoinScription { + assert!(0 < amount && amount < inscription.amount, EInvalidAmount); + let original_amount = inscription.amount; + inscription.amount = original_amount - amount; + let split_movescription = CoinScription { + id: object::new(ctx), + amount, + tick: inscription.tick, + }; + split_movescription + } + + #[lint_allow(self_transfer)] + public entry fun split( + inscription: &mut CoinScription, + amount: u64, + ctx: &mut TxContext + ) { + let ins = do_split(inscription, amount, ctx); + transfer::public_transfer(ins, tx_context::sender(ctx)); + } + + + // ========= Destroy and Burn functions ========= + + public fun zero(tick_record: &TickRecord, ctx: &mut TxContext): CoinScription { + CoinScription { + id: object::new(ctx), + tick: tick_record.tick, + amount: 0 + } + } + + public fun is_zero(self: &CoinScription): bool { + self.amount == 0 + } + + public fun destroy_zero(self: CoinScription) { + assert!(self.amount == 0, ErrorNotZero); + let CoinScription { id, amount: _, tick: _ } = self; + object::delete(id); + } + + + public entry fun do_burn( + tick_record: &mut TickRecord, + inscription: CoinScription, + ctx: &mut TxContext + ) { + assert!(tick_record.tick == inscription.tick, ErrorNotSameTick); + assert!(tick_record.burnable, ErrorCannotBurn); + let sender = tx_context::sender(ctx); + let CoinScription { id: scription_uid, amount, tick } = inscription; + tick_record.current_supply = tick_record.current_supply - amount; + object::delete(scription_uid); + + emit({ + BurnCoinScription { + sender, + tick, + amount, + } + }); + } +} \ No newline at end of file diff --git a/crates/mgo-framework/packages/mgo-inscription/sources/inscription.move b/crates/mgo-framework/packages/mgo-inscription/sources/inscription.move new file mode 100644 index 00000000..dd2ab72e --- /dev/null +++ b/crates/mgo-framework/packages/mgo-inscription/sources/inscription.move @@ -0,0 +1,94 @@ +module mgo_inscription::inscription { + use std::option; + use std::string; + use std::string::String; + + use mgo::transfer::{public_share_object, public_transfer}; + use mgo::tx_context; + use mgo::tx_context::TxContext; + + use mgo_inscription::coinscription; + use mgo_inscription::coinscription::{CoinScription, TickPoolRecord, TickRecord}; + use mgo_inscription::singlescription; + use mgo_inscription::singlescription::{CopyrightPoolRecord, SingleScription, SingleScriptionRecord}; + + #[allow(lint(share_owned))] + public entry fun coinscription_new_tick(tick_pool_record: &mut TickPoolRecord, + tick: String, + total_supply: u64, + burnable: bool, + ctx: &mut TxContext) { + let tick_record = coinscription::new_tick( + tick_pool_record, + tick, + total_supply, + burnable, + ctx + ); + public_share_object(tick_record) + } + + + public entry fun coinscription_mint(tick_record: &mut TickRecord, + amount: u64, + ctx: &mut TxContext) { + let coinscription = coinscription::do_mint(tick_record, amount, ctx); + public_transfer(coinscription, tx_context::sender(ctx)) + } + + + public entry fun coinscription_transfer(scription: CoinScription, receipt: address, _: &mut TxContext) { + public_transfer(scription, receipt) + } + + public entry fun coinscription_split(scription: &mut CoinScription, amount: u64, ctx: &mut TxContext) { + let scription = coinscription::do_split(scription, amount, ctx); + public_transfer(scription, tx_context::sender(ctx)); + } + + public entry fun coinscription_merge(scription1: &mut CoinScription, scription2: CoinScription, _: &mut TxContext) { + coinscription::do_merge(scription1, scription2) + } + + public entry fun coinscription_burn(tick_record: &mut TickRecord, + inscription: CoinScription, + ctx: &mut TxContext) { + coinscription::do_burn(tick_record, inscription, ctx) + } + + + #[allow(lint(share_owned))] + public entry fun singlescription_new_copyright(copyright_pool_record: &mut CopyrightPoolRecord, + copr: String, + ctx: &mut TxContext) { + let sender = tx_context::sender(ctx); + let record = singlescription::new_copright(copyright_pool_record, copr, ctx); + public_transfer(record, sender); + } + + + public entry fun singlescription_mint(record: &mut SingleScriptionRecord, + name: String, + typ: String, + sub_typ: String, + content: String, + link: String, + ctx: &mut TxContext) { + let link_opt = option::none(); + if (!string::is_empty(&link)) { + option::fill(&mut link_opt, link); + }; + let scription = singlescription::do_mint(record, name, typ, sub_typ, content, link_opt, ctx); + public_transfer(scription, tx_context::sender(ctx)); + } + + public entry fun singlescription_transfer(scription: SingleScription, receipt: address, _: &mut TxContext) { + public_transfer(scription, receipt); + } + + public entry fun singlescription_burn(record: &mut SingleScriptionRecord, + scription: SingleScription, + ctx: &mut TxContext) { + singlescription::do_burn(record, scription, ctx); + } +} \ No newline at end of file diff --git a/crates/mgo-framework/packages/mgo-inscription/sources/singlescription.move b/crates/mgo-framework/packages/mgo-inscription/sources/singlescription.move new file mode 100644 index 00000000..532910c9 --- /dev/null +++ b/crates/mgo-framework/packages/mgo-inscription/sources/singlescription.move @@ -0,0 +1,222 @@ +module mgo_inscription::singlescription { + use std::option; + use std::option::Option; + use std::string::String; + use std::vector; + + use mgo::display; + use mgo::display::Display; + use mgo::event::emit; + use mgo::object::{Self, ID, UID, uid_to_address, uid_to_inner}; + use mgo::package; + use mgo::table; + use mgo::table::Table; + use mgo::transfer; + use mgo::tx_context; + use mgo::tx_context::TxContext; + use mgo::vec_set; + use mgo::vec_set::VecSet; + + use mgo_inscription::string_util; + use mgo_inscription::svg; + + // ======== Errors ========= + const ErrorCoprAlreadyExists: u64 = 1; + const ErrorInvalidCopyright: u64 = 2; + const ErrorDisplayInited: u64 = 3; + + struct CopyrightPoolRecord has key, store { + id: UID, + /// The Copyright name -> SingleScriptionRecord object id + record: Table, + display: Display + } + + struct SingleScriptionRecord has key, store { + id: UID, + copyright: String, + record: VecSet
, + } + + struct SingleScription has key, store { + id: UID, + name: String, + typ: String, + sub_typ: String, + copyright: String, + content: String, + link: Option, + } + + struct SINGLESCRIPTION has drop {} + + // ======== Events ========= + struct NewCopyright has copy, drop { + id: ID, + deployer: address, + copyright: String, + } + + struct MintSingleScription has copy, drop { + id: ID, + sender: address, + name: String, + copyright: String, + } + + struct BurnSingleScription has copy, drop { + id: ID, + sender: address, + copyright: String, + } + + + fun init(otw: SINGLESCRIPTION, ctx: &mut TxContext) { + let publisher = package::claim(otw, ctx); + + let keys = vector[ + std::string::utf8(b"name"), + std::string::utf8(b"image_url"), + ]; + + let p = b"mrc-721"; + let na = b"{name}"; + let typ = b"{typ}"; + let copr = b"{copyright}"; + + let img_metadata = svg::generate_singlescription_svg(p, na, typ, copr); + + let values = vector[ + std::string::utf8(b"{name}"), + std::string::utf8(img_metadata), + ]; + + + let display = display::new_with_fields( + &publisher, keys, values, ctx + ); + + let copyright_pool_record = CopyrightPoolRecord { + id: object::new(ctx), record: table::new(ctx), display + }; + transfer::share_object(copyright_pool_record); + + package::burn_publisher(publisher); + } + + public entry fun init_display(copyright_pool_record: &mut CopyrightPoolRecord, _ctx: &mut TxContext) { + assert!(display::version(©right_pool_record.display) == 0, ErrorDisplayInited); + display::update_version(&mut copyright_pool_record.display); + } + + + public fun new_copright( + copyright_pool_record: &mut CopyrightPoolRecord, + copr: String, + ctx: &mut TxContext + ): (SingleScriptionRecord) { + assert!(!string_util::is_empty_str(&copr), ErrorInvalidCopyright); + assert!(!table::contains(©right_pool_record.record, copr), ErrorCoprAlreadyExists); + + let scription_record = SingleScriptionRecord { + id: object::new(ctx), + copyright: copr, + record: vec_set::empty(), + }; + table::add(&mut copyright_pool_record.record, copr, uid_to_address(&scription_record.id)); + emit(NewCopyright { + id: uid_to_inner(&scription_record.id), + deployer: tx_context::sender(ctx), + copyright: copr, + }); + scription_record + } + + + public fun find_copyright( + copyright_pool_record: &mut CopyrightPoolRecord, + copr: String + ): (Option
) { + let record_addr = option::none
(); + if (table::contains(©right_pool_record.record, copr)) { + let addr = table::borrow(©right_pool_record.record, copr); + record_addr = option::some(*addr); + }; + (record_addr) + } + + public fun copyright_record_address_list( + copyright_pool_record: &mut CopyrightPoolRecord, + coprs: vector + ): vector
{ + let vec_addrs = vector::empty
(); + + let i = 0; + let end = vector::length(&coprs); + while (i < end) { + let key = vector::borrow(&coprs, i); + let value = table::borrow(©right_pool_record.record, *key); + vector::push_back(&mut vec_addrs, *value); + i = i + 1; + }; + + vec_addrs + } + + public fun do_mint( + record: &mut SingleScriptionRecord, + name: String, + typ: String, + sub_typ: String, + content: String, + link: Option, + ctx: &mut TxContext + ): SingleScription { + let scription_uid = object::new(ctx); + let scription_id = object::uid_to_inner(&scription_uid); + + let scription = SingleScription { + id: scription_uid, + name, + typ, + sub_typ, + content, + copyright: record.copyright, + link + }; + + let scription_address = object::id_address(&scription); + vec_set::insert(&mut record.record, scription_address); + emit(MintSingleScription { + id: scription_id, + sender: tx_context::sender(ctx), + name, + copyright: record.copyright + }); + scription + } + + + public fun do_burn( + record: &mut SingleScriptionRecord, + scription: SingleScription, + ctx: &mut TxContext + ) { + assert!(record.copyright == scription.copyright, ErrorInvalidCopyright); + + let address = object::id_address(&scription); + let SingleScription { id: uid, name: _, typ: _, sub_typ: _, copyright, content: _, link: _ } = scription; + let id = object::uid_to_inner(&uid); + + vec_set::remove(&mut record.record, &address); + object::delete(uid); + + emit({ + BurnSingleScription { + id, + sender: tx_context::sender(ctx), + copyright, + } + }); + } +} \ No newline at end of file diff --git a/crates/mgo-framework/packages/mgo-inscription/sources/string_util.move b/crates/mgo-framework/packages/mgo-inscription/sources/string_util.move new file mode 100644 index 00000000..b2648a56 --- /dev/null +++ b/crates/mgo-framework/packages/mgo-inscription/sources/string_util.move @@ -0,0 +1,177 @@ +module mgo_inscription::string_util { + use std::string; + use std::string::String; + use std::vector; + + public fun is_empty_str(input: &String): bool { + is_empty(string::bytes(input)) + } + + public fun is_empty(input: &vector): bool { + vector::is_empty(input) + } + + public fun is_tick_valid(input: &String): bool { + let bytes = string::bytes(input); + let len = vector::length(bytes); + let i = 0; + let res = len > 0; + while (i < len) { + let b = *vector::borrow(bytes, i); + res = is_number(b) || is_uppercase(b); + if (!res) { + break + }; + i = i + 1; + }; + res + } + + public fun to_uppercase(input: &mut vector) { + let length = vector::length(input); + let i = 0; + while (i < length) { + let letter = vector::borrow_mut(input, i); + if (is_lowercase(*letter)) { + *letter = *letter - 32; + }; + i = i + 1; + } + } + + public fun to_lowercase(input: &mut vector) { + let length = vector::length(input); + let i = 0; + while (i < length) { + let letter = vector::borrow_mut(input, i); + if (is_uppercase(*letter)) { + *letter = *letter + 32; + }; + i = i + 1; + } + } + + public fun is_number(letter: u8): bool { + letter >= 48 && letter <= 57 + } + + public fun is_lowercase(letter: u8): bool { + letter >= 97 && letter <= 122 + } + + public fun is_uppercase(letter: u8): bool { + letter >= 65 && letter <= 90 + } + + public fun starts_with(input: &vector, prefix: &vector): bool { + let input_length = vector::length(input); + let prefix_length = vector::length(prefix); + if (input_length < prefix_length) { + return false + }; + let i = 0; + while (i < prefix_length) { + if (vector::borrow(input, i) != vector::borrow(prefix, i)) { + return false + }; + i = i + 1; + }; + true + } + + /// Returns if the input contains the search string and the index of the first match + public fun index_of(input: &vector, search: &vector): (bool, u64) { + let input_length = vector::length(input); + let search_length = vector::length(search); + if (input_length < search_length) { + return (false, 0) + }; + let i = 0; + while (i < input_length) { + let j = 0; + while (j < search_length) { + let idx = i + j; + if (idx >= input_length) { + break + }; + if (vector::borrow(input, idx) != vector::borrow(search, j)) { + break + }; + j = j + 1; + }; + if (j == search_length) { + return (true, i) + }; + i = i + 1; + }; + (false, 0) + } + + /// Returns if the input contains the search string and the index of the last match + public fun last_index_of(input: &vector, search: &vector): (bool, u64) { + let input_length = vector::length(input); + let search_length = vector::length(search); + if (input_length < search_length) { + return (false, 0) + }; + let i = input_length - search_length; + while (i >= 0) { + let j = 0; + while (j < search_length) { + let idx = i + j; + if (idx >= input_length) { + break + }; + if (vector::borrow(input, idx) != vector::borrow(search, j)) { + break + }; + j = j + 1; + }; + if (j == search_length) { + return (true, i) + }; + if (i == 0) { + break + }; + i = i - 1; + }; + (false, 0) + } + + public fun substring(input: &vector, start: u64, end: u64): vector { + let length = vector::length(input); + if (start >= length) { + return vector::empty() + }; + let end = if (end > length) { + length + } else { + end + }; + let result = vector::empty(); + let i = start; + while (i < end) { + vector::push_back(&mut result, *vector::borrow(input, i)); + i = i + 1; + }; + result + } + + /// Returns if the input contains any of the chars + public fun contains_any(input: &vector, chars: &vector): bool { + let length = vector::length(input); + let chars_length = vector::length(chars); + let i = 0; + while (i < length) { + let j = 0; + while (j < chars_length) { + if (vector::borrow(input, i) == vector::borrow(chars, j)) { + return true + }; + j = j + 1; + }; + i = i + 1; + }; + false + } +} \ No newline at end of file diff --git a/crates/mgo-framework/packages/mgo-inscription/sources/svg.move b/crates/mgo-framework/packages/mgo-inscription/sources/svg.move new file mode 100644 index 00000000..71355121 --- /dev/null +++ b/crates/mgo-framework/packages/mgo-inscription/sources/svg.move @@ -0,0 +1,53 @@ +module mgo_inscription::svg { + use std::vector; + + const SVG_PATH_COIN_1: vector = b"data:image/svg+xml,%3Csvg%20width%3D%22120%22%20height%3D%22120%22%20viewBox%3D%220%200%20120%20120%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Crect%20width%3D%22120%22%20height%3D%22120%22%20fill%3D%22%2346ADB3%22%2F%3E%3Ctext%20fill%3D%22%23EAF7FF%22%20xml%3Aspace%3D%22preserve%22%20style%3D%22white-space%3A%20pre%22%20font-family%3D%22Inter%22%20font-size%3D%2210%22%20letter-spacing%3D%220em%22%3E%3Ctspan%20x%3D%2215%22%20y%3D%2226.8636%22%3E%7B%26%2310%3B%3C%2Ftspan%3E%3Ctspan%20x%3D%2215%22%20y%3D%2241.8636%22%3E%20%20%20%20p%3A%20%26%2339%3B"; + const SVG_PATH_COIN_2: vector = b"%26%2339%3B%2C%26%2310%3B%3C%2Ftspan%3E%3Ctspan%20x%3D%2215%22%20y%3D%2256.8636%22%3E%20%20%20%20op%3A%20%26%2339%3B"; + const SVG_PATH_COIN_3: vector = b"%26%2339%3B%2C%26%2310%3B%3C%2Ftspan%3E%3Ctspan%20x%3D%2215%22%20y%3D%2271.8636%22%3E%20%20%20%20tick%3A%20%26%2339%3B"; + const SVG_PATH_COIN_4: vector = b"%26%2339%3B%2C%26%2310%3B%3C%2Ftspan%3E%3Ctspan%20x%3D%2215%22%20y%3D%2286.8636%22%3E%20%20%20%20amt%3A%20"; + const SVG_PATH_COIN_5: vector = b"%26%2310%3B%3C%2Ftspan%3E%3Ctspan%20x%3D%2215%22%20y%3D%22101.864%22%3E%7D%3C%2Ftspan%3E%3C%2Ftext%3E%3C%2Fsvg%3E"; + + const SVG_PATH_SINGLE_1: vector = b"data:image/svg+xml,%3Csvg%20width%3D%22120%22%20height%3D%22120%22%20viewBox%3D%220%200%20120%20120%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Crect%20width%3D%22120%22%20height%3D%22120%22%20fill%3D%22%2346ADB3%22%2F%3E%3Ctext%20fill%3D%22%23EAF7FF%22%20xml%3Aspace%3D%22preserve%22%20style%3D%22white-space%3A%20pre%22%20font-family%3D%22Inter%22%20font-size%3D%2210%22%20letter-spacing%3D%220em%22%3E%3Ctspan%20x%3D%2215%22%20y%3D%2226.8636%22%3E%7B%26%2310%3B%3C%2Ftspan%3E%3Ctspan%20x%3D%2215%22%20y%3D%2241.8636%22%3E%20%20%20%20p%3A%20%26%2339%3B"; + const SVG_PATH_SINGLE_2: vector = b"%26%2339%3B%2C%26%2310%3B%3C%2Ftspan%3E%3Ctspan%20x%3D%2215%22%20y%3D%2256.8636%22%3E%20%20%20%20na%3A%20%26%2339%3B"; + const SVG_PATH_SINGLE_3: vector = b"%26%2339%3B%2C%26%2310%3B%3C%2Ftspan%3E%3Ctspan%20x%3D%2215%22%20y%3D%2271.8636%22%3E%20%20%20%20typ%3A%20%26%2339%3B"; + const SVG_PATH_SINGLE_4: vector = b"%26%2339%3B%2C%26%2310%3B%3C%2Ftspan%3E%3Ctspan%20x%3D%2215%22%20y%3D%2286.8636%22%3E%20%20%20%20copr%3A%20%26%2339%3B%C2%A9"; + const SVG_PATH_SINGLE_5: vector = b"%26%2339%3B%26%2310%3B%3C%2Ftspan%3E%3Ctspan%20x%3D%2215%22%20y%3D%22101.864%22%3E%7D%3C%2Ftspan%3E%3C%2Ftext%3E%3C%2Fsvg%3E"; + + public fun generate_coinscription_svg( + p: vector, + op: vector, + tick: vector, + amt: vector + ): vector { + let metadata = SVG_PATH_COIN_1; + vector::append(&mut metadata, p); + vector::append(&mut metadata, SVG_PATH_COIN_2); + vector::append(&mut metadata, op); + vector::append(&mut metadata, SVG_PATH_COIN_3); + vector::append(&mut metadata, tick); + vector::append(&mut metadata, SVG_PATH_COIN_4); + vector::append(&mut metadata, amt); + vector::append(&mut metadata, SVG_PATH_COIN_5); + + metadata + } + + public fun generate_singlescription_svg( + p: vector, + na: vector, + typ: vector, + copr: vector + ): vector { + let metadata = SVG_PATH_SINGLE_1; + vector::append(&mut metadata, p); + vector::append(&mut metadata, SVG_PATH_SINGLE_2); + vector::append(&mut metadata, na); + vector::append(&mut metadata, SVG_PATH_SINGLE_3); + vector::append(&mut metadata, typ); + vector::append(&mut metadata, SVG_PATH_SINGLE_4); + vector::append(&mut metadata, copr); + vector::append(&mut metadata, SVG_PATH_SINGLE_5); + + metadata + } +} \ No newline at end of file diff --git a/crates/mgo-framework/src/lib.rs b/crates/mgo-framework/src/lib.rs index 4baa5855..de639b8a 100644 --- a/crates/mgo-framework/src/lib.rs +++ b/crates/mgo-framework/src/lib.rs @@ -10,13 +10,7 @@ use serde::{Deserialize, Serialize}; use std::fmt::Formatter; use mgo_types::base_types::ObjectRef; use mgo_types::storage::ObjectStore; -use mgo_types::{ - base_types::ObjectID, - digests::TransactionDigest, - move_package::MovePackage, - object::{Object, OBJECT_START_VERSION}, - MOVE_STDLIB_PACKAGE_ID, MGO_FRAMEWORK_PACKAGE_ID, MGO_SYSTEM_PACKAGE_ID, -}; +use mgo_types::{base_types::ObjectID, digests::TransactionDigest, move_package::MovePackage, object::{Object, OBJECT_START_VERSION}, MOVE_STDLIB_PACKAGE_ID, MGO_FRAMEWORK_PACKAGE_ID, MGO_SYSTEM_PACKAGE_ID, MGO_INSCRIPTION_PACKAGE_ID}; use tracing::error; /// Represents a system package in the framework, that's built from the source code inside @@ -116,6 +110,11 @@ impl BuiltInFramework { MGO_SYSTEM_PACKAGE_ID, "mgo-system", [MOVE_STDLIB_PACKAGE_ID, MGO_FRAMEWORK_PACKAGE_ID] + ), + ( + MGO_INSCRIPTION_PACKAGE_ID, + "mgo-inscription", + [MOVE_STDLIB_PACKAGE_ID, MGO_FRAMEWORK_PACKAGE_ID] ) ]) .iter() diff --git a/crates/mgo-graphql-rpc/tests/e2e_tests.rs b/crates/mgo-graphql-rpc/tests/e2e_tests.rs index b0dcfcd2..9617143b 100644 --- a/crates/mgo-graphql-rpc/tests/e2e_tests.rs +++ b/crates/mgo-graphql-rpc/tests/e2e_tests.rs @@ -16,6 +16,7 @@ mod tests { use mgo_graphql_rpc::config::ConnectionConfig; use mgo_graphql_rpc::test_infra::cluster::DEFAULT_INTERNAL_DATA_SOURCE_PORT; use mgo_types::digests::ChainIdentifier; + use mgo_types::MGO_INSCRIPTION_ADDRESS; use mgo_types::MGO_FRAMEWORK_ADDRESS; use tokio::time::sleep; @@ -84,7 +85,7 @@ mod tests { Arc::new(sim), None, ) - .await; + .await; let query = r#" { @@ -116,7 +117,7 @@ mod tests { Arc::new(sim), None, ) - .await; + .await; let query = r#" { @@ -158,15 +159,21 @@ mod tests { Arc::new(sim), None, ) - .await; + .await; - let query = r#"{obj1: object(address: $framework_addr) {address}}"#; + let query = r#"{obj1: object(address: $framework_addr) {address} + obj2: object(address: $inscription_addr) {address}}"#; let variables = vec![ GraphqlQueryVariable { name: "framework_addr".to_string(), ty: "MgoAddress!".to_string(), value: json!("0x2"), }, + GraphqlQueryVariable { + name: "inscription_addr".to_string(), + ty: "MgoAddress!".to_string(), + value: json!("0x4"), + }, ]; let res = cluster .graphql_client @@ -186,6 +193,15 @@ mod tests { .unwrap(), MGO_FRAMEWORK_ADDRESS.to_canonical_string(true) ); + assert_eq!( + data.get("obj2") + .unwrap() + .get("address") + .unwrap() + .as_str() + .unwrap(), + MGO_INSCRIPTION_ADDRESS.to_canonical_string(true) + ); let bad_variables = vec![ GraphqlQueryVariable { @@ -193,6 +209,16 @@ mod tests { ty: "MgoAddress!".to_string(), value: json!("0x2"), }, + GraphqlQueryVariable { + name: "inscription_addr".to_string(), + ty: "MgoAddress!".to_string(), + value: json!("0x4"), + }, + GraphqlQueryVariable { + name: "inscription_addr".to_string(), + ty: "MgoAddress!".to_string(), + value: json!("0x46666666"), + }, ]; let res = cluster .graphql_client @@ -207,6 +233,16 @@ mod tests { ty: "MgoAddress!".to_string(), value: json!("0x2"), }, + GraphqlQueryVariable { + name: "inscription_addr".to_string(), + ty: "MgoAddress!".to_string(), + value: json!("0x4"), + }, + GraphqlQueryVariable { + name: "inscription_addr".to_string(), + ty: "MgoAddressP!".to_string(), + value: json!("0x4"), + }, ]; let res = cluster .graphql_client @@ -221,6 +257,26 @@ mod tests { ty: "MgoAddress!".to_string(), value: json!("0x2"), }, + GraphqlQueryVariable { + name: " inscription_addr".to_string(), + ty: "MgoAddress!".to_string(), + value: json!("0x4"), + }, + GraphqlQueryVariable { + name: "4inscription_addr".to_string(), + ty: "MgoAddressP!".to_string(), + value: json!("0x4"), + }, + GraphqlQueryVariable { + name: "".to_string(), + ty: "MgoAddress!".to_string(), + value: json!("0x4"), + }, + GraphqlQueryVariable { + name: " ".to_string(), + ty: "MgoAddress!".to_string(), + value: json!("0x4"), + }, ]; for var in bad_variables { @@ -233,8 +289,8 @@ mod tests { assert!( res.unwrap_err().to_string() == ClientError::InvalidVariableName { - var_name: var.name.clone() - } + var_name: var.name.clone() + } .to_string() ); } diff --git a/crates/mgo-keys/src/key_derive.rs b/crates/mgo-keys/src/key_derive.rs index 78ecb78c..9e2ea03d 100644 --- a/crates/mgo-keys/src/key_derive.rs +++ b/crates/mgo-keys/src/key_derive.rs @@ -19,14 +19,14 @@ use mgo_types::{ error::MgoError, }; -pub const DERIVATION_PATH_COIN_TYPE: u32 = 784; +pub const DERIVATION_PATH_COIN_TYPE: u32 = 938; pub const DERVIATION_PATH_PURPOSE_ED25519: u32 = 44; pub const DERVIATION_PATH_PURPOSE_SECP256K1: u32 = 54; pub const DERVIATION_PATH_PURPOSE_SECP256R1: u32 = 74; -/// Ed25519 follows SLIP-0010 using hardened path: m/44'/784'/0'/0'/{index}' -/// Secp256k1 follows BIP-32/44 using path where the first 3 levels are hardened: m/54'/784'/0'/0/{index} -/// Secp256r1 follows BIP-32/44 using path where the first 3 levels are hardened: m/74'/784'/0'/0/{index} +/// Ed25519 follows SLIP-0010 using hardened path: m/44'/938'/0'/0'/{index}' +/// Secp256k1 follows BIP-32/44 using path where the first 3 levels are hardened: m/54'/938'/0'/0/{index} +/// Secp256r1 follows BIP-32/44 using path where the first 3 levels are hardened: m/74'/938'/0'/0/{index} /// Note that the purpose node is used to distinguish signature schemes. pub fn derive_key_pair_from_path( seed: &[u8], @@ -77,7 +77,7 @@ pub fn validate_path( SignatureScheme::ED25519 => { match path { Some(p) => { - // The derivation path must be hardened at all levels with purpose = 44, coin_type = 784 + // The derivation path must be hardened at all levels with purpose = 44, coin_type = 938 if let &[purpose, coin_type, account, change, address] = p.as_ref() { if Some(purpose) == ChildNumber::new(DERVIATION_PATH_PURPOSE_ED25519, true).ok() @@ -105,7 +105,7 @@ pub fn validate_path( SignatureScheme::Secp256k1 => { match path { Some(p) => { - // The derivation path must be hardened at first 3 levels with purpose = 54, coin_type = 784 + // The derivation path must be hardened at first 3 levels with purpose = 54, coin_type = 938 if let &[purpose, coin_type, account, change, address] = p.as_ref() { if Some(purpose) == ChildNumber::new(DERVIATION_PATH_PURPOSE_SECP256K1, true).ok() @@ -133,7 +133,7 @@ pub fn validate_path( SignatureScheme::Secp256r1 => { match path { Some(p) => { - // The derivation path must be hardened at first 3 levels with purpose = 74, coin_type = 784 + // The derivation path must be hardened at first 3 levels with purpose = 74, coin_type = 938 if let &[purpose, coin_type, account, change, address] = p.as_ref() { if Some(purpose) == ChildNumber::new(DERVIATION_PATH_PURPOSE_SECP256R1, true).ok() diff --git a/crates/mgo-move-build/src/lib.rs b/crates/mgo-move-build/src/lib.rs index 9a4b32a5..e5ec90dc 100644 --- a/crates/mgo-move-build/src/lib.rs +++ b/crates/mgo-move-build/src/lib.rs @@ -48,7 +48,7 @@ use mgo_types::{ error::{MgoError, MgoResult}, is_system_package, move_package::{FnInfo, FnInfoKey, FnInfoMap, MovePackage}, - MOVE_STDLIB_ADDRESS, MGO_FRAMEWORK_ADDRESS, MGO_SYSTEM_ADDRESS, + MOVE_STDLIB_ADDRESS, MGO_FRAMEWORK_ADDRESS, MGO_SYSTEM_ADDRESS, MGO_INSCRIPTION_ADDRESS }; use mgo_verifier::{default_verifier_config, verifier as mgo_bytecode_verifier}; @@ -403,6 +403,12 @@ impl CompiledPackage { .collect() } + /// Get bytecode modules from the Mgo inscription that are used by this package + pub fn get_mgo_inscription_modules(&self) -> impl Iterator { + self.get_modules_and_deps() + .filter(|m| *m.self_id().address() == MGO_INSCRIPTION_ADDRESS) + } + /// Get bytecode modules from the Mgo System that are used by this package pub fn get_mgo_system_modules(&self) -> impl Iterator { self.get_modules_and_deps() diff --git a/crates/mgo-protocol-config/src/lib.rs b/crates/mgo-protocol-config/src/lib.rs index 05ab3674..aa1049d7 100644 --- a/crates/mgo-protocol-config/src/lib.rs +++ b/crates/mgo-protocol-config/src/lib.rs @@ -12,7 +12,7 @@ use tracing::{info, warn}; /// The minimum and maximum protocol versions supported by this build. const MIN_PROTOCOL_VERSION: u64 = 1; -const MAX_PROTOCOL_VERSION: u64 = 2; +const MAX_PROTOCOL_VERSION: u64 = 3; // Record history of protocol version allocations here: // @@ -1171,18 +1171,18 @@ impl ProtocolConfig { // All flags are disabled in V1 feature_flags: Default::default(), - max_tx_size_bytes: Some(512 * 1024), + max_tx_size_bytes: Some(128 * 1024), // We need this number to be at least 100x less than `max_serialized_tx_effects_size_bytes`otherwise effects can be huge - max_input_objects: Some(4096), + max_input_objects: Some(2048), max_serialized_tx_effects_size_bytes: Some(512 * 1024), max_serialized_tx_effects_size_bytes_system_tx: Some(512 * 1024 * 16), max_gas_payment_objects: Some(256), max_modules_in_publish: Some(128), - max_arguments: Some(2048), + max_arguments: Some(512), max_type_arguments: Some(16), max_type_argument_depth: Some(16), max_pure_argument_size: Some(16 * 1024), - max_programmable_tx_commands: Some(4096), + max_programmable_tx_commands: Some(1024), move_binary_format_version: Some(6), max_move_object_size: Some(250 * 1024), max_move_package_size: Some(100 * 1024), @@ -1648,6 +1648,9 @@ impl ProtocolConfig { cfg.consensus_max_transaction_size_bytes = Some(256 * 1024); // 256KB cfg.consensus_max_transactions_in_block_bytes = Some(6 * 1_024 * 1024); + } + 3 => { + } _ => panic!("unsupported version {:?}", version), } diff --git a/crates/mgo-replay/src/replay.rs b/crates/mgo-replay/src/replay.rs index 3a41b3b5..802ae1b3 100644 --- a/crates/mgo-replay/src/replay.rs +++ b/crates/mgo-replay/src/replay.rs @@ -64,6 +64,7 @@ use mgo_types::{ ObjectReadResultKind, SenderSignedData, Transaction, TransactionData, TransactionDataAPI, TransactionKind, VerifiedCertificate, VerifiedTransaction, }, + MGO_INSCRIPTION_PACKAGE_ID }; use tracing::{error, info, trace, warn}; @@ -1017,8 +1018,11 @@ impl LocalExec { } } - fn system_package_ids(_protocol_version: u64) -> Vec { - let ids = BuiltInFramework::all_package_ids(); + fn system_package_ids(protocol_version: u64) -> Vec { + let mut ids = BuiltInFramework::all_package_ids(); + if protocol_version < 3 { + ids.retain(|id| *id != MGO_INSCRIPTION_PACKAGE_ID) + } ids } diff --git a/crates/mgo-source-validation-service/config.toml b/crates/mgo-source-validation-service/config.toml index 74063750..081135d1 100644 --- a/crates/mgo-source-validation-service/config.toml +++ b/crates/mgo-source-validation-service/config.toml @@ -8,6 +8,7 @@ packages = [ { path = "crates/mgo-framework/packages/move-stdlib", watch = "0x1" }, { path = "crates/mgo-framework/packages/mgo-framework", watch = "0x2" }, { path = "crates/mgo-framework/packages/mgo-system", watch = "0x3" }, + { path = "crates/mgo-framework/packages/mgo-inscription", watch = "0x4"}, ] [[packages]] @@ -20,6 +21,7 @@ packages = [ { path = "crates/mgo-framework/packages/move-stdlib", watch = "0x1" }, { path = "crates/mgo-framework/packages/mgo-framework", watch = "0x2" }, { path = "crates/mgo-framework/packages/mgo-system", watch = "0x3" }, + { path = "crates/mgo-framework/packages/mgo-inscription", watch = "0x4"}, ] [[packages]] @@ -32,6 +34,7 @@ packages = [ { path = "crates/mgo-framework/packages/move-stdlib", watch = "0x1" }, { path = "crates/mgo-framework/packages/mgo-framework", watch = "0x2" }, { path = "crates/mgo-framework/packages/mgo-system", watch = "0x3" }, + { path = "crates/mgo-framework/packages/mgo-inscription", watch = "0x4"}, ] [[packages]] diff --git a/crates/mgo-transactional-test-runner/src/test_adapter.rs b/crates/mgo-transactional-test-runner/src/test_adapter.rs index db7e204d..d4f9490c 100644 --- a/crates/mgo-transactional-test-runner/src/test_adapter.rs +++ b/crates/mgo-transactional-test-runner/src/test_adapter.rs @@ -71,6 +71,7 @@ use mgo_types::storage::ObjectStore; use mgo_types::storage::ReadStore; use mgo_types::transaction::Command; use mgo_types::transaction::ProgrammableTransaction; +use mgo_types::MGO_INSCRIPTION_PACKAGE_ID; use mgo_types::MOVE_STDLIB_PACKAGE_ID; use mgo_types::MGO_SYSTEM_ADDRESS; use mgo_types::{ @@ -91,7 +92,7 @@ use mgo_types::{ programmable_transaction_builder::ProgrammableTransactionBuilder, MGO_FRAMEWORK_PACKAGE_ID, }; use mgo_types::{utils::to_sender_signed_transaction, MGO_SYSTEM_PACKAGE_ID}; -use mgo_types::{MGO_DENY_LIST_OBJECT_ID}; +use mgo_types::{MGO_INSCRIPTION_ADDRESS, MGO_DENY_LIST_OBJECT_ID}; use tempfile::NamedTempFile; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] @@ -106,6 +107,7 @@ const WELL_KNOWN_OBJECTS: &[ObjectID] = &[ MOVE_STDLIB_PACKAGE_ID, MGO_FRAMEWORK_PACKAGE_ID, MGO_SYSTEM_PACKAGE_ID, + MGO_INSCRIPTION_PACKAGE_ID, MGO_SYSTEM_STATE_OBJECT_ID, MGO_CLOCK_OBJECT_ID, MGO_DENY_LIST_OBJECT_ID, @@ -1744,6 +1746,13 @@ static NAMED_ADDRESSES: Lazy> = Lazy::new(|| move_compiler::shared::NumberFormat::Hex, ), ); + map.insert( + "mgo_inscription".to_string(), + NumericalAddress::new( + MGO_INSCRIPTION_ADDRESS.into_bytes(), + move_compiler::shared::NumberFormat::Hex, + ), + ); map }); @@ -1765,10 +1774,15 @@ pub static PRE_COMPILED: Lazy = Lazy::new(|| { buf.extend(["packages", "move-stdlib", "sources"]); buf.to_string_lossy().to_string() }; + let mgo_inscription_deps = { + let mut buf = mgo_files.to_path_buf(); + buf.extend(["packages", "mgo-inscription", "sources"]); + buf.to_string_lossy().to_string() + }; let fully_compiled_res = move_compiler::construct_pre_compiled_lib( vec![PackagePaths { name: None, - paths: vec![mgo_system_sources, mgo_sources, mgo_deps], + paths: vec![mgo_system_sources, mgo_sources, mgo_deps, mgo_inscription_deps], named_address_map: NAMED_ADDRESSES.clone(), }], None, diff --git a/crates/mgo-types/src/crypto.rs b/crates/mgo-types/src/crypto.rs index edef80ce..80070a51 100644 --- a/crates/mgo-types/src/crypto.rs +++ b/crates/mgo-types/src/crypto.rs @@ -49,7 +49,7 @@ use crate::mgo_serde::{Readable, MgoBitmap}; pub use enum_dispatch::enum_dispatch; use fastcrypto::encoding::{Base64, Bech32, Encoding, Hex}; use fastcrypto::error::FastCryptoError; -use fastcrypto::hash::{Blake2b256, HashFunction}; +use fastcrypto::hash::{HashFunction, Keccak256}; pub use fastcrypto::traits::Signer; use std::fmt::Debug; use tracing::{instrument, warn}; @@ -80,7 +80,7 @@ pub type NetworkKeyPair = Ed25519KeyPair; pub type NetworkPublicKey = Ed25519PublicKey; pub type NetworkPrivateKey = Ed25519PrivateKey; -pub type DefaultHash = Blake2b256; +pub type DefaultHash = Keccak256; pub const DEFAULT_EPOCH_ID: EpochId = 0; pub const MGO_PRIV_KEY_PREFIX: &str = "mgoprivkey"; diff --git a/crates/mgo-types/src/lib.rs b/crates/mgo-types/src/lib.rs index fbe7006a..99af48b0 100644 --- a/crates/mgo-types/src/lib.rs +++ b/crates/mgo-types/src/lib.rs @@ -98,6 +98,11 @@ pub const MGO_FRAMEWORK_PACKAGE_ID: ObjectID = ObjectID::from_address(MGO_FRAMEW pub const MGO_SYSTEM_ADDRESS: AccountAddress = address_from_single_byte(3); pub const MGO_SYSTEM_PACKAGE_ID: ObjectID = ObjectID::from_address(MGO_SYSTEM_ADDRESS); +/// 0x4-- account address where mgo inscription modules are stored +/// Same as the ObjectID +pub const MGO_INSCRIPTION_ADDRESS: AccountAddress = address_from_single_byte(4); +pub const MGO_INSCRIPTION_PACKAGE_ID: ObjectID = ObjectID::from_address(MGO_INSCRIPTION_ADDRESS); + /// 0x5: hardcoded object ID for the singleton mgo system state object. pub const MGO_SYSTEM_STATE_ADDRESS: AccountAddress = address_from_single_byte(5); pub const MGO_SYSTEM_STATE_OBJECT_ID: ObjectID = ObjectID::from_address(MGO_SYSTEM_STATE_ADDRESS); @@ -128,7 +133,7 @@ pub const MGO_DENY_LIST_OBJECT_ID: ObjectID = ObjectID::from_address(MGO_DENY_LI pub fn is_system_package(addr: impl Into) -> bool { matches!( addr.into(), - MOVE_STDLIB_ADDRESS | MGO_FRAMEWORK_ADDRESS | MGO_SYSTEM_ADDRESS + MOVE_STDLIB_ADDRESS | MGO_FRAMEWORK_ADDRESS | MGO_SYSTEM_ADDRESS | MGO_INSCRIPTION_ADDRESS ) } @@ -153,7 +158,7 @@ pub fn mgo_framework_address_concat_string(suffix: &str) -> String { /// Parses `s` as an address. Valid formats for addresses are: /// /// - A 256bit number, encoded in decimal, or hexadecimal with a leading "0x" prefix. -/// - One of a number of pre-defined named addresses: std, mgo, mgo_system. +/// - One of a number of pre-defined named addresses: std, mgo, mgo_system, mgo_inscription. /// /// Parsing succeeds if and only if `s` matches one of these formats exactly, with no remaining /// suffix. This function is intended for use within the authority codebases. @@ -201,6 +206,7 @@ pub fn parse_mgo_type_tag(s: &str) -> anyhow::Result { /// Resolve well-known named addresses into numeric addresses. fn resolve_address(addr: &str) -> Option { match addr { + "mgo_inscription" => Some(MGO_INSCRIPTION_ADDRESS), "std" => Some(MOVE_STDLIB_ADDRESS), "mgo" => Some(MGO_FRAMEWORK_ADDRESS), "mgo_system" => Some(MGO_SYSTEM_ADDRESS), diff --git a/crates/mgo-types/src/mgo_serde.rs b/crates/mgo-types/src/mgo_serde.rs index 34421687..6fa47653 100644 --- a/crates/mgo-types/src/mgo_serde.rs +++ b/crates/mgo-types/src/mgo_serde.rs @@ -24,7 +24,7 @@ use mgo_protocol_config::ProtocolVersion; use crate::{ parse_mgo_struct_tag, parse_mgo_type_tag, MGO_CLOCK_ADDRESS, - MGO_FRAMEWORK_ADDRESS, MGO_SYSTEM_ADDRESS, MGO_SYSTEM_STATE_ADDRESS, + MGO_FRAMEWORK_ADDRESS, MGO_SYSTEM_ADDRESS, MGO_INSCRIPTION_ADDRESS, MGO_SYSTEM_STATE_ADDRESS, }; #[inline] @@ -165,11 +165,12 @@ impl SerializeAs for MgoStructTag { } } -const MGO_ADDRESSES: [AccountAddress; 6] = [ +const MGO_ADDRESSES: [AccountAddress; 7] = [ AccountAddress::ZERO, AccountAddress::ONE, MGO_FRAMEWORK_ADDRESS, MGO_SYSTEM_ADDRESS, + MGO_INSCRIPTION_ADDRESS, MGO_SYSTEM_STATE_ADDRESS, MGO_CLOCK_ADDRESS, ]; diff --git a/crates/mgo/src/client_commands.rs b/crates/mgo/src/client_commands.rs index c52ab29e..02e2e472 100644 --- a/crates/mgo/src/client_commands.rs +++ b/crates/mgo/src/client_commands.rs @@ -271,8 +271,8 @@ pub enum MgoClientCommands { }, /// Generate new address and keypair with keypair scheme flag {ed25519 | secp256k1 | secp256r1} - /// with optional derivation path, default to m/44'/784'/0'/0'/0' for ed25519 or - /// m/54'/784'/0'/0/0 for secp256k1 or m/74'/784'/0'/0/0 for secp256r1. Word length can be + /// with optional derivation path, default to m/44'/938'/0'/0'/0' for ed25519 or + /// m/54'/938'/0'/0/0 for secp256k1 or m/74'/938'/0'/0/0 for secp256r1. Word length can be /// { word12 | word15 | word18 | word21 | word24} default to word12 if not specified. #[clap(name = "new-address")] NewAddress { diff --git a/crates/mgo/src/keytool.rs b/crates/mgo/src/keytool.rs index c8c33a7e..f943276e 100644 --- a/crates/mgo/src/keytool.rs +++ b/crates/mgo/src/keytool.rs @@ -88,8 +88,8 @@ pub enum KeyToolCommand { tx_bytes: Option, }, /// Generate a new keypair with key scheme flag {ed25519 | secp256k1 | secp256r1} - /// with optional derivation path, default to m/44'/784'/0'/0'/0' for ed25519 or - /// m/54'/784'/0'/0/0 for secp256k1 or m/74'/784'/0'/0/0 for secp256r1. Word + /// with optional derivation path, default to m/44'/938'/0'/0'/0' for ed25519 or + /// m/54'/938'/0'/0/0 for secp256k1 or m/74'/938'/0'/0/0 for secp256r1. Word /// length can be { word12 | word15 | word18 | word21 | word24} default to word12 /// if not specified. /// @@ -105,8 +105,8 @@ pub enum KeyToolCommand { /// Add a new key to Mgo CLI Keystore using either the input mnemonic phrase or a Bech32 encoded 33-byte /// `flag || privkey` starting with "mgoprivkey", the key scheme flag {ed25519 | secp256k1 | secp256r1} - /// and an optional derivation path, default to m/44'/784'/0'/0'/0' for ed25519 or m/54'/784'/0'/0/0 - /// for secp256k1 or m/74'/784'/0'/0/0 for secp256r1. Supports mnemonic phrase of word length 12, 15, + /// and an optional derivation path, default to m/44'/938'/0'/0'/0' for ed25519 or m/54'/938'/0'/0/0 + /// for secp256k1 or m/74'/938'/0'/0/0 for secp256r1. Supports mnemonic phrase of word length 12, 15, /// 18, 21, 24. Set an alias for the key with the --alias flag. If no alias is provided, the tool will /// automatically generate one. Import { @@ -371,6 +371,7 @@ pub struct ConvertOutput { base64_with_flag: String, // Mgo Keystore storage format hex_without_flag: String, // Legacy Mgo Wallet format scheme: String, + address: String, } #[derive(Serialize)] @@ -564,14 +565,6 @@ impl KeyToolCommand { key_scheme, derivation_path, } => { - if Hex::decode(&input_string).is_ok() { - return Err(anyhow!( - "Mgo Keystore and Mgo Wallet no longer support importing - private key as Hex, if you are sure your private key is encoded in Hex, use - `mgo keytool convert $HEX` to convert first then import the Bech32 encoded - private key starting with `mgoprivkey`." - )); - } match MgoKeyPair::decode(&input_string) { Ok(skp) => { @@ -1233,11 +1226,14 @@ fn convert_private_key_to_bech32(value: String) -> Result Result<(), anyhow::Error> { + + // let hex_prv_key = "b4ed9f3ad71d251ccd9ab288b3f559a64130584d3d62af335730c4e4bf0d7477"; + // let decoded = Hex::decode(&hex_prv_key).unwrap(); + // let mgo_key = MgoKeyPair::Ed25519(Ed25519KeyPair::from_bytes(&decoded)?); + // let key = Key::from(&mgo_key); + // println!("address:{}", key.mgo_address.to_string()); + + let mnemonic = "spice receive prosper hurdle turn two awake fee frown desert rent decide"; + println!("mnemonic:{}", mnemonic); + + let mut keystore = Keystore::from(InMemKeystore::new_insecure_for_tests(0)); + let mgo_address = keystore.import_from_mnemonic( + mnemonic, + SignatureScheme::ED25519, + Some(DerivationPath::from_str("m/44'/938'/0'/0'/0'").unwrap()), + )?; + let mgo_kp = keystore.get_key(&mgo_address).unwrap(); + + let mgo_prefix_key = mgo_kp.encode().unwrap(); + println!("mgo_prefix_key:{}", mgo_prefix_key.to_string()); + let hex_prefix_key = Hex::encode(&mgo_kp.to_bytes()[1..]); + println!("hex_prefix_key:0x{}", hex_prefix_key); + println!("address:{}", mgo_address.to_string()); + Ok(()) +} + #[test] async fn test_addresses_command() -> Result<(), anyhow::Error> { // Add 3 Ed25519 KeyPairs as default @@ -403,7 +432,7 @@ async fn test_invalid_derivation_path() -> Result<(), anyhow::Error> { alias: None, input_string: TEST_MNEMONIC.to_string(), key_scheme: SignatureScheme::ED25519, - derivation_path: Some("m/0'/784'/0'/0/0".parse().unwrap()), + derivation_path: Some("m/0'/938'/0'/0/0".parse().unwrap()), } .execute(&mut keystore) .await @@ -413,7 +442,7 @@ async fn test_invalid_derivation_path() -> Result<(), anyhow::Error> { alias: None, input_string: TEST_MNEMONIC.to_string(), key_scheme: SignatureScheme::ED25519, - derivation_path: Some("m/54'/784'/0'/0/0".parse().unwrap()), + derivation_path: Some("m/54'/938'/0'/0/0".parse().unwrap()), } .execute(&mut keystore) .await @@ -423,7 +452,7 @@ async fn test_invalid_derivation_path() -> Result<(), anyhow::Error> { alias: None, input_string: TEST_MNEMONIC.to_string(), key_scheme: SignatureScheme::Secp256k1, - derivation_path: Some("m/54'/784'/0'/0'/0'".parse().unwrap()), + derivation_path: Some("m/54'/938'/0'/0'/0'".parse().unwrap()), } .execute(&mut keystore) .await @@ -433,7 +462,7 @@ async fn test_invalid_derivation_path() -> Result<(), anyhow::Error> { alias: None, input_string: TEST_MNEMONIC.to_string(), key_scheme: SignatureScheme::Secp256k1, - derivation_path: Some("m/44'/784'/0'/0/0".parse().unwrap()), + derivation_path: Some("m/44'/938'/0'/0/0".parse().unwrap()), } .execute(&mut keystore) .await @@ -449,7 +478,7 @@ async fn test_valid_derivation_path() -> Result<(), anyhow::Error> { alias: None, input_string: TEST_MNEMONIC.to_string(), key_scheme: SignatureScheme::ED25519, - derivation_path: Some("m/44'/784'/0'/0'/0'".parse().unwrap()), + derivation_path: Some("m/44'/938'/0'/0'/0'".parse().unwrap()), } .execute(&mut keystore) .await @@ -459,7 +488,7 @@ async fn test_valid_derivation_path() -> Result<(), anyhow::Error> { alias: None, input_string: TEST_MNEMONIC.to_string(), key_scheme: SignatureScheme::ED25519, - derivation_path: Some("m/44'/784'/0'/0'/1'".parse().unwrap()), + derivation_path: Some("m/44'/938'/0'/0'/1'".parse().unwrap()), } .execute(&mut keystore) .await @@ -469,7 +498,7 @@ async fn test_valid_derivation_path() -> Result<(), anyhow::Error> { alias: None, input_string: TEST_MNEMONIC.to_string(), key_scheme: SignatureScheme::ED25519, - derivation_path: Some("m/44'/784'/1'/0'/1'".parse().unwrap()), + derivation_path: Some("m/44'/938'/1'/0'/1'".parse().unwrap()), } .execute(&mut keystore) .await @@ -479,7 +508,7 @@ async fn test_valid_derivation_path() -> Result<(), anyhow::Error> { alias: None, input_string: TEST_MNEMONIC.to_string(), key_scheme: SignatureScheme::Secp256k1, - derivation_path: Some("m/54'/784'/0'/0/1".parse().unwrap()), + derivation_path: Some("m/54'/938'/0'/0/1".parse().unwrap()), } .execute(&mut keystore) .await @@ -489,7 +518,7 @@ async fn test_valid_derivation_path() -> Result<(), anyhow::Error> { alias: None, input_string: TEST_MNEMONIC.to_string(), key_scheme: SignatureScheme::Secp256k1, - derivation_path: Some("m/54'/784'/1'/0/1".parse().unwrap()), + derivation_path: Some("m/54'/938'/1'/0/1".parse().unwrap()), } .execute(&mut keystore) .await diff --git a/narwhal/crypto/src/lib.rs b/narwhal/crypto/src/lib.rs index 218704e5..70f1f03e 100644 --- a/narwhal/crypto/src/lib.rs +++ b/narwhal/crypto/src/lib.rs @@ -11,7 +11,7 @@ use fastcrypto::{ bls12381, ed25519, error::FastCryptoError, - hash::{Blake2b256, HashFunction}, + hash::{Keccak256, HashFunction}, traits::{AggregateAuthenticator, Signer, VerifyingKey}, }; @@ -52,7 +52,7 @@ pub type RandomnessPrivateKey = //////////////////////////////////////////////////////////////////////// // Type alias selecting the default hash function for the code base. -pub type DefaultHashFunction = Blake2b256; +pub type DefaultHashFunction = Keccak256; pub const DIGEST_LENGTH: usize = DefaultHashFunction::OUTPUT_SIZE; pub const INTENT_MESSAGE_LENGTH: usize = INTENT_PREFIX_LENGTH + DIGEST_LENGTH; diff --git a/parameters b/parameters new file mode 100644 index 00000000..589ae775 --- /dev/null +++ b/parameters @@ -0,0 +1,9 @@ +--- +chain_start_timestamp_ms: 1718352444596 +protocol_version: 3 +allow_insertion_of_extra_objects: true +epoch_duration_ms: 86400000 +stake_subsidy_start_epoch: 0 +stake_subsidy_initial_distribution_amount: 1000000000000000 +stake_subsidy_period_length: 10 +stake_subsidy_decrease_rate: 1000