From 247d445dc1678686fbb4ac9c739aa733f204b94e Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Sun, 15 Oct 2023 02:01:38 +0800 Subject: [PATCH 01/17] init --- .../sources/nft/collection.move | 207 ++++++++++++++++++ .../rooch-framework/sources/nft/display.move | 0 crates/rooch-framework/sources/nft/nft.move | 0 3 files changed, 207 insertions(+) create mode 100644 crates/rooch-framework/sources/nft/collection.move create mode 100644 crates/rooch-framework/sources/nft/display.move create mode 100644 crates/rooch-framework/sources/nft/nft.move diff --git a/crates/rooch-framework/sources/nft/collection.move b/crates/rooch-framework/sources/nft/collection.move new file mode 100644 index 0000000000..54153a36c3 --- /dev/null +++ b/crates/rooch-framework/sources/nft/collection.move @@ -0,0 +1,207 @@ +// Copyright (c) RoochNetwork +// SPDX-License-Identifier: Apache-2.0 + +module rooch_framework::collection{ + use std::option::Option; + use std::string::String; + use moveos_std::object::ObjectID; + use moveos_std::object_ref; + use moveos_std::event; + use moveos_std::context; + use moveos_std::context::Context; + use moveos_std::object; + use moveos_std::object_ref::ObjectRef; + use moveos_std::type_table; + + const EMutatorNotExist: u64 = 100; + const ECollectionNotExist: u64 = 101; + + struct Collection has store{ + name: String, + uri: String, + creator: address, + description: String, + supply: Supply, + extend: type_table::TypeTable + } + + struct Supply has store{ + current: u64, + maximum: Option, + } + + struct MutatorRef has store{ + collection: ObjectID, + } + + // event + struct CreateCollectionEvent{ + objectID: ObjectID, + name: String, + uri: String, + creator: address, + maximum: Option, + description: String, + } + + + public fun create_collection( + name: String, + uri: String, + creator: address, + description: String, + max_supply: Option, + ctx: &mut Context + ):ObjectRef { + + let collection = Collection { + name, + uri, + creator, + description, + supply: Supply { + current: 0, + maximum: max_supply, + }, + extend: type_table::new(ctx) + }; + + let object_ref = context::new_object_with_owner( + ctx, + creator, + collection + ); + event::emit( + ctx, + CreateCollectionEvent { + objectID: object_ref::id(&object_ref), + name, + uri, + creator, + maximum: max_supply, + description, + } + ); + object_ref + } + + public fun generate_mutator_ref(collection: ObjectRef, ctx: &mut Context):ObjectRef{ + let mutator_ref = context::new_object_with_owner( + ctx, + object_ref::owner(&collection), + MutatorRef { + collection: object_ref::id(&collection), + } + ); + mutator_ref + } + + // assert + public fun assert_collection_exist_of_ref(collectionRef: &ObjectRef){ + assert!( object_ref::exist_object(collectionRef), ECollectionNotExist); + } + + public fun assert_collection_exist_of_id(collectionID: ObjectID, ctx: & Context){ + assert!( context::exist_object(ctx, collectionID), ECollectionNotExist); + context::borrow_object(ctx,collectionID); + } + + public fun assert_mutator_exist_of_ref(mutatorRef: &ObjectRef){ + assert!( object_ref::exist_object(mutatorRef), EMutatorNotExist); + } + + public fun assert_mutator_exist_of_id(mutatorID: ObjectID, ctx: & Context){ + assert!( context::exist_object(ctx, mutatorID), EMutatorNotExist); + context::borrow_object(ctx, mutatorID); + } + + public fun add_collection_extend(mutator: &ObjectRef,val: V,ctx: &mut Context){ + assert_mutator_exist_of_ref(mutator); + let collection = object_ref::borrow(mutator); + assert_collection_exist_of_id(collection.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, collection.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + type_table::add( &mut collection_mut_ref.extend, val); + } + + public fun borrow_collection_extend(mutator: &ObjectRef, ctx: &mut Context):&V{ + assert_mutator_exist_of_ref(mutator); + let collection = object_ref::borrow(mutator); + assert_collection_exist_of_id(collection.collection, ctx); + let collection_object_ref = context::borrow_object(ctx, collection.collection); + let collection_ref = object::borrow(collection_object_ref); + type_table::borrow(&collection_ref.extend) + } + + public fun borrow_mut_collection_extend(mutator: &ObjectRef, ctx: &mut Context):&mut V{ + assert_mutator_exist_of_ref(mutator); + let collection = object_ref::borrow(mutator); + assert_collection_exist_of_id(collection.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, collection.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + type_table::borrow_mut(&mut collection_mut_ref.extend) + } + + public fun remove_collection_extend(mutator: &ObjectRef, ctx: &mut Context){ + assert_mutator_exist_of_ref(mutator); + let collection = object_ref::borrow(mutator); + assert_collection_exist_of_id(collection.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, collection.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + type_table::remove(&mut collection_mut_ref.extend) + } + + public fun contains_collection_extend(mutator: &ObjectRef, ctx: &mut Context): bool{ + assert_mutator_exist_of_ref(mutator); + let collection = object_ref::borrow(mutator); + assert_collection_exist_of_id(collection.collection, ctx); + let collection_object_ref = context::borrow_object(ctx, collection.collection); + let collection_ref = object::borrow(collection_object_ref); + type_table::contains(&collection_ref.extend) + } + + // view + + public fun get_collection_name(collectionID: ObjectID, ctx: &mut Context): String{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.name + } + + public fun get_collection_uri(collectionID: ObjectID, ctx: &mut Context): String{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.uri + } + + public fun get_collection_creator(collectionID: ObjectID, ctx: &mut Context): address{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.creator + } + + public fun get_collection_description(collectionID: ObjectID, ctx: &mut Context): String{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.description + } + + public fun get_collection_current_supply(collectionID: ObjectID, ctx: &mut Context): u64{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.supply.current + } + + public fun get_collection_maximum_supply(collectionID: ObjectID, ctx: &mut Context): Option{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.supply.maximum + } + +} diff --git a/crates/rooch-framework/sources/nft/display.move b/crates/rooch-framework/sources/nft/display.move new file mode 100644 index 0000000000..e69de29bb2 diff --git a/crates/rooch-framework/sources/nft/nft.move b/crates/rooch-framework/sources/nft/nft.move new file mode 100644 index 0000000000..e69de29bb2 From 8135aa32d320313e88fa45e64cfb90b36c16c39e Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Sun, 15 Oct 2023 02:44:22 +0800 Subject: [PATCH 02/17] add nft.move --- .../sources/nft/collection.move | 89 +++++++--- crates/rooch-framework/sources/nft/nft.move | 168 ++++++++++++++++++ 2 files changed, 229 insertions(+), 28 deletions(-) diff --git a/crates/rooch-framework/sources/nft/collection.move b/crates/rooch-framework/sources/nft/collection.move index 54153a36c3..cb8fb59556 100644 --- a/crates/rooch-framework/sources/nft/collection.move +++ b/crates/rooch-framework/sources/nft/collection.move @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 module rooch_framework::collection{ + use std::option; use std::option::Option; use std::string::String; use moveos_std::object::ObjectID; @@ -13,14 +14,16 @@ module rooch_framework::collection{ use moveos_std::object_ref::ObjectRef; use moveos_std::type_table; + friend rooch_framework::nft; + const EMutatorNotExist: u64 = 100; const ECollectionNotExist: u64 = 101; + const ECollectionMaximumSupply: u64 = 102; struct Collection has store{ name: String, uri: String, creator: address, - description: String, supply: Supply, extend: type_table::TypeTable } @@ -58,7 +61,6 @@ module rooch_framework::collection{ name, uri, creator, - description, supply: Supply { current: 0, maximum: max_supply, @@ -85,17 +87,53 @@ module rooch_framework::collection{ object_ref } - public fun generate_mutator_ref(collection: ObjectRef, ctx: &mut Context):ObjectRef{ + public fun generate_mutator_ref(collection: &ObjectRef, ctx: &mut Context):ObjectRef{ let mutator_ref = context::new_object_with_owner( ctx, - object_ref::owner(&collection), + object_ref::owner(collection), MutatorRef { - collection: object_ref::id(&collection), + collection: object_ref::id(collection), } ); mutator_ref } + public fun get_collection_id(mutator: &ObjectRef): ObjectID{ + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + mutator_object_ref.collection + } + + + public(friend) fun increment_supply(mutator: &ObjectRef, ctx: &mut Context): Option{ + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + assert_collection_exist_of_id(mutator_object_ref.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + collection_mut_ref.supply.current = collection_mut_ref.supply.current + 1; + if(option::is_some(&collection_mut_ref.supply.maximum)){ + assert!(collection_mut_ref.supply.current <= *option::borrow(&collection_mut_ref.supply.maximum), ECollectionMaximumSupply); + option::some(collection_mut_ref.supply.current) + }else{ + option::none() + } + } + + public (friend) fun decrement_supply(mutator: &ObjectRef, ctx: &mut Context): Option{ + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + assert_collection_exist_of_id(mutator_object_ref.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + collection_mut_ref.supply.current = collection_mut_ref.supply.current - 1; + if(option::is_some(&collection_mut_ref.supply.maximum)){ + option::some(collection_mut_ref.supply.current) + }else{ + option::none() + } + } + // assert public fun assert_collection_exist_of_ref(collectionRef: &ObjectRef){ assert!( object_ref::exist_object(collectionRef), ECollectionNotExist); @@ -115,53 +153,55 @@ module rooch_framework::collection{ context::borrow_object(ctx, mutatorID); } + #[private_generics(T)] public fun add_collection_extend(mutator: &ObjectRef,val: V,ctx: &mut Context){ assert_mutator_exist_of_ref(mutator); - let collection = object_ref::borrow(mutator); - assert_collection_exist_of_id(collection.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut(ctx, collection.collection); + let mutator_object_ref = object_ref::borrow(mutator); + assert_collection_exist_of_id(mutator_object_ref.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); type_table::add( &mut collection_mut_ref.extend, val); } public fun borrow_collection_extend(mutator: &ObjectRef, ctx: &mut Context):&V{ assert_mutator_exist_of_ref(mutator); - let collection = object_ref::borrow(mutator); - assert_collection_exist_of_id(collection.collection, ctx); - let collection_object_ref = context::borrow_object(ctx, collection.collection); + let mutator_object_ref = object_ref::borrow(mutator); + assert_collection_exist_of_id(mutator_object_ref.collection, ctx); + let collection_object_ref = context::borrow_object(ctx, mutator_object_ref.collection); let collection_ref = object::borrow(collection_object_ref); type_table::borrow(&collection_ref.extend) } + #[private_generics(T)] public fun borrow_mut_collection_extend(mutator: &ObjectRef, ctx: &mut Context):&mut V{ assert_mutator_exist_of_ref(mutator); - let collection = object_ref::borrow(mutator); - assert_collection_exist_of_id(collection.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut(ctx, collection.collection); + let mutator_object_ref = object_ref::borrow(mutator); + assert_collection_exist_of_id(mutator_object_ref.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); type_table::borrow_mut(&mut collection_mut_ref.extend) } + #[private_generics(T)] public fun remove_collection_extend(mutator: &ObjectRef, ctx: &mut Context){ assert_mutator_exist_of_ref(mutator); - let collection = object_ref::borrow(mutator); - assert_collection_exist_of_id(collection.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut(ctx, collection.collection); + let mutator_object_ref = object_ref::borrow(mutator); + assert_collection_exist_of_id(mutator_object_ref.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); type_table::remove(&mut collection_mut_ref.extend) } public fun contains_collection_extend(mutator: &ObjectRef, ctx: &mut Context): bool{ assert_mutator_exist_of_ref(mutator); - let collection = object_ref::borrow(mutator); - assert_collection_exist_of_id(collection.collection, ctx); - let collection_object_ref = context::borrow_object(ctx, collection.collection); + let mutator_object_ref = object_ref::borrow(mutator); + assert_collection_exist_of_id(mutator_object_ref.collection, ctx); + let collection_object_ref = context::borrow_object(ctx, mutator_object_ref.collection); let collection_ref = object::borrow(collection_object_ref); type_table::contains(&collection_ref.extend) } // view - public fun get_collection_name(collectionID: ObjectID, ctx: &mut Context): String{ assert_collection_exist_of_id(collectionID, ctx); let collection_object_ref = context::borrow_object(ctx, collectionID); @@ -183,13 +223,6 @@ module rooch_framework::collection{ collection_ref.creator } - public fun get_collection_description(collectionID: ObjectID, ctx: &mut Context): String{ - assert_collection_exist_of_id(collectionID, ctx); - let collection_object_ref = context::borrow_object(ctx, collectionID); - let collection_ref = object::borrow(collection_object_ref); - collection_ref.description - } - public fun get_collection_current_supply(collectionID: ObjectID, ctx: &mut Context): u64{ assert_collection_exist_of_id(collectionID, ctx); let collection_object_ref = context::borrow_object(ctx, collectionID); diff --git a/crates/rooch-framework/sources/nft/nft.move b/crates/rooch-framework/sources/nft/nft.move index e69de29bb2..933bfe15e1 100644 --- a/crates/rooch-framework/sources/nft/nft.move +++ b/crates/rooch-framework/sources/nft/nft.move @@ -0,0 +1,168 @@ +// Copyright (c) RoochNetwork +// SPDX-License-Identifier: Apache-2.0 + +module rooch_framework::nft { + use std::string::String; + use moveos_std::object_ref; + use moveos_std::object; + use rooch_framework::collection; + use moveos_std::object_ref::ObjectRef; + use moveos_std::context::Context; + use moveos_std::context; + use moveos_std::type_table; + use moveos_std::object::ObjectID; + use moveos_std::type_table::TypeTable; + + const ENftNotExist: u64 = 100; + const EMutatorNotExist: u64 = 101; + + struct NFT has store { + name: String, + uri: String, + collection: ObjectID, + creator: address, + extend: TypeTable + } + + struct MutatorRef has store{ + nft: ObjectID, + } + + public fun create_nft( + name: String, + uri: String, + mutator_ref: &ObjectRef, + creator: address, + ctx: &mut Context + ): ObjectRef { + collection::assert_mutator_exist_of_ref(mutator_ref); + let nft = NFT { + name, + uri, + collection: collection::get_collection_id(mutator_ref), + creator, + extend: type_table::new(ctx) + }; + + collection::increment_supply(mutator_ref, ctx); + + let object_ref = context::new_object_with_owner( + ctx, + creator, + nft + ); + + object_ref + } + + public fun generate_mutator_ref(nft_object_ref: &ObjectRef, ctx: &mut Context):ObjectRef{ + let mutator_ref = context::new_object_with_owner( + ctx, + object_ref::owner(nft_object_ref), + MutatorRef { + nft: object_ref::id(nft_object_ref), + } + ); + mutator_ref + } + + // assert + public fun assert_nft_exist_of_id(objectId: ObjectID, ctx: &Context) { + assert!(context::exist_object(ctx, objectId), ENftNotExist); + context::borrow_object(ctx, objectId); + } + + public fun assert_nft_exist_of_ref(nft_object_ref: &ObjectRef) { + assert!(object_ref::exist_object(nft_object_ref), ENftNotExist); + } + + public fun assert_mutator_exist_of_ref(mutator_ref: &ObjectRef) { + assert!(object_ref::exist_object(mutator_ref), EMutatorNotExist); + } + + public fun assert_mutator_exist_of_id(objectId: ObjectID, ctx: &Context) { + assert!(context::exist_object(ctx, objectId), EMutatorNotExist); + context::borrow_object(ctx, objectId); + } + + #[private_generics(T)] + public fun add_nft_extend(mutator: &ObjectRef,val: V,ctx: &mut Context) { + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + assert_nft_exist_of_id(mutator_object_ref.nft, ctx); + let nft_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.nft); + let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); + type_table::add( &mut nft_mut_ref.extend, val); + } + + + public fun borrow_nft_extend(mutator: &ObjectRef,ctx: &Context): &V { + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + assert_nft_exist_of_id(mutator_object_ref.nft, ctx); + let nft_object_ref = context::borrow_object(ctx, mutator_object_ref.nft); + let nft_mut_ref = object::borrow(nft_object_ref); + type_table::borrow(&nft_mut_ref.extend) + } + + #[private_generics(T)] + public fun borrow_mut_nft_extend(mutator: &ObjectRef,ctx: &mut Context): &mut V { + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + assert_nft_exist_of_id(mutator_object_ref.nft, ctx); + let nft_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.nft); + let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); + type_table::borrow_mut(&mut nft_mut_ref.extend) + } + + #[private_generics(T)] + public fun remove_nft_extend(mutator: &ObjectRef,ctx: &mut Context) { + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + assert_nft_exist_of_id(mutator_object_ref.nft, ctx); + let nft_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.nft); + let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); + type_table::remove(&mut nft_mut_ref.extend) + } + + public fun contains_nft_extend(mutator: &ObjectRef,ctx: &Context): bool { + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + assert_nft_exist_of_id(mutator_object_ref.nft, ctx); + let nft_object_ref = context::borrow_object(ctx, mutator_object_ref.nft); + let nft_mut_ref = object::borrow(nft_object_ref); + type_table::contains(&nft_mut_ref.extend) + } + + // view + + public fun get_name(objectId: ObjectID, ctx: &Context): String { + assert_nft_exist_of_id(objectId, ctx); + let nft_object_ref = context::borrow_object(ctx, objectId); + let nft = object::borrow(nft_object_ref); + nft.name + } + + public fun get_uri(objectId: ObjectID, ctx: &Context): String { + assert_nft_exist_of_id(objectId, ctx); + let nft_object_ref = context::borrow_object(ctx, objectId); + let nft = object::borrow(nft_object_ref); + nft.uri + } + + public fun get_collection(objectId: ObjectID, ctx: &Context): ObjectID { + assert_nft_exist_of_id(objectId, ctx); + let nft_object_ref = context::borrow_object(ctx, objectId); + let nft = object::borrow(nft_object_ref); + nft.collection + } + + public fun get_creator(objectId: ObjectID, ctx: &Context): address { + assert_nft_exist_of_id(objectId, ctx); + let nft_object_ref = context::borrow_object(ctx, objectId); + let nft = object::borrow(nft_object_ref); + nft.creator + } + + +} \ No newline at end of file From 7c8a16c29fe8e5ff5563a1fde18d3aa0e2725307 Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Sun, 15 Oct 2023 02:52:46 +0800 Subject: [PATCH 03/17] add burn nft --- crates/rooch-framework/sources/nft/nft.move | 39 ++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/crates/rooch-framework/sources/nft/nft.move b/crates/rooch-framework/sources/nft/nft.move index 933bfe15e1..1977b1e473 100644 --- a/crates/rooch-framework/sources/nft/nft.move +++ b/crates/rooch-framework/sources/nft/nft.move @@ -28,7 +28,11 @@ module rooch_framework::nft { nft: ObjectID, } - public fun create_nft( + struct BurnerRef has store{ + nft: ObjectID, + } + + public fun mint( name: String, uri: String, mutator_ref: &ObjectRef, @@ -55,6 +59,30 @@ module rooch_framework::nft { object_ref } + public fun burn ( + burn_ref: &ObjectRef, + mutator_ref: &ObjectRef, + ctx: &mut Context + ) { + assert_burner_exist_of_ref(burn_ref); + let burner_object_ref = object_ref::borrow(burn_ref); + assert_burner_exist_of_id(burner_object_ref.nft, ctx); + // let nft_object_mut_ref = context::borrow_object_mut(ctx, burner_object_ref.nft); + collection::decrement_supply(mutator_ref, ctx); + let ( + _, + _, + NFT { + name:_, + uri:_, + collection:_, + creator:_, + extend + } + ) = context::remove_object(ctx, burner_object_ref.nft); + type_table::destroy_empty(extend) + } + public fun generate_mutator_ref(nft_object_ref: &ObjectRef, ctx: &mut Context):ObjectRef{ let mutator_ref = context::new_object_with_owner( ctx, @@ -85,6 +113,15 @@ module rooch_framework::nft { context::borrow_object(ctx, objectId); } + public fun assert_burner_exist_of_ref(burner_ref: &ObjectRef) { + assert!(object_ref::exist_object(burner_ref), EMutatorNotExist); + } + + public fun assert_burner_exist_of_id(objectId: ObjectID, ctx: &Context) { + assert!(context::exist_object(ctx, objectId), EMutatorNotExist); + context::borrow_object(ctx, objectId); + } + #[private_generics(T)] public fun add_nft_extend(mutator: &ObjectRef,val: V,ctx: &mut Context) { assert_mutator_exist_of_ref(mutator); From 522d22bec3f324989615d81afb98511feee8f538 Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Sun, 15 Oct 2023 19:21:02 +0800 Subject: [PATCH 04/17] add Display --- .../sources/nft/collection.move | 9 ++++ .../rooch-framework/sources/nft/display.move | 42 +++++++++++++++++++ crates/rooch-framework/sources/nft/nft.move | 27 ++++++++++++ 3 files changed, 78 insertions(+) diff --git a/crates/rooch-framework/sources/nft/collection.move b/crates/rooch-framework/sources/nft/collection.move index cb8fb59556..793989a8e7 100644 --- a/crates/rooch-framework/sources/nft/collection.move +++ b/crates/rooch-framework/sources/nft/collection.move @@ -73,6 +73,7 @@ module rooch_framework::collection{ creator, collection ); + event::emit( ctx, CreateCollectionEvent { @@ -98,6 +99,14 @@ module rooch_framework::collection{ mutator_ref } + public fun destroy_mutator_ref(mutator_ref :ObjectRef):ObjectID{ + assert_mutator_exist_of_ref(&mutator_ref); + let MutatorRef { + collection + } = object_ref::remove(mutator_ref); + collection + } + public fun get_collection_id(mutator: &ObjectRef): ObjectID{ assert_mutator_exist_of_ref(mutator); let mutator_object_ref = object_ref::borrow(mutator); diff --git a/crates/rooch-framework/sources/nft/display.move b/crates/rooch-framework/sources/nft/display.move index e69de29bb2..27486d1516 100644 --- a/crates/rooch-framework/sources/nft/display.move +++ b/crates/rooch-framework/sources/nft/display.move @@ -0,0 +1,42 @@ +module rooch_framework::display{ + use std::ascii::String; + use moveos_std::simple_map; + + struct Display has key, store,drop,copy { + sample_map: simple_map::SimpleMap + } + + public fun new (): Display { + Display { + sample_map: simple_map::create() + } + } + + public fun set (self: &mut Display, key: String, value: String) { + simple_map::add(&mut self.sample_map, key, value); + } + + public fun borrow (self: & Display, key: String): &String { + simple_map::borrow(&mut self.sample_map, &key) + } + + public fun borrow_mut (self: &mut Display, key: String): &mut String { + simple_map::borrow_mut(&mut self.sample_map, &key) + } + + public fun remove (self: &mut Display, key: String) { + simple_map::remove(&mut self.sample_map, &key); + } + + public fun keys (self: & Display): vector { + simple_map::keys(& self.sample_map) + } + + public fun values (self: & Display): vector { + simple_map::values(& self.sample_map) + } + + public fun contains_key (self: & Display, key: String) -> bool { + simple_map::contains(& self.sample_map, key) + } +} \ No newline at end of file diff --git a/crates/rooch-framework/sources/nft/nft.move b/crates/rooch-framework/sources/nft/nft.move index 1977b1e473..9ee1b2475d 100644 --- a/crates/rooch-framework/sources/nft/nft.move +++ b/crates/rooch-framework/sources/nft/nft.move @@ -94,6 +94,33 @@ module rooch_framework::nft { mutator_ref } + public fun destroy_mutator_ref(mutator_ref :ObjectRef):ObjectID{ + assert_mutator_exist_of_ref(&mutator_ref); + let MutatorRef { + nft + } = object_ref::remove(mutator_ref); + nft + } + + public fun generate_burner_ref(nft_object_ref: &ObjectRef, ctx: &mut Context):ObjectRef{ + let burner_ref = context::new_object_with_owner( + ctx, + object_ref::owner(nft_object_ref), + BurnerRef { + nft: object_ref::id(nft_object_ref), + } + ); + burner_ref + } + + public fun destroy_burner_ref(burner_ref :ObjectRef):ObjectID{ + assert_burner_exist_of_ref(&burner_ref); + let BurnerRef { + nft + } = object_ref::remove(burner_ref); + nft + } + // assert public fun assert_nft_exist_of_id(objectId: ObjectID, ctx: &Context) { assert!(context::exist_object(ctx, objectId), ENftNotExist); From 9442a64456b24bb8b69a334c231c9f0a3449e87b Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Sun, 15 Oct 2023 02:01:38 +0800 Subject: [PATCH 05/17] init --- .../sources/nft/collection.move | 207 ++++++++++++++++++ .../rooch-framework/sources/nft/display.move | 0 crates/rooch-framework/sources/nft/nft.move | 0 3 files changed, 207 insertions(+) create mode 100644 crates/rooch-framework/sources/nft/collection.move create mode 100644 crates/rooch-framework/sources/nft/display.move create mode 100644 crates/rooch-framework/sources/nft/nft.move diff --git a/crates/rooch-framework/sources/nft/collection.move b/crates/rooch-framework/sources/nft/collection.move new file mode 100644 index 0000000000..54153a36c3 --- /dev/null +++ b/crates/rooch-framework/sources/nft/collection.move @@ -0,0 +1,207 @@ +// Copyright (c) RoochNetwork +// SPDX-License-Identifier: Apache-2.0 + +module rooch_framework::collection{ + use std::option::Option; + use std::string::String; + use moveos_std::object::ObjectID; + use moveos_std::object_ref; + use moveos_std::event; + use moveos_std::context; + use moveos_std::context::Context; + use moveos_std::object; + use moveos_std::object_ref::ObjectRef; + use moveos_std::type_table; + + const EMutatorNotExist: u64 = 100; + const ECollectionNotExist: u64 = 101; + + struct Collection has store{ + name: String, + uri: String, + creator: address, + description: String, + supply: Supply, + extend: type_table::TypeTable + } + + struct Supply has store{ + current: u64, + maximum: Option, + } + + struct MutatorRef has store{ + collection: ObjectID, + } + + // event + struct CreateCollectionEvent{ + objectID: ObjectID, + name: String, + uri: String, + creator: address, + maximum: Option, + description: String, + } + + + public fun create_collection( + name: String, + uri: String, + creator: address, + description: String, + max_supply: Option, + ctx: &mut Context + ):ObjectRef { + + let collection = Collection { + name, + uri, + creator, + description, + supply: Supply { + current: 0, + maximum: max_supply, + }, + extend: type_table::new(ctx) + }; + + let object_ref = context::new_object_with_owner( + ctx, + creator, + collection + ); + event::emit( + ctx, + CreateCollectionEvent { + objectID: object_ref::id(&object_ref), + name, + uri, + creator, + maximum: max_supply, + description, + } + ); + object_ref + } + + public fun generate_mutator_ref(collection: ObjectRef, ctx: &mut Context):ObjectRef{ + let mutator_ref = context::new_object_with_owner( + ctx, + object_ref::owner(&collection), + MutatorRef { + collection: object_ref::id(&collection), + } + ); + mutator_ref + } + + // assert + public fun assert_collection_exist_of_ref(collectionRef: &ObjectRef){ + assert!( object_ref::exist_object(collectionRef), ECollectionNotExist); + } + + public fun assert_collection_exist_of_id(collectionID: ObjectID, ctx: & Context){ + assert!( context::exist_object(ctx, collectionID), ECollectionNotExist); + context::borrow_object(ctx,collectionID); + } + + public fun assert_mutator_exist_of_ref(mutatorRef: &ObjectRef){ + assert!( object_ref::exist_object(mutatorRef), EMutatorNotExist); + } + + public fun assert_mutator_exist_of_id(mutatorID: ObjectID, ctx: & Context){ + assert!( context::exist_object(ctx, mutatorID), EMutatorNotExist); + context::borrow_object(ctx, mutatorID); + } + + public fun add_collection_extend(mutator: &ObjectRef,val: V,ctx: &mut Context){ + assert_mutator_exist_of_ref(mutator); + let collection = object_ref::borrow(mutator); + assert_collection_exist_of_id(collection.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, collection.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + type_table::add( &mut collection_mut_ref.extend, val); + } + + public fun borrow_collection_extend(mutator: &ObjectRef, ctx: &mut Context):&V{ + assert_mutator_exist_of_ref(mutator); + let collection = object_ref::borrow(mutator); + assert_collection_exist_of_id(collection.collection, ctx); + let collection_object_ref = context::borrow_object(ctx, collection.collection); + let collection_ref = object::borrow(collection_object_ref); + type_table::borrow(&collection_ref.extend) + } + + public fun borrow_mut_collection_extend(mutator: &ObjectRef, ctx: &mut Context):&mut V{ + assert_mutator_exist_of_ref(mutator); + let collection = object_ref::borrow(mutator); + assert_collection_exist_of_id(collection.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, collection.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + type_table::borrow_mut(&mut collection_mut_ref.extend) + } + + public fun remove_collection_extend(mutator: &ObjectRef, ctx: &mut Context){ + assert_mutator_exist_of_ref(mutator); + let collection = object_ref::borrow(mutator); + assert_collection_exist_of_id(collection.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, collection.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + type_table::remove(&mut collection_mut_ref.extend) + } + + public fun contains_collection_extend(mutator: &ObjectRef, ctx: &mut Context): bool{ + assert_mutator_exist_of_ref(mutator); + let collection = object_ref::borrow(mutator); + assert_collection_exist_of_id(collection.collection, ctx); + let collection_object_ref = context::borrow_object(ctx, collection.collection); + let collection_ref = object::borrow(collection_object_ref); + type_table::contains(&collection_ref.extend) + } + + // view + + public fun get_collection_name(collectionID: ObjectID, ctx: &mut Context): String{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.name + } + + public fun get_collection_uri(collectionID: ObjectID, ctx: &mut Context): String{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.uri + } + + public fun get_collection_creator(collectionID: ObjectID, ctx: &mut Context): address{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.creator + } + + public fun get_collection_description(collectionID: ObjectID, ctx: &mut Context): String{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.description + } + + public fun get_collection_current_supply(collectionID: ObjectID, ctx: &mut Context): u64{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.supply.current + } + + public fun get_collection_maximum_supply(collectionID: ObjectID, ctx: &mut Context): Option{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.supply.maximum + } + +} diff --git a/crates/rooch-framework/sources/nft/display.move b/crates/rooch-framework/sources/nft/display.move new file mode 100644 index 0000000000..e69de29bb2 diff --git a/crates/rooch-framework/sources/nft/nft.move b/crates/rooch-framework/sources/nft/nft.move new file mode 100644 index 0000000000..e69de29bb2 From f760a27291e029dc8d4c482521641b7bba44eb45 Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Sun, 15 Oct 2023 02:44:22 +0800 Subject: [PATCH 06/17] add nft.move --- .../sources/nft/collection.move | 89 +++++++--- crates/rooch-framework/sources/nft/nft.move | 168 ++++++++++++++++++ 2 files changed, 229 insertions(+), 28 deletions(-) diff --git a/crates/rooch-framework/sources/nft/collection.move b/crates/rooch-framework/sources/nft/collection.move index 54153a36c3..cb8fb59556 100644 --- a/crates/rooch-framework/sources/nft/collection.move +++ b/crates/rooch-framework/sources/nft/collection.move @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 module rooch_framework::collection{ + use std::option; use std::option::Option; use std::string::String; use moveos_std::object::ObjectID; @@ -13,14 +14,16 @@ module rooch_framework::collection{ use moveos_std::object_ref::ObjectRef; use moveos_std::type_table; + friend rooch_framework::nft; + const EMutatorNotExist: u64 = 100; const ECollectionNotExist: u64 = 101; + const ECollectionMaximumSupply: u64 = 102; struct Collection has store{ name: String, uri: String, creator: address, - description: String, supply: Supply, extend: type_table::TypeTable } @@ -58,7 +61,6 @@ module rooch_framework::collection{ name, uri, creator, - description, supply: Supply { current: 0, maximum: max_supply, @@ -85,17 +87,53 @@ module rooch_framework::collection{ object_ref } - public fun generate_mutator_ref(collection: ObjectRef, ctx: &mut Context):ObjectRef{ + public fun generate_mutator_ref(collection: &ObjectRef, ctx: &mut Context):ObjectRef{ let mutator_ref = context::new_object_with_owner( ctx, - object_ref::owner(&collection), + object_ref::owner(collection), MutatorRef { - collection: object_ref::id(&collection), + collection: object_ref::id(collection), } ); mutator_ref } + public fun get_collection_id(mutator: &ObjectRef): ObjectID{ + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + mutator_object_ref.collection + } + + + public(friend) fun increment_supply(mutator: &ObjectRef, ctx: &mut Context): Option{ + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + assert_collection_exist_of_id(mutator_object_ref.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + collection_mut_ref.supply.current = collection_mut_ref.supply.current + 1; + if(option::is_some(&collection_mut_ref.supply.maximum)){ + assert!(collection_mut_ref.supply.current <= *option::borrow(&collection_mut_ref.supply.maximum), ECollectionMaximumSupply); + option::some(collection_mut_ref.supply.current) + }else{ + option::none() + } + } + + public (friend) fun decrement_supply(mutator: &ObjectRef, ctx: &mut Context): Option{ + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + assert_collection_exist_of_id(mutator_object_ref.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + collection_mut_ref.supply.current = collection_mut_ref.supply.current - 1; + if(option::is_some(&collection_mut_ref.supply.maximum)){ + option::some(collection_mut_ref.supply.current) + }else{ + option::none() + } + } + // assert public fun assert_collection_exist_of_ref(collectionRef: &ObjectRef){ assert!( object_ref::exist_object(collectionRef), ECollectionNotExist); @@ -115,53 +153,55 @@ module rooch_framework::collection{ context::borrow_object(ctx, mutatorID); } + #[private_generics(T)] public fun add_collection_extend(mutator: &ObjectRef,val: V,ctx: &mut Context){ assert_mutator_exist_of_ref(mutator); - let collection = object_ref::borrow(mutator); - assert_collection_exist_of_id(collection.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut(ctx, collection.collection); + let mutator_object_ref = object_ref::borrow(mutator); + assert_collection_exist_of_id(mutator_object_ref.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); type_table::add( &mut collection_mut_ref.extend, val); } public fun borrow_collection_extend(mutator: &ObjectRef, ctx: &mut Context):&V{ assert_mutator_exist_of_ref(mutator); - let collection = object_ref::borrow(mutator); - assert_collection_exist_of_id(collection.collection, ctx); - let collection_object_ref = context::borrow_object(ctx, collection.collection); + let mutator_object_ref = object_ref::borrow(mutator); + assert_collection_exist_of_id(mutator_object_ref.collection, ctx); + let collection_object_ref = context::borrow_object(ctx, mutator_object_ref.collection); let collection_ref = object::borrow(collection_object_ref); type_table::borrow(&collection_ref.extend) } + #[private_generics(T)] public fun borrow_mut_collection_extend(mutator: &ObjectRef, ctx: &mut Context):&mut V{ assert_mutator_exist_of_ref(mutator); - let collection = object_ref::borrow(mutator); - assert_collection_exist_of_id(collection.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut(ctx, collection.collection); + let mutator_object_ref = object_ref::borrow(mutator); + assert_collection_exist_of_id(mutator_object_ref.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); type_table::borrow_mut(&mut collection_mut_ref.extend) } + #[private_generics(T)] public fun remove_collection_extend(mutator: &ObjectRef, ctx: &mut Context){ assert_mutator_exist_of_ref(mutator); - let collection = object_ref::borrow(mutator); - assert_collection_exist_of_id(collection.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut(ctx, collection.collection); + let mutator_object_ref = object_ref::borrow(mutator); + assert_collection_exist_of_id(mutator_object_ref.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); type_table::remove(&mut collection_mut_ref.extend) } public fun contains_collection_extend(mutator: &ObjectRef, ctx: &mut Context): bool{ assert_mutator_exist_of_ref(mutator); - let collection = object_ref::borrow(mutator); - assert_collection_exist_of_id(collection.collection, ctx); - let collection_object_ref = context::borrow_object(ctx, collection.collection); + let mutator_object_ref = object_ref::borrow(mutator); + assert_collection_exist_of_id(mutator_object_ref.collection, ctx); + let collection_object_ref = context::borrow_object(ctx, mutator_object_ref.collection); let collection_ref = object::borrow(collection_object_ref); type_table::contains(&collection_ref.extend) } // view - public fun get_collection_name(collectionID: ObjectID, ctx: &mut Context): String{ assert_collection_exist_of_id(collectionID, ctx); let collection_object_ref = context::borrow_object(ctx, collectionID); @@ -183,13 +223,6 @@ module rooch_framework::collection{ collection_ref.creator } - public fun get_collection_description(collectionID: ObjectID, ctx: &mut Context): String{ - assert_collection_exist_of_id(collectionID, ctx); - let collection_object_ref = context::borrow_object(ctx, collectionID); - let collection_ref = object::borrow(collection_object_ref); - collection_ref.description - } - public fun get_collection_current_supply(collectionID: ObjectID, ctx: &mut Context): u64{ assert_collection_exist_of_id(collectionID, ctx); let collection_object_ref = context::borrow_object(ctx, collectionID); diff --git a/crates/rooch-framework/sources/nft/nft.move b/crates/rooch-framework/sources/nft/nft.move index e69de29bb2..933bfe15e1 100644 --- a/crates/rooch-framework/sources/nft/nft.move +++ b/crates/rooch-framework/sources/nft/nft.move @@ -0,0 +1,168 @@ +// Copyright (c) RoochNetwork +// SPDX-License-Identifier: Apache-2.0 + +module rooch_framework::nft { + use std::string::String; + use moveos_std::object_ref; + use moveos_std::object; + use rooch_framework::collection; + use moveos_std::object_ref::ObjectRef; + use moveos_std::context::Context; + use moveos_std::context; + use moveos_std::type_table; + use moveos_std::object::ObjectID; + use moveos_std::type_table::TypeTable; + + const ENftNotExist: u64 = 100; + const EMutatorNotExist: u64 = 101; + + struct NFT has store { + name: String, + uri: String, + collection: ObjectID, + creator: address, + extend: TypeTable + } + + struct MutatorRef has store{ + nft: ObjectID, + } + + public fun create_nft( + name: String, + uri: String, + mutator_ref: &ObjectRef, + creator: address, + ctx: &mut Context + ): ObjectRef { + collection::assert_mutator_exist_of_ref(mutator_ref); + let nft = NFT { + name, + uri, + collection: collection::get_collection_id(mutator_ref), + creator, + extend: type_table::new(ctx) + }; + + collection::increment_supply(mutator_ref, ctx); + + let object_ref = context::new_object_with_owner( + ctx, + creator, + nft + ); + + object_ref + } + + public fun generate_mutator_ref(nft_object_ref: &ObjectRef, ctx: &mut Context):ObjectRef{ + let mutator_ref = context::new_object_with_owner( + ctx, + object_ref::owner(nft_object_ref), + MutatorRef { + nft: object_ref::id(nft_object_ref), + } + ); + mutator_ref + } + + // assert + public fun assert_nft_exist_of_id(objectId: ObjectID, ctx: &Context) { + assert!(context::exist_object(ctx, objectId), ENftNotExist); + context::borrow_object(ctx, objectId); + } + + public fun assert_nft_exist_of_ref(nft_object_ref: &ObjectRef) { + assert!(object_ref::exist_object(nft_object_ref), ENftNotExist); + } + + public fun assert_mutator_exist_of_ref(mutator_ref: &ObjectRef) { + assert!(object_ref::exist_object(mutator_ref), EMutatorNotExist); + } + + public fun assert_mutator_exist_of_id(objectId: ObjectID, ctx: &Context) { + assert!(context::exist_object(ctx, objectId), EMutatorNotExist); + context::borrow_object(ctx, objectId); + } + + #[private_generics(T)] + public fun add_nft_extend(mutator: &ObjectRef,val: V,ctx: &mut Context) { + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + assert_nft_exist_of_id(mutator_object_ref.nft, ctx); + let nft_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.nft); + let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); + type_table::add( &mut nft_mut_ref.extend, val); + } + + + public fun borrow_nft_extend(mutator: &ObjectRef,ctx: &Context): &V { + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + assert_nft_exist_of_id(mutator_object_ref.nft, ctx); + let nft_object_ref = context::borrow_object(ctx, mutator_object_ref.nft); + let nft_mut_ref = object::borrow(nft_object_ref); + type_table::borrow(&nft_mut_ref.extend) + } + + #[private_generics(T)] + public fun borrow_mut_nft_extend(mutator: &ObjectRef,ctx: &mut Context): &mut V { + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + assert_nft_exist_of_id(mutator_object_ref.nft, ctx); + let nft_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.nft); + let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); + type_table::borrow_mut(&mut nft_mut_ref.extend) + } + + #[private_generics(T)] + public fun remove_nft_extend(mutator: &ObjectRef,ctx: &mut Context) { + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + assert_nft_exist_of_id(mutator_object_ref.nft, ctx); + let nft_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.nft); + let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); + type_table::remove(&mut nft_mut_ref.extend) + } + + public fun contains_nft_extend(mutator: &ObjectRef,ctx: &Context): bool { + assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); + assert_nft_exist_of_id(mutator_object_ref.nft, ctx); + let nft_object_ref = context::borrow_object(ctx, mutator_object_ref.nft); + let nft_mut_ref = object::borrow(nft_object_ref); + type_table::contains(&nft_mut_ref.extend) + } + + // view + + public fun get_name(objectId: ObjectID, ctx: &Context): String { + assert_nft_exist_of_id(objectId, ctx); + let nft_object_ref = context::borrow_object(ctx, objectId); + let nft = object::borrow(nft_object_ref); + nft.name + } + + public fun get_uri(objectId: ObjectID, ctx: &Context): String { + assert_nft_exist_of_id(objectId, ctx); + let nft_object_ref = context::borrow_object(ctx, objectId); + let nft = object::borrow(nft_object_ref); + nft.uri + } + + public fun get_collection(objectId: ObjectID, ctx: &Context): ObjectID { + assert_nft_exist_of_id(objectId, ctx); + let nft_object_ref = context::borrow_object(ctx, objectId); + let nft = object::borrow(nft_object_ref); + nft.collection + } + + public fun get_creator(objectId: ObjectID, ctx: &Context): address { + assert_nft_exist_of_id(objectId, ctx); + let nft_object_ref = context::borrow_object(ctx, objectId); + let nft = object::borrow(nft_object_ref); + nft.creator + } + + +} \ No newline at end of file From c849b4258b1de0fa749368f480c427181d35f44e Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Sun, 15 Oct 2023 02:52:46 +0800 Subject: [PATCH 07/17] add burn nft --- crates/rooch-framework/sources/nft/nft.move | 39 ++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/crates/rooch-framework/sources/nft/nft.move b/crates/rooch-framework/sources/nft/nft.move index 933bfe15e1..1977b1e473 100644 --- a/crates/rooch-framework/sources/nft/nft.move +++ b/crates/rooch-framework/sources/nft/nft.move @@ -28,7 +28,11 @@ module rooch_framework::nft { nft: ObjectID, } - public fun create_nft( + struct BurnerRef has store{ + nft: ObjectID, + } + + public fun mint( name: String, uri: String, mutator_ref: &ObjectRef, @@ -55,6 +59,30 @@ module rooch_framework::nft { object_ref } + public fun burn ( + burn_ref: &ObjectRef, + mutator_ref: &ObjectRef, + ctx: &mut Context + ) { + assert_burner_exist_of_ref(burn_ref); + let burner_object_ref = object_ref::borrow(burn_ref); + assert_burner_exist_of_id(burner_object_ref.nft, ctx); + // let nft_object_mut_ref = context::borrow_object_mut(ctx, burner_object_ref.nft); + collection::decrement_supply(mutator_ref, ctx); + let ( + _, + _, + NFT { + name:_, + uri:_, + collection:_, + creator:_, + extend + } + ) = context::remove_object(ctx, burner_object_ref.nft); + type_table::destroy_empty(extend) + } + public fun generate_mutator_ref(nft_object_ref: &ObjectRef, ctx: &mut Context):ObjectRef{ let mutator_ref = context::new_object_with_owner( ctx, @@ -85,6 +113,15 @@ module rooch_framework::nft { context::borrow_object(ctx, objectId); } + public fun assert_burner_exist_of_ref(burner_ref: &ObjectRef) { + assert!(object_ref::exist_object(burner_ref), EMutatorNotExist); + } + + public fun assert_burner_exist_of_id(objectId: ObjectID, ctx: &Context) { + assert!(context::exist_object(ctx, objectId), EMutatorNotExist); + context::borrow_object(ctx, objectId); + } + #[private_generics(T)] public fun add_nft_extend(mutator: &ObjectRef,val: V,ctx: &mut Context) { assert_mutator_exist_of_ref(mutator); From 4a8a68c0c0ed7e40fd27cafe1f50d701e36ee15f Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Sun, 15 Oct 2023 19:21:02 +0800 Subject: [PATCH 08/17] add Display --- .../sources/nft/collection.move | 9 ++++ .../rooch-framework/sources/nft/display.move | 42 +++++++++++++++++++ crates/rooch-framework/sources/nft/nft.move | 27 ++++++++++++ 3 files changed, 78 insertions(+) diff --git a/crates/rooch-framework/sources/nft/collection.move b/crates/rooch-framework/sources/nft/collection.move index cb8fb59556..793989a8e7 100644 --- a/crates/rooch-framework/sources/nft/collection.move +++ b/crates/rooch-framework/sources/nft/collection.move @@ -73,6 +73,7 @@ module rooch_framework::collection{ creator, collection ); + event::emit( ctx, CreateCollectionEvent { @@ -98,6 +99,14 @@ module rooch_framework::collection{ mutator_ref } + public fun destroy_mutator_ref(mutator_ref :ObjectRef):ObjectID{ + assert_mutator_exist_of_ref(&mutator_ref); + let MutatorRef { + collection + } = object_ref::remove(mutator_ref); + collection + } + public fun get_collection_id(mutator: &ObjectRef): ObjectID{ assert_mutator_exist_of_ref(mutator); let mutator_object_ref = object_ref::borrow(mutator); diff --git a/crates/rooch-framework/sources/nft/display.move b/crates/rooch-framework/sources/nft/display.move index e69de29bb2..27486d1516 100644 --- a/crates/rooch-framework/sources/nft/display.move +++ b/crates/rooch-framework/sources/nft/display.move @@ -0,0 +1,42 @@ +module rooch_framework::display{ + use std::ascii::String; + use moveos_std::simple_map; + + struct Display has key, store,drop,copy { + sample_map: simple_map::SimpleMap + } + + public fun new (): Display { + Display { + sample_map: simple_map::create() + } + } + + public fun set (self: &mut Display, key: String, value: String) { + simple_map::add(&mut self.sample_map, key, value); + } + + public fun borrow (self: & Display, key: String): &String { + simple_map::borrow(&mut self.sample_map, &key) + } + + public fun borrow_mut (self: &mut Display, key: String): &mut String { + simple_map::borrow_mut(&mut self.sample_map, &key) + } + + public fun remove (self: &mut Display, key: String) { + simple_map::remove(&mut self.sample_map, &key); + } + + public fun keys (self: & Display): vector { + simple_map::keys(& self.sample_map) + } + + public fun values (self: & Display): vector { + simple_map::values(& self.sample_map) + } + + public fun contains_key (self: & Display, key: String) -> bool { + simple_map::contains(& self.sample_map, key) + } +} \ No newline at end of file diff --git a/crates/rooch-framework/sources/nft/nft.move b/crates/rooch-framework/sources/nft/nft.move index 1977b1e473..9ee1b2475d 100644 --- a/crates/rooch-framework/sources/nft/nft.move +++ b/crates/rooch-framework/sources/nft/nft.move @@ -94,6 +94,33 @@ module rooch_framework::nft { mutator_ref } + public fun destroy_mutator_ref(mutator_ref :ObjectRef):ObjectID{ + assert_mutator_exist_of_ref(&mutator_ref); + let MutatorRef { + nft + } = object_ref::remove(mutator_ref); + nft + } + + public fun generate_burner_ref(nft_object_ref: &ObjectRef, ctx: &mut Context):ObjectRef{ + let burner_ref = context::new_object_with_owner( + ctx, + object_ref::owner(nft_object_ref), + BurnerRef { + nft: object_ref::id(nft_object_ref), + } + ); + burner_ref + } + + public fun destroy_burner_ref(burner_ref :ObjectRef):ObjectID{ + assert_burner_exist_of_ref(&burner_ref); + let BurnerRef { + nft + } = object_ref::remove(burner_ref); + nft + } + // assert public fun assert_nft_exist_of_id(objectId: ObjectID, ctx: &Context) { assert!(context::exist_object(ctx, objectId), ENftNotExist); From b2743fa8f1ed67aea75dbcf45b68b88f60a99f41 Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Mon, 16 Oct 2023 16:23:42 +0800 Subject: [PATCH 09/17] add unit test --- .../rooch-framework/sources/nft/display.move | 6 +-- crates/rooch-framework/sources/nft/nft.move | 53 +++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/crates/rooch-framework/sources/nft/display.move b/crates/rooch-framework/sources/nft/display.move index 27486d1516..869ba76895 100644 --- a/crates/rooch-framework/sources/nft/display.move +++ b/crates/rooch-framework/sources/nft/display.move @@ -1,5 +1,5 @@ module rooch_framework::display{ - use std::ascii::String; + use std::string::String; use moveos_std::simple_map; struct Display has key, store,drop,copy { @@ -36,7 +36,7 @@ module rooch_framework::display{ simple_map::values(& self.sample_map) } - public fun contains_key (self: & Display, key: String) -> bool { - simple_map::contains(& self.sample_map, key) + public fun contains_key (self: & Display, key: String): bool { + simple_map::contains_key(& self.sample_map, &key) } } \ No newline at end of file diff --git a/crates/rooch-framework/sources/nft/nft.move b/crates/rooch-framework/sources/nft/nft.move index 9ee1b2475d..864bd29b2f 100644 --- a/crates/rooch-framework/sources/nft/nft.move +++ b/crates/rooch-framework/sources/nft/nft.move @@ -12,6 +12,12 @@ module rooch_framework::nft { use moveos_std::type_table; use moveos_std::object::ObjectID; use moveos_std::type_table::TypeTable; + #[test_only] + use std::option; + #[test_only] + use std::string; + #[test_only] + use rooch_framework::display; const ENftNotExist: u64 = 100; const EMutatorNotExist: u64 = 101; @@ -228,5 +234,52 @@ module rooch_framework::nft { nft.creator } + #[test(sender = @0x2)] + public fun test_create_nft (sender: address){ + let ctx = context::new_test_context(sender); + + let collection_object_ref = collection::create_collection( + string::utf8(b"name"), + string::utf8(b"uri"), + sender, + string::utf8(b"description"), + option::none(), + &mut ctx + ); + + let collection_mutator_ref = collection::generate_mutator_ref(&collection_object_ref, &mut ctx); + let collcetion_display = display::new(); + display::set(&mut collcetion_display, string::utf8(b"name"), string::utf8(b"{ name }")); + display::set(&mut collcetion_display, string::utf8(b"uri"), string::utf8(b"{ uri }")); + display::set(&mut collcetion_display, string::utf8(b"description"), string::utf8(b"{ description }")); + display::set(&mut collcetion_display, string::utf8(b"creator"), string::utf8(b"{ creator }")); + display::set(&mut collcetion_display, string::utf8(b"supply"), string::utf8(b"{ supply }")); + collection::add_collection_extend( + &collection_mutator_ref, + collcetion_display, &mut ctx + ); + + let nft_object_ref = mint( + string::utf8(b"name"), + string::utf8(b"uri"), + &collection_mutator_ref, + sender, + &mut ctx + ); + + let nft_display = display::new(); + display::set(&mut nft_display, string::utf8(b"name"), string::utf8(b"{ name }")); + display::set(&mut nft_display, string::utf8(b"uri"), string::utf8(b"{ uri }/{ name }.png")); + display::set(&mut nft_display, string::utf8(b"collection"), string::utf8(b"{ collection }")); + + let nft_mutaor_ref = generate_mutator_ref(&nft_object_ref, &mut ctx); + add_nft_extend( + &nft_mutaor_ref, + nft_display, + &mut ctx + ); + + context::drop_test_context(ctx); + } } \ No newline at end of file From 606f3bd178cbc99ecb2b5d65ad0c9f136f55333a Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Mon, 16 Oct 2023 17:46:20 +0800 Subject: [PATCH 10/17] Fix unit test --- crates/rooch-framework/doc/README.md | 3 + crates/rooch-framework/doc/collection.md | 937 ++++++++++++++++++ crates/rooch-framework/doc/display.md | 244 +++++ crates/rooch-framework/doc/nft.md | 882 +++++++++++++++++ .../sources/nft/collection.move | 67 +- .../rooch-framework/sources/nft/display.move | 17 +- crates/rooch-framework/sources/nft/nft.move | 88 +- 7 files changed, 2200 insertions(+), 38 deletions(-) create mode 100644 crates/rooch-framework/doc/collection.md create mode 100644 crates/rooch-framework/doc/display.md create mode 100644 crates/rooch-framework/doc/nft.md diff --git a/crates/rooch-framework/doc/README.md b/crates/rooch-framework/doc/README.md index e665567beb..218cb032c4 100644 --- a/crates/rooch-framework/doc/README.md +++ b/crates/rooch-framework/doc/README.md @@ -24,8 +24,10 @@ This is the reference documentation of the Rooch Framework. - [`0x3::chain_id`](chain_id.md#0x3_chain_id) - [`0x3::coin`](coin.md#0x3_coin) - [`0x3::coin_store`](coin_store.md#0x3_coin_store) +- [`0x3::collection`](collection.md#0x3_collection) - [`0x3::core_addresses`](core_addresses.md#0x3_core_addresses) - [`0x3::decoding`](decoding.md#0x3_decoding) +- [`0x3::display`](display.md#0x3_display) - [`0x3::ecdsa_k1`](ecdsa_k1.md#0x3_ecdsa_k1) - [`0x3::ecdsa_k1_recoverable`](ecdsa_k1_recoverable.md#0x3_ecdsa_k1_recoverable) - [`0x3::ed25519`](ed25519.md#0x3_ed25519) @@ -39,6 +41,7 @@ This is the reference documentation of the Rooch Framework. - [`0x3::hash`](hash.md#0x3_hash) - [`0x3::multichain_address`](multichain_address.md#0x3_multichain_address) - [`0x3::native_validator`](native_validator.md#0x3_native_validator) +- [`0x3::nft`](nft.md#0x3_nft) - [`0x3::schnorr`](schnorr.md#0x3_schnorr) - [`0x3::session_key`](session_key.md#0x3_session_key) - [`0x3::timestamp`](timestamp.md#0x3_timestamp) diff --git a/crates/rooch-framework/doc/collection.md b/crates/rooch-framework/doc/collection.md new file mode 100644 index 0000000000..77eed1249e --- /dev/null +++ b/crates/rooch-framework/doc/collection.md @@ -0,0 +1,937 @@ + + + +# Module `0x3::collection` + + + +- [Resource `Collection`](#0x3_collection_Collection) +- [Struct `Supply`](#0x3_collection_Supply) +- [Resource `MutatorRef`](#0x3_collection_MutatorRef) +- [Struct `CreateCollectionEvent`](#0x3_collection_CreateCollectionEvent) +- [Constants](#@Constants_0) +- [Function `create_collection`](#0x3_collection_create_collection) +- [Function `generate_mutator_ref`](#0x3_collection_generate_mutator_ref) +- [Function `destroy_mutator_ref`](#0x3_collection_destroy_mutator_ref) +- [Function `get_collection_id`](#0x3_collection_get_collection_id) +- [Function `increment_supply`](#0x3_collection_increment_supply) +- [Function `decrement_supply`](#0x3_collection_decrement_supply) +- [Function `assert_collection_exist_of_ref`](#0x3_collection_assert_collection_exist_of_ref) +- [Function `assert_collection_exist_of_id`](#0x3_collection_assert_collection_exist_of_id) +- [Function `assert_mutator_exist_of_ref`](#0x3_collection_assert_mutator_exist_of_ref) +- [Function `assert_mutator_exist_of_id`](#0x3_collection_assert_mutator_exist_of_id) +- [Function `add_display`](#0x3_collection_add_display) +- [Function `borrow_display`](#0x3_collection_borrow_display) +- [Function `borrow_mut_display`](#0x3_collection_borrow_mut_display) +- [Function `remove_display`](#0x3_collection_remove_display) +- [Function `contains_display`](#0x3_collection_contains_display) +- [Function `add_extend`](#0x3_collection_add_extend) +- [Function `borrow_extend`](#0x3_collection_borrow_extend) +- [Function `borrow_mut_extend`](#0x3_collection_borrow_mut_extend) +- [Function `remove_extend`](#0x3_collection_remove_extend) +- [Function `contains_extend`](#0x3_collection_contains_extend) +- [Function `get_collection_name`](#0x3_collection_get_collection_name) +- [Function `get_collection_uri`](#0x3_collection_get_collection_uri) +- [Function `get_collection_creator`](#0x3_collection_get_collection_creator) +- [Function `get_collection_current_supply`](#0x3_collection_get_collection_current_supply) +- [Function `get_collection_maximum_supply`](#0x3_collection_get_collection_maximum_supply) + + +
use 0x1::option;
+use 0x1::string;
+use 0x2::context;
+use 0x2::event;
+use 0x2::object;
+use 0x2::object_ref;
+use 0x2::type_table;
+use 0x3::display;
+
+ + + + + +## Resource `Collection` + + + +
struct Collection has key
+
+ + + +
+Fields + + +
+
+name: string::String +
+
+ +
+
+uri: string::String +
+
+ +
+
+creator: address +
+
+ +
+
+supply: collection::Supply +
+
+ +
+
+extend: type_table::TypeTable +
+
+ +
+
+ + +
+ + + +## Struct `Supply` + + + +
struct Supply has store
+
+ + + +
+Fields + + +
+
+current: u64 +
+
+ +
+
+maximum: option::Option<u64> +
+
+ +
+
+ + +
+ + + +## Resource `MutatorRef` + + + +
struct MutatorRef has key
+
+ + + +
+Fields + + +
+
+collection: object::ObjectID +
+
+ +
+
+ + +
+ + + +## Struct `CreateCollectionEvent` + + + +
struct CreateCollectionEvent
+
+ + + +
+Fields + + +
+
+objectID: object::ObjectID +
+
+ +
+
+name: string::String +
+
+ +
+
+uri: string::String +
+
+ +
+
+creator: address +
+
+ +
+
+maximum: option::Option<u64> +
+
+ +
+
+description: string::String +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ECollectionMaximumSupply: u64 = 102;
+
+ + + + + + + +
const ECollectionNotExist: u64 = 101;
+
+ + + + + + + +
const EMutatorNotExist: u64 = 100;
+
+ + + + + +## Function `create_collection` + + + +
public fun create_collection(name: string::String, uri: string::String, creator: address, description: string::String, max_supply: option::Option<u64>, ctx: &mut context::Context): object_ref::ObjectRef<collection::Collection>
+
+ + + +
+Implementation + + +
public fun create_collection(
+    name: String,
+    uri: String,
+    creator: address,
+    description: String,
+    max_supply: Option<u64>,
+    ctx: &mut Context
+):ObjectRef<Collection> {
+
+    let collection = Collection {
+        name,
+        uri,
+        creator,
+        supply: Supply {
+            current: 0,
+            maximum: max_supply,
+        },
+        extend: type_table::new(ctx)
+    };
+
+    let object_ref = context::new_object_with_owner(
+        ctx,
+        creator,
+        collection
+    );
+
+    event::emit(
+        ctx,
+        CreateCollectionEvent {
+            objectID: object_ref::id(&object_ref),
+            name,
+            uri,
+            creator,
+            maximum: max_supply,
+            description,
+        }
+    );
+    object_ref
+}
+
+ + + +
+ + + +## Function `generate_mutator_ref` + + + +
public fun generate_mutator_ref(collection: &object_ref::ObjectRef<collection::Collection>, ctx: &mut context::Context): object_ref::ObjectRef<collection::MutatorRef>
+
+ + + +
+Implementation + + +
public fun generate_mutator_ref(collection: &ObjectRef<Collection>, ctx: &mut Context):ObjectRef<MutatorRef>{
+    let mutator_ref = context::new_object_with_owner(
+        ctx,
+        object_ref::owner(collection),
+        MutatorRef {
+            collection: object_ref::id(collection),
+        }
+    );
+    mutator_ref
+}
+
+ + + +
+ + + +## Function `destroy_mutator_ref` + + + +
public fun destroy_mutator_ref(mutator_ref: object_ref::ObjectRef<collection::MutatorRef>): object::ObjectID
+
+ + + +
+Implementation + + +
public fun destroy_mutator_ref(mutator_ref :ObjectRef<MutatorRef>):ObjectID{
+    assert_mutator_exist_of_ref(&mutator_ref);
+    let MutatorRef {
+        collection
+    } = object_ref::remove<MutatorRef>(mutator_ref);
+    collection
+}
+
+ + + +
+ + + +## Function `get_collection_id` + + + +
public fun get_collection_id(mutator: &object_ref::ObjectRef<collection::MutatorRef>): object::ObjectID
+
+ + + +
+Implementation + + +
public fun get_collection_id(mutator: &ObjectRef<MutatorRef>): ObjectID{
+    assert_mutator_exist_of_ref(mutator);
+    let mutator_object_ref = object_ref::borrow(mutator);
+    mutator_object_ref.collection
+}
+
+ + + +
+ + + +## Function `increment_supply` + + + +
public(friend) fun increment_supply(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): option::Option<u64>
+
+ + + +
+Implementation + + +
public(friend) fun increment_supply(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context): Option<u64>{
+    assert_mutator_exist_of_ref(mutator);
+    let mutator_object_ref = object_ref::borrow(mutator);
+    assert_collection_exist_of_id(mutator_object_ref.collection, ctx);
+    let collection_object_mut_ref = context::borrow_object_mut<Collection>(ctx, mutator_object_ref.collection);
+    let collection_mut_ref = object::borrow_mut(collection_object_mut_ref);
+    collection_mut_ref.supply.current = collection_mut_ref.supply.current + 1;
+    if(option::is_some(&collection_mut_ref.supply.maximum)){
+        assert!(collection_mut_ref.supply.current <= *option::borrow(&collection_mut_ref.supply.maximum), ECollectionMaximumSupply);
+        option::some(collection_mut_ref.supply.current)
+    }else{
+        option::none<u64>()
+    }
+}
+
+ + + +
+ + + +## Function `decrement_supply` + + + +
public(friend) fun decrement_supply(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): option::Option<u64>
+
+ + + +
+Implementation + + +
public (friend) fun decrement_supply(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context): Option<u64>{
+    assert_mutator_exist_of_ref(mutator);
+    let mutator_object_ref = object_ref::borrow(mutator);
+    assert_collection_exist_of_id(mutator_object_ref.collection, ctx);
+    let collection_object_mut_ref = context::borrow_object_mut<Collection>(ctx, mutator_object_ref.collection);
+    let collection_mut_ref = object::borrow_mut(collection_object_mut_ref);
+    collection_mut_ref.supply.current = collection_mut_ref.supply.current - 1;
+    if(option::is_some(&collection_mut_ref.supply.maximum)){
+        option::some(collection_mut_ref.supply.current)
+    }else{
+        option::none<u64>()
+    }
+}
+
+ + + +
+ + + +## Function `assert_collection_exist_of_ref` + + + +
public fun assert_collection_exist_of_ref(collectionRef: &object_ref::ObjectRef<collection::Collection>)
+
+ + + +
+Implementation + + +
public fun assert_collection_exist_of_ref(collectionRef: &ObjectRef<Collection>){
+    assert!( object_ref::exist_object(collectionRef), ECollectionNotExist);
+}
+
+ + + +
+ + + +## Function `assert_collection_exist_of_id` + + + +
public fun assert_collection_exist_of_id(collectionID: object::ObjectID, ctx: &context::Context)
+
+ + + +
+Implementation + + +
public fun assert_collection_exist_of_id(collectionID: ObjectID, ctx: & Context){
+    assert!( context::exist_object(ctx, collectionID), ECollectionNotExist);
+    context::borrow_object<Collection>(ctx,collectionID);
+}
+
+ + + +
+ + + +## Function `assert_mutator_exist_of_ref` + + + +
public fun assert_mutator_exist_of_ref(mutatorRef: &object_ref::ObjectRef<collection::MutatorRef>)
+
+ + + +
+Implementation + + +
public fun assert_mutator_exist_of_ref(mutatorRef: &ObjectRef<MutatorRef>){
+    assert!( object_ref::exist_object(mutatorRef), EMutatorNotExist);
+}
+
+ + + +
+ + + +## Function `assert_mutator_exist_of_id` + + + +
public fun assert_mutator_exist_of_id(mutatorID: object::ObjectID, ctx: &context::Context)
+
+ + + +
+Implementation + + +
public fun assert_mutator_exist_of_id(mutatorID: ObjectID, ctx: & Context){
+    assert!( context::exist_object(ctx, mutatorID), EMutatorNotExist);
+    context::borrow_object<MutatorRef>(ctx, mutatorID);
+}
+
+ + + +
+ + + +## Function `add_display` + + + +
public fun add_display(mutator: &object_ref::ObjectRef<collection::MutatorRef>, display: display::Display, ctx: &mut context::Context)
+
+ + + +
+Implementation + + +
public fun add_display(mutator: &ObjectRef<MutatorRef>, display: Display, ctx: &mut Context){
+    add_extend_internal(mutator, display, ctx);
+}
+
+ + + +
+ + + +## Function `borrow_display` + + + +
public fun borrow_display(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): &display::Display
+
+ + + +
+Implementation + + +
public fun borrow_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&Display{
+    borrow_extend_internal(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `borrow_mut_display` + + + +
public fun borrow_mut_display(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): &mut display::Display
+
+ + + +
+Implementation + + +
public fun borrow_mut_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&mut Display{
+    borrow_mut_extend_internal(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `remove_display` + + + +
public fun remove_display(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): display::Display
+
+ + + +
+Implementation + + +
public fun remove_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):Display{
+    remove_extend_internal(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `contains_display` + + + +
public fun contains_display(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): bool
+
+ + + +
+Implementation + + +
public fun contains_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context): bool{
+    contains_extend_internal<Display>(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `add_extend` + + + +
public fun add_extend<V: key>(mutator: &object_ref::ObjectRef<collection::MutatorRef>, val: V, ctx: &mut context::Context)
+
+ + + +
+Implementation + + +
public fun add_extend<V: key>(mutator: &ObjectRef<MutatorRef>, val: V, ctx: &mut Context){
+    add_extend_internal(mutator, val, ctx);
+}
+
+ + + +
+ + + +## Function `borrow_extend` + + + +
public fun borrow_extend<V: key>(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): &V
+
+ + + +
+Implementation + + +
public fun borrow_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&V{
+    borrow_extend_internal(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `borrow_mut_extend` + + + +
public fun borrow_mut_extend<V: key>(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): &mut V
+
+ + + +
+Implementation + + +
public fun borrow_mut_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&mut V{
+    borrow_mut_extend_internal(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `remove_extend` + + + +
public fun remove_extend<V: key>(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): V
+
+ + + +
+Implementation + + +
public fun remove_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):V{
+    remove_extend_internal(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `contains_extend` + + + +
public fun contains_extend<V: key>(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): bool
+
+ + + +
+Implementation + + +
public fun contains_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context): bool{
+    contains_extend_internal<V>(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `get_collection_name` + + + +
public fun get_collection_name(collectionID: object::ObjectID, ctx: &mut context::Context): string::String
+
+ + + +
+Implementation + + +
public fun get_collection_name(collectionID: ObjectID, ctx: &mut Context): String{
+    assert_collection_exist_of_id(collectionID, ctx);
+    let collection_object_ref = context::borrow_object<Collection>(ctx, collectionID);
+    let collection_ref = object::borrow(collection_object_ref);
+    collection_ref.name
+}
+
+ + + +
+ + + +## Function `get_collection_uri` + + + +
public fun get_collection_uri(collectionID: object::ObjectID, ctx: &mut context::Context): string::String
+
+ + + +
+Implementation + + +
public fun get_collection_uri(collectionID: ObjectID, ctx: &mut Context): String{
+    assert_collection_exist_of_id(collectionID, ctx);
+    let collection_object_ref = context::borrow_object<Collection>(ctx, collectionID);
+    let collection_ref = object::borrow(collection_object_ref);
+    collection_ref.uri
+}
+
+ + + +
+ + + +## Function `get_collection_creator` + + + +
public fun get_collection_creator(collectionID: object::ObjectID, ctx: &mut context::Context): address
+
+ + + +
+Implementation + + +
public fun get_collection_creator(collectionID: ObjectID, ctx: &mut Context): address{
+    assert_collection_exist_of_id(collectionID, ctx);
+    let collection_object_ref = context::borrow_object<Collection>(ctx, collectionID);
+    let collection_ref = object::borrow(collection_object_ref);
+    collection_ref.creator
+}
+
+ + + +
+ + + +## Function `get_collection_current_supply` + + + +
public fun get_collection_current_supply(collectionID: object::ObjectID, ctx: &mut context::Context): u64
+
+ + + +
+Implementation + + +
public fun get_collection_current_supply(collectionID: ObjectID, ctx: &mut Context): u64{
+    assert_collection_exist_of_id(collectionID, ctx);
+    let collection_object_ref = context::borrow_object<Collection>(ctx, collectionID);
+    let collection_ref = object::borrow(collection_object_ref);
+    collection_ref.supply.current
+}
+
+ + + +
+ + + +## Function `get_collection_maximum_supply` + + + +
public fun get_collection_maximum_supply(collectionID: object::ObjectID, ctx: &mut context::Context): option::Option<u64>
+
+ + + +
+Implementation + + +
public fun get_collection_maximum_supply(collectionID: ObjectID, ctx: &mut Context): Option<u64>{
+    assert_collection_exist_of_id(collectionID, ctx);
+    let collection_object_ref = context::borrow_object<Collection>(ctx, collectionID);
+    let collection_ref = object::borrow(collection_object_ref);
+    collection_ref.supply.maximum
+}
+
+ + + +
diff --git a/crates/rooch-framework/doc/display.md b/crates/rooch-framework/doc/display.md new file mode 100644 index 0000000000..4355b31c96 --- /dev/null +++ b/crates/rooch-framework/doc/display.md @@ -0,0 +1,244 @@ + + + +# Module `0x3::display` + + + +- [Resource `Display`](#0x3_display_Display) +- [Function `new`](#0x3_display_new) +- [Function `set`](#0x3_display_set) +- [Function `borrow`](#0x3_display_borrow) +- [Function `borrow_mut`](#0x3_display_borrow_mut) +- [Function `remove`](#0x3_display_remove) +- [Function `keys`](#0x3_display_keys) +- [Function `values`](#0x3_display_values) +- [Function `contains_key`](#0x3_display_contains_key) + + +
use 0x1::string;
+use 0x2::simple_map;
+
+ + + + + +## Resource `Display` + + + +
struct Display has copy, drop, store, key
+
+ + + +
+Fields + + +
+
+sample_map: simple_map::SimpleMap<string::String, string::String> +
+
+ +
+
+ + +
+ + + +## Function `new` + + + +
public fun new(): display::Display
+
+ + + +
+Implementation + + +
public fun new (): Display {
+    Display {
+        sample_map: simple_map::create()
+    }
+}
+
+ + + +
+ + + +## Function `set` + + + +
public fun set(self: &mut display::Display, key: string::String, value: string::String)
+
+ + + +
+Implementation + + +
public fun set (self: &mut Display, key: String, value: String) {
+    simple_map::add(&mut self.sample_map, key, value);
+}
+
+ + + +
+ + + +## Function `borrow` + + + +
public fun borrow(self: &display::Display, key: &string::String): &string::String
+
+ + + +
+Implementation + + +
public fun borrow (self: &Display, key: &String): &String {
+    simple_map::borrow(&self.sample_map, key)
+}
+
+ + + +
+ + + +## Function `borrow_mut` + + + +
public fun borrow_mut(self: &mut display::Display, key: &string::String): &mut string::String
+
+ + + +
+Implementation + + +
public fun borrow_mut (self: &mut Display, key: &String): &mut String {
+    simple_map::borrow_mut(&mut self.sample_map, key)
+}
+
+ + + +
+ + + +## Function `remove` + + + +
public fun remove(self: &mut display::Display, key: &string::String)
+
+ + + +
+Implementation + + +
public fun remove (self: &mut Display, key: &String) {
+    simple_map::remove(&mut self.sample_map, key);
+}
+
+ + + +
+ + + +## Function `keys` + + + +
public fun keys(self: &display::Display): vector<string::String>
+
+ + + +
+Implementation + + +
public fun keys (self: & Display): vector<String> {
+    simple_map::keys(& self.sample_map)
+}
+
+ + + +
+ + + +## Function `values` + + + +
public fun values(self: &display::Display): vector<string::String>
+
+ + + +
+Implementation + + +
public fun values (self: & Display): vector<String> {
+    simple_map::values(& self.sample_map)
+}
+
+ + + +
+ + + +## Function `contains_key` + + + +
public fun contains_key(self: &display::Display, key: &string::String): bool
+
+ + + +
+Implementation + + +
public fun contains_key (self: & Display, key: &String): bool {
+    simple_map::contains_key(& self.sample_map, key)
+}
+
+ + + +
diff --git a/crates/rooch-framework/doc/nft.md b/crates/rooch-framework/doc/nft.md new file mode 100644 index 0000000000..2adb2a5602 --- /dev/null +++ b/crates/rooch-framework/doc/nft.md @@ -0,0 +1,882 @@ + + + +# Module `0x3::nft` + + + +- [Resource `NFT`](#0x3_nft_NFT) +- [Resource `MutatorRef`](#0x3_nft_MutatorRef) +- [Resource `BurnerRef`](#0x3_nft_BurnerRef) +- [Constants](#@Constants_0) +- [Function `mint`](#0x3_nft_mint) +- [Function `burn`](#0x3_nft_burn) +- [Function `generate_mutator_ref`](#0x3_nft_generate_mutator_ref) +- [Function `destroy_mutator_ref`](#0x3_nft_destroy_mutator_ref) +- [Function `generate_burner_ref`](#0x3_nft_generate_burner_ref) +- [Function `destroy_burner_ref`](#0x3_nft_destroy_burner_ref) +- [Function `assert_nft_exist_of_id`](#0x3_nft_assert_nft_exist_of_id) +- [Function `assert_nft_exist_of_ref`](#0x3_nft_assert_nft_exist_of_ref) +- [Function `assert_mutator_exist_of_ref`](#0x3_nft_assert_mutator_exist_of_ref) +- [Function `assert_mutator_exist_of_id`](#0x3_nft_assert_mutator_exist_of_id) +- [Function `assert_burner_exist_of_ref`](#0x3_nft_assert_burner_exist_of_ref) +- [Function `assert_burner_exist_of_id`](#0x3_nft_assert_burner_exist_of_id) +- [Function `add_display`](#0x3_nft_add_display) +- [Function `borrow_display`](#0x3_nft_borrow_display) +- [Function `borrow_mut_display`](#0x3_nft_borrow_mut_display) +- [Function `remove_display`](#0x3_nft_remove_display) +- [Function `contains_display`](#0x3_nft_contains_display) +- [Function `add_extend`](#0x3_nft_add_extend) +- [Function `borrow_extend`](#0x3_nft_borrow_extend) +- [Function `borrow_mut_extend`](#0x3_nft_borrow_mut_extend) +- [Function `remove_extend`](#0x3_nft_remove_extend) +- [Function `contains_extend`](#0x3_nft_contains_extend) +- [Function `get_name`](#0x3_nft_get_name) +- [Function `get_uri`](#0x3_nft_get_uri) +- [Function `get_collection`](#0x3_nft_get_collection) +- [Function `get_creator`](#0x3_nft_get_creator) + + +
use 0x1::option;
+use 0x1::string;
+use 0x2::context;
+use 0x2::object;
+use 0x2::object_ref;
+use 0x2::type_table;
+use 0x3::collection;
+use 0x3::display;
+
+ + + + + +## Resource `NFT` + + + +
struct NFT has key
+
+ + + +
+Fields + + +
+
+name: string::String +
+
+ +
+
+uri: string::String +
+
+ +
+
+collection: object::ObjectID +
+
+ +
+
+creator: address +
+
+ +
+
+extend: type_table::TypeTable +
+
+ +
+
+ + +
+ + + +## Resource `MutatorRef` + + + +
struct MutatorRef has key
+
+ + + +
+Fields + + +
+
+nft: object::ObjectID +
+
+ +
+
+ + +
+ + + +## Resource `BurnerRef` + + + +
struct BurnerRef has key
+
+ + + +
+Fields + + +
+
+nft: object::ObjectID +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const EMutatorNotExist: u64 = 101;
+
+ + + + + + + +
const ENftNotExist: u64 = 100;
+
+ + + + + +## Function `mint` + + + +
public fun mint(name: string::String, uri: string::String, mutator_ref: &object_ref::ObjectRef<collection::MutatorRef>, creator: address, ctx: &mut context::Context): object_ref::ObjectRef<nft::NFT>
+
+ + + +
+Implementation + + +
public fun mint(
+    name: String,
+    uri: String,
+    mutator_ref: &ObjectRef<collection::MutatorRef>,
+    creator: address,
+    ctx: &mut Context
+): ObjectRef<NFT> {
+    collection::assert_mutator_exist_of_ref(mutator_ref);
+    let nft = NFT {
+        name,
+        uri,
+        collection: collection::get_collection_id(mutator_ref),
+        creator,
+        extend: type_table::new(ctx)
+    };
+
+    collection::increment_supply(mutator_ref, ctx);
+
+    let object_ref = context::new_object_with_owner(
+        ctx,
+        creator,
+        nft
+    );
+
+    object_ref
+}
+
+ + + +
+ + + +## Function `burn` + + + +
public fun burn(burn_ref: &object_ref::ObjectRef<nft::BurnerRef>, mutator_ref: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context)
+
+ + + +
+Implementation + + +
public fun burn (
+    burn_ref: &ObjectRef<BurnerRef>,
+    mutator_ref: &ObjectRef<collection::MutatorRef>,
+    ctx: &mut Context
+) {
+    assert_burner_exist_of_ref(burn_ref);
+    let burner_object_ref = object_ref::borrow(burn_ref);
+    assert_burner_exist_of_id(burner_object_ref.nft, ctx);
+    // let nft_object_mut_ref = context::borrow_object_mut<NFT>(ctx, burner_object_ref.nft);
+    collection::decrement_supply(mutator_ref, ctx);
+    let (
+        _,
+        _,
+        NFT {
+            name:_,
+            uri:_,
+            collection:_,
+            creator:_,
+            extend
+        }
+    ) = context::remove_object<NFT>(ctx, burner_object_ref.nft);
+    type_table::destroy_empty(extend)
+}
+
+ + + +
+ + + +## Function `generate_mutator_ref` + + + +
public fun generate_mutator_ref(nft_object_ref: &object_ref::ObjectRef<nft::NFT>, ctx: &mut context::Context): object_ref::ObjectRef<nft::MutatorRef>
+
+ + + +
+Implementation + + +
public fun generate_mutator_ref(nft_object_ref: &ObjectRef<NFT>, ctx: &mut Context):ObjectRef<MutatorRef>{
+    let mutator_ref = context::new_object_with_owner(
+        ctx,
+        object_ref::owner(nft_object_ref),
+        MutatorRef {
+            nft: object_ref::id(nft_object_ref),
+        }
+    );
+    mutator_ref
+}
+
+ + + +
+ + + +## Function `destroy_mutator_ref` + + + +
public fun destroy_mutator_ref(mutator_ref: object_ref::ObjectRef<nft::MutatorRef>): object::ObjectID
+
+ + + +
+Implementation + + +
public fun destroy_mutator_ref(mutator_ref :ObjectRef<MutatorRef>):ObjectID{
+    assert_mutator_exist_of_ref(&mutator_ref);
+    let MutatorRef {
+        nft
+    } = object_ref::remove<MutatorRef>(mutator_ref);
+    nft
+}
+
+ + + +
+ + + +## Function `generate_burner_ref` + + + +
public fun generate_burner_ref(nft_object_ref: &object_ref::ObjectRef<nft::NFT>, ctx: &mut context::Context): object_ref::ObjectRef<nft::BurnerRef>
+
+ + + +
+Implementation + + +
public fun generate_burner_ref(nft_object_ref: &ObjectRef<NFT>, ctx: &mut Context):ObjectRef<BurnerRef>{
+    let burner_ref = context::new_object_with_owner(
+        ctx,
+        object_ref::owner(nft_object_ref),
+        BurnerRef {
+            nft: object_ref::id(nft_object_ref),
+        }
+    );
+    burner_ref
+}
+
+ + + +
+ + + +## Function `destroy_burner_ref` + + + +
public fun destroy_burner_ref(burner_ref: object_ref::ObjectRef<nft::BurnerRef>): object::ObjectID
+
+ + + +
+Implementation + + +
public fun destroy_burner_ref(burner_ref :ObjectRef<BurnerRef>):ObjectID{
+    assert_burner_exist_of_ref(&burner_ref);
+    let BurnerRef {
+        nft
+    } = object_ref::remove<BurnerRef>(burner_ref);
+    nft
+}
+
+ + + +
+ + + +## Function `assert_nft_exist_of_id` + + + +
public fun assert_nft_exist_of_id(objectId: object::ObjectID, ctx: &context::Context)
+
+ + + +
+Implementation + + +
public fun assert_nft_exist_of_id(objectId: ObjectID, ctx: &Context) {
+    assert!(context::exist_object(ctx, objectId), ENftNotExist);
+    context::borrow_object<NFT>(ctx, objectId);
+}
+
+ + + +
+ + + +## Function `assert_nft_exist_of_ref` + + + +
public fun assert_nft_exist_of_ref(nft_object_ref: &object_ref::ObjectRef<nft::NFT>)
+
+ + + +
+Implementation + + +
public fun assert_nft_exist_of_ref(nft_object_ref: &ObjectRef<NFT>) {
+    assert!(object_ref::exist_object(nft_object_ref), ENftNotExist);
+}
+
+ + + +
+ + + +## Function `assert_mutator_exist_of_ref` + + + +
public fun assert_mutator_exist_of_ref(mutator_ref: &object_ref::ObjectRef<nft::MutatorRef>)
+
+ + + +
+Implementation + + +
public fun assert_mutator_exist_of_ref(mutator_ref: &ObjectRef<MutatorRef>) {
+    assert!(object_ref::exist_object(mutator_ref), EMutatorNotExist);
+}
+
+ + + +
+ + + +## Function `assert_mutator_exist_of_id` + + + +
public fun assert_mutator_exist_of_id(objectId: object::ObjectID, ctx: &context::Context)
+
+ + + +
+Implementation + + +
public fun assert_mutator_exist_of_id(objectId: ObjectID, ctx: &Context) {
+    assert!(context::exist_object(ctx, objectId), EMutatorNotExist);
+    context::borrow_object<MutatorRef>(ctx, objectId);
+}
+
+ + + +
+ + + +## Function `assert_burner_exist_of_ref` + + + +
public fun assert_burner_exist_of_ref(burner_ref: &object_ref::ObjectRef<nft::BurnerRef>)
+
+ + + +
+Implementation + + +
public fun assert_burner_exist_of_ref(burner_ref: &ObjectRef<BurnerRef>) {
+    assert!(object_ref::exist_object(burner_ref), EMutatorNotExist);
+}
+
+ + + +
+ + + +## Function `assert_burner_exist_of_id` + + + +
public fun assert_burner_exist_of_id(objectId: object::ObjectID, ctx: &context::Context)
+
+ + + +
+Implementation + + +
public fun assert_burner_exist_of_id(objectId: ObjectID, ctx: &Context) {
+    assert!(context::exist_object(ctx, objectId), EMutatorNotExist);
+    context::borrow_object<BurnerRef>(ctx, objectId);
+}
+
+ + + +
+ + + +## Function `add_display` + + + +
public fun add_display(mutator: &object_ref::ObjectRef<nft::MutatorRef>, display: display::Display, ctx: &mut context::Context)
+
+ + + +
+Implementation + + +
public fun add_display(mutator: &ObjectRef<MutatorRef>, display: Display, ctx: &mut Context){
+    add_extend_internal(mutator, display, ctx);
+}
+
+ + + +
+ + + +## Function `borrow_display` + + + +
public fun borrow_display(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): &display::Display
+
+ + + +
+Implementation + + +
public fun borrow_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&Display{
+    borrow_extend_internal(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `borrow_mut_display` + + + +
public fun borrow_mut_display(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): &mut display::Display
+
+ + + +
+Implementation + + +
public fun borrow_mut_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&mut Display{
+    borrow_mut_extend_internal(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `remove_display` + + + +
public fun remove_display(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): display::Display
+
+ + + +
+Implementation + + +
public fun remove_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):Display{
+    remove_extend_internal(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `contains_display` + + + +
public fun contains_display(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): bool
+
+ + + +
+Implementation + + +
public fun contains_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context): bool{
+    contains_extend_internal<Display>(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `add_extend` + + + +
public fun add_extend<V: key>(mutator: &object_ref::ObjectRef<nft::MutatorRef>, val: V, ctx: &mut context::Context)
+
+ + + +
+Implementation + + +
public fun add_extend<V: key>(mutator: &ObjectRef<MutatorRef>, val: V, ctx: &mut Context){
+    add_extend_internal(mutator, val, ctx);
+}
+
+ + + +
+ + + +## Function `borrow_extend` + + + +
public fun borrow_extend<V: key>(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): &V
+
+ + + +
+Implementation + + +
public fun borrow_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&V{
+    borrow_extend_internal(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `borrow_mut_extend` + + + +
public fun borrow_mut_extend<V: key>(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): &mut V
+
+ + + +
+Implementation + + +
public fun borrow_mut_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&mut V{
+    borrow_mut_extend_internal(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `remove_extend` + + + +
public fun remove_extend<V: key>(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): V
+
+ + + +
+Implementation + + +
public fun remove_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):V{
+    remove_extend_internal(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `contains_extend` + + + +
public fun contains_extend<V: key>(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): bool
+
+ + + +
+Implementation + + +
public fun contains_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context): bool{
+    contains_extend_internal<V>(mutator, ctx)
+}
+
+ + + +
+ + + +## Function `get_name` + + + +
public fun get_name(objectId: object::ObjectID, ctx: &context::Context): string::String
+
+ + + +
+Implementation + + +
public fun get_name(objectId: ObjectID, ctx: &Context): String {
+    assert_nft_exist_of_id(objectId, ctx);
+    let nft_object_ref = context::borrow_object<NFT>(ctx, objectId);
+    let nft = object::borrow(nft_object_ref);
+    nft.name
+}
+
+ + + +
+ + + +## Function `get_uri` + + + +
public fun get_uri(objectId: object::ObjectID, ctx: &context::Context): string::String
+
+ + + +
+Implementation + + +
public fun get_uri(objectId: ObjectID, ctx: &Context): String {
+    assert_nft_exist_of_id(objectId, ctx);
+    let nft_object_ref = context::borrow_object<NFT>(ctx, objectId);
+    let nft = object::borrow(nft_object_ref);
+    nft.uri
+}
+
+ + + +
+ + + +## Function `get_collection` + + + +
public fun get_collection(objectId: object::ObjectID, ctx: &context::Context): object::ObjectID
+
+ + + +
+Implementation + + +
public fun get_collection(objectId: ObjectID, ctx: &Context): ObjectID {
+    assert_nft_exist_of_id(objectId, ctx);
+    let nft_object_ref = context::borrow_object<NFT>(ctx, objectId);
+    let nft = object::borrow(nft_object_ref);
+    nft.collection
+}
+
+ + + +
+ + + +## Function `get_creator` + + + +
public fun get_creator(objectId: object::ObjectID, ctx: &context::Context): address
+
+ + + +
+Implementation + + +
public fun get_creator(objectId: ObjectID, ctx: &Context): address {
+    assert_nft_exist_of_id(objectId, ctx);
+    let nft_object_ref = context::borrow_object<NFT>(ctx, objectId);
+    let nft = object::borrow(nft_object_ref);
+    nft.creator
+}
+
+ + + +
diff --git a/crates/rooch-framework/sources/nft/collection.move b/crates/rooch-framework/sources/nft/collection.move index 793989a8e7..b865c0b6eb 100644 --- a/crates/rooch-framework/sources/nft/collection.move +++ b/crates/rooch-framework/sources/nft/collection.move @@ -5,6 +5,7 @@ module rooch_framework::collection{ use std::option; use std::option::Option; use std::string::String; + use rooch_framework::display::Display; use moveos_std::object::ObjectID; use moveos_std::object_ref; use moveos_std::event; @@ -20,7 +21,7 @@ module rooch_framework::collection{ const ECollectionNotExist: u64 = 101; const ECollectionMaximumSupply: u64 = 102; - struct Collection has store{ + struct Collection has key{ name: String, uri: String, creator: address, @@ -33,7 +34,7 @@ module rooch_framework::collection{ maximum: Option, } - struct MutatorRef has store{ + struct MutatorRef has key{ collection: ObjectID, } @@ -103,7 +104,7 @@ module rooch_framework::collection{ assert_mutator_exist_of_ref(&mutator_ref); let MutatorRef { collection - } = object_ref::remove(mutator_ref); + } = object_ref::remove(mutator_ref); collection } @@ -162,9 +163,53 @@ module rooch_framework::collection{ context::borrow_object(ctx, mutatorID); } - #[private_generics(T)] - public fun add_collection_extend(mutator: &ObjectRef,val: V,ctx: &mut Context){ + public fun add_display(mutator: &ObjectRef, display: Display, ctx: &mut Context){ + add_extend_internal(mutator, display, ctx); + } + + public fun borrow_display(mutator: &ObjectRef, ctx: &mut Context):&Display{ + borrow_extend_internal(mutator, ctx) + } + + public fun borrow_mut_display(mutator: &ObjectRef, ctx: &mut Context):&mut Display{ + borrow_mut_extend_internal(mutator, ctx) + } + + public fun remove_display(mutator: &ObjectRef, ctx: &mut Context):Display{ + remove_extend_internal(mutator, ctx) + } + + public fun contains_display(mutator: &ObjectRef, ctx: &mut Context): bool{ + contains_extend_internal(mutator, ctx) + } + + #[private_generics(V)] + public fun add_extend(mutator: &ObjectRef, val: V, ctx: &mut Context){ + add_extend_internal(mutator, val, ctx); + } + + public fun borrow_extend(mutator: &ObjectRef, ctx: &mut Context):&V{ + borrow_extend_internal(mutator, ctx) + } + + #[private_generics(V)] + public fun borrow_mut_extend(mutator: &ObjectRef, ctx: &mut Context):&mut V{ + borrow_mut_extend_internal(mutator, ctx) + } + + #[private_generics(V)] + public fun remove_extend(mutator: &ObjectRef, ctx: &mut Context):V{ + remove_extend_internal(mutator, ctx) + } + + public fun contains_extend(mutator: &ObjectRef, ctx: &mut Context): bool{ + contains_extend_internal(mutator, ctx) + } + + + fun add_extend_internal(mutator: &ObjectRef,val: V,ctx: &mut Context){ assert_mutator_exist_of_ref(mutator); + let mutator_object_ref = object_ref::borrow(mutator); assert_collection_exist_of_id(mutator_object_ref.collection, ctx); let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); @@ -172,7 +217,7 @@ module rooch_framework::collection{ type_table::add( &mut collection_mut_ref.extend, val); } - public fun borrow_collection_extend(mutator: &ObjectRef, ctx: &mut Context):&V{ + fun borrow_extend_internal(mutator: &ObjectRef, ctx: &mut Context):&V{ assert_mutator_exist_of_ref(mutator); let mutator_object_ref = object_ref::borrow(mutator); assert_collection_exist_of_id(mutator_object_ref.collection, ctx); @@ -181,8 +226,7 @@ module rooch_framework::collection{ type_table::borrow(&collection_ref.extend) } - #[private_generics(T)] - public fun borrow_mut_collection_extend(mutator: &ObjectRef, ctx: &mut Context):&mut V{ + fun borrow_mut_extend_internal(mutator: &ObjectRef, ctx: &mut Context):&mut V{ assert_mutator_exist_of_ref(mutator); let mutator_object_ref = object_ref::borrow(mutator); assert_collection_exist_of_id(mutator_object_ref.collection, ctx); @@ -191,17 +235,16 @@ module rooch_framework::collection{ type_table::borrow_mut(&mut collection_mut_ref.extend) } - #[private_generics(T)] - public fun remove_collection_extend(mutator: &ObjectRef, ctx: &mut Context){ + fun remove_extend_internal(mutator: &ObjectRef, ctx: &mut Context):V{ assert_mutator_exist_of_ref(mutator); let mutator_object_ref = object_ref::borrow(mutator); assert_collection_exist_of_id(mutator_object_ref.collection, ctx); let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); - type_table::remove(&mut collection_mut_ref.extend) + type_table::remove(&mut collection_mut_ref.extend) } - public fun contains_collection_extend(mutator: &ObjectRef, ctx: &mut Context): bool{ + fun contains_extend_internal(mutator: &ObjectRef, ctx: &mut Context): bool{ assert_mutator_exist_of_ref(mutator); let mutator_object_ref = object_ref::borrow(mutator); assert_collection_exist_of_id(mutator_object_ref.collection, ctx); diff --git a/crates/rooch-framework/sources/nft/display.move b/crates/rooch-framework/sources/nft/display.move index 869ba76895..276673745d 100644 --- a/crates/rooch-framework/sources/nft/display.move +++ b/crates/rooch-framework/sources/nft/display.move @@ -16,16 +16,16 @@ module rooch_framework::display{ simple_map::add(&mut self.sample_map, key, value); } - public fun borrow (self: & Display, key: String): &String { - simple_map::borrow(&mut self.sample_map, &key) + public fun borrow (self: &Display, key: &String): &String { + simple_map::borrow(&self.sample_map, key) } - public fun borrow_mut (self: &mut Display, key: String): &mut String { - simple_map::borrow_mut(&mut self.sample_map, &key) + public fun borrow_mut (self: &mut Display, key: &String): &mut String { + simple_map::borrow_mut(&mut self.sample_map, key) } - public fun remove (self: &mut Display, key: String) { - simple_map::remove(&mut self.sample_map, &key); + public fun remove (self: &mut Display, key: &String) { + simple_map::remove(&mut self.sample_map, key); } public fun keys (self: & Display): vector { @@ -36,7 +36,8 @@ module rooch_framework::display{ simple_map::values(& self.sample_map) } - public fun contains_key (self: & Display, key: String): bool { - simple_map::contains_key(& self.sample_map, &key) + public fun contains_key (self: & Display, key: &String): bool { + simple_map::contains_key(& self.sample_map, key) } + } \ No newline at end of file diff --git a/crates/rooch-framework/sources/nft/nft.move b/crates/rooch-framework/sources/nft/nft.move index 864bd29b2f..e67c7218d4 100644 --- a/crates/rooch-framework/sources/nft/nft.move +++ b/crates/rooch-framework/sources/nft/nft.move @@ -3,6 +3,7 @@ module rooch_framework::nft { use std::string::String; + use rooch_framework::display::Display; use moveos_std::object_ref; use moveos_std::object; use rooch_framework::collection; @@ -22,7 +23,7 @@ module rooch_framework::nft { const ENftNotExist: u64 = 100; const EMutatorNotExist: u64 = 101; - struct NFT has store { + struct NFT has key { name: String, uri: String, collection: ObjectID, @@ -30,11 +31,11 @@ module rooch_framework::nft { extend: TypeTable } - struct MutatorRef has store{ + struct MutatorRef has key { nft: ObjectID, } - struct BurnerRef has store{ + struct BurnerRef has key { nft: ObjectID, } @@ -104,7 +105,7 @@ module rooch_framework::nft { assert_mutator_exist_of_ref(&mutator_ref); let MutatorRef { nft - } = object_ref::remove(mutator_ref); + } = object_ref::remove(mutator_ref); nft } @@ -123,7 +124,7 @@ module rooch_framework::nft { assert_burner_exist_of_ref(&burner_ref); let BurnerRef { nft - } = object_ref::remove(burner_ref); + } = object_ref::remove(burner_ref); nft } @@ -155,8 +156,51 @@ module rooch_framework::nft { context::borrow_object(ctx, objectId); } - #[private_generics(T)] - public fun add_nft_extend(mutator: &ObjectRef,val: V,ctx: &mut Context) { + public fun add_display(mutator: &ObjectRef, display: Display, ctx: &mut Context){ + add_extend_internal(mutator, display, ctx); + } + + public fun borrow_display(mutator: &ObjectRef, ctx: &mut Context):&Display{ + borrow_extend_internal(mutator, ctx) + } + + public fun borrow_mut_display(mutator: &ObjectRef, ctx: &mut Context):&mut Display{ + borrow_mut_extend_internal(mutator, ctx) + } + + public fun remove_display(mutator: &ObjectRef, ctx: &mut Context):Display{ + remove_extend_internal(mutator, ctx) + } + + public fun contains_display(mutator: &ObjectRef, ctx: &mut Context): bool{ + contains_extend_internal(mutator, ctx) + } + + #[private_generics(V)] + public fun add_extend(mutator: &ObjectRef, val: V, ctx: &mut Context){ + add_extend_internal(mutator, val, ctx); + } + + public fun borrow_extend(mutator: &ObjectRef, ctx: &mut Context):&V{ + borrow_extend_internal(mutator, ctx) + } + + #[private_generics(V)] + public fun borrow_mut_extend(mutator: &ObjectRef, ctx: &mut Context):&mut V{ + borrow_mut_extend_internal(mutator, ctx) + } + + #[private_generics(V)] + public fun remove_extend(mutator: &ObjectRef, ctx: &mut Context):V{ + remove_extend_internal(mutator, ctx) + } + + public fun contains_extend(mutator: &ObjectRef, ctx: &mut Context): bool{ + contains_extend_internal(mutator, ctx) + } + + + fun add_extend_internal(mutator: &ObjectRef,val: V,ctx: &mut Context) { assert_mutator_exist_of_ref(mutator); let mutator_object_ref = object_ref::borrow(mutator); assert_nft_exist_of_id(mutator_object_ref.nft, ctx); @@ -165,8 +209,7 @@ module rooch_framework::nft { type_table::add( &mut nft_mut_ref.extend, val); } - - public fun borrow_nft_extend(mutator: &ObjectRef,ctx: &Context): &V { + fun borrow_extend_internal(mutator: &ObjectRef,ctx: &Context): &V { assert_mutator_exist_of_ref(mutator); let mutator_object_ref = object_ref::borrow(mutator); assert_nft_exist_of_id(mutator_object_ref.nft, ctx); @@ -175,8 +218,7 @@ module rooch_framework::nft { type_table::borrow(&nft_mut_ref.extend) } - #[private_generics(T)] - public fun borrow_mut_nft_extend(mutator: &ObjectRef,ctx: &mut Context): &mut V { + fun borrow_mut_extend_internal(mutator: &ObjectRef,ctx: &mut Context): &mut V { assert_mutator_exist_of_ref(mutator); let mutator_object_ref = object_ref::borrow(mutator); assert_nft_exist_of_id(mutator_object_ref.nft, ctx); @@ -185,17 +227,16 @@ module rooch_framework::nft { type_table::borrow_mut(&mut nft_mut_ref.extend) } - #[private_generics(T)] - public fun remove_nft_extend(mutator: &ObjectRef,ctx: &mut Context) { + fun remove_extend_internal(mutator: &ObjectRef,ctx: &mut Context):V { assert_mutator_exist_of_ref(mutator); let mutator_object_ref = object_ref::borrow(mutator); assert_nft_exist_of_id(mutator_object_ref.nft, ctx); let nft_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.nft); let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); - type_table::remove(&mut nft_mut_ref.extend) + type_table::remove(&mut nft_mut_ref.extend) } - public fun contains_nft_extend(mutator: &ObjectRef,ctx: &Context): bool { + fun contains_extend_internal(mutator: &ObjectRef,ctx: &Context): bool { assert_mutator_exist_of_ref(mutator); let mutator_object_ref = object_ref::borrow(mutator); assert_nft_exist_of_id(mutator_object_ref.nft, ctx); @@ -254,9 +295,11 @@ module rooch_framework::nft { display::set(&mut collcetion_display, string::utf8(b"description"), string::utf8(b"{ description }")); display::set(&mut collcetion_display, string::utf8(b"creator"), string::utf8(b"{ creator }")); display::set(&mut collcetion_display, string::utf8(b"supply"), string::utf8(b"{ supply }")); - collection::add_collection_extend( + + collection::add_display( &collection_mutator_ref, - collcetion_display, &mut ctx + collcetion_display, + &mut ctx ); let nft_object_ref = mint( @@ -273,12 +316,21 @@ module rooch_framework::nft { display::set(&mut nft_display, string::utf8(b"collection"), string::utf8(b"{ collection }")); let nft_mutaor_ref = generate_mutator_ref(&nft_object_ref, &mut ctx); - add_nft_extend( + add_display( &nft_mutaor_ref, nft_display, &mut ctx ); + + let burner_ref = generate_burner_ref(&nft_object_ref, &mut ctx); + burn(&burner_ref, &collection_mutator_ref, &mut ctx); + + + collection::destroy_mutator_ref(collection_mutator_ref); + destroy_mutator_ref(nft_mutaor_ref); + destroy_burner_ref(burner_ref); + context::drop_test_context(ctx); } From d5d27bcb77f3f8ffeecf1868e280b63eb651e171 Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Mon, 16 Oct 2023 17:46:59 +0800 Subject: [PATCH 11/17] Fix unit test --- crates/rooch-framework/sources/nft/collection.move | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/rooch-framework/sources/nft/collection.move b/crates/rooch-framework/sources/nft/collection.move index b865c0b6eb..5248a5128a 100644 --- a/crates/rooch-framework/sources/nft/collection.move +++ b/crates/rooch-framework/sources/nft/collection.move @@ -209,7 +209,6 @@ module rooch_framework::collection{ fun add_extend_internal(mutator: &ObjectRef,val: V,ctx: &mut Context){ assert_mutator_exist_of_ref(mutator); - let mutator_object_ref = object_ref::borrow(mutator); assert_collection_exist_of_id(mutator_object_ref.collection, ctx); let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); From b4d174432cc59d02611591fe5b91755a9cd68de3 Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Mon, 16 Oct 2023 23:59:06 +0800 Subject: [PATCH 12/17] Fix unit test --- crates/rooch-framework/doc/nft.md | 6 ++-- crates/rooch-framework/sources/nft/nft.move | 36 +++++++++++++-------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/crates/rooch-framework/doc/nft.md b/crates/rooch-framework/doc/nft.md index 2adb2a5602..914135c63e 100644 --- a/crates/rooch-framework/doc/nft.md +++ b/crates/rooch-framework/doc/nft.md @@ -246,8 +246,7 @@ ) { assert_burner_exist_of_ref(burn_ref); let burner_object_ref = object_ref::borrow(burn_ref); - assert_burner_exist_of_id(burner_object_ref.nft, ctx); - // let nft_object_mut_ref = context::borrow_object_mut<NFT>(ctx, burner_object_ref.nft); + assert_nft_exist_of_id(burner_object_ref.nft, ctx); collection::decrement_supply(mutator_ref, ctx); let ( _, @@ -260,6 +259,9 @@ extend } ) = context::remove_object<NFT>(ctx, burner_object_ref.nft); + if(type_table::contains<Display>( &extend )){ + type_table::remove<Display>( &mut extend); + }; type_table::destroy_empty(extend) } diff --git a/crates/rooch-framework/sources/nft/nft.move b/crates/rooch-framework/sources/nft/nft.move index e67c7218d4..584e07df03 100644 --- a/crates/rooch-framework/sources/nft/nft.move +++ b/crates/rooch-framework/sources/nft/nft.move @@ -18,8 +18,11 @@ module rooch_framework::nft { #[test_only] use std::string; #[test_only] + use rooch_framework::account; + #[test_only] use rooch_framework::display; + const ENftNotExist: u64 = 100; const EMutatorNotExist: u64 = 101; @@ -73,8 +76,7 @@ module rooch_framework::nft { ) { assert_burner_exist_of_ref(burn_ref); let burner_object_ref = object_ref::borrow(burn_ref); - assert_burner_exist_of_id(burner_object_ref.nft, ctx); - // let nft_object_mut_ref = context::borrow_object_mut(ctx, burner_object_ref.nft); + assert_nft_exist_of_id(burner_object_ref.nft, ctx); collection::decrement_supply(mutator_ref, ctx); let ( _, @@ -87,6 +89,9 @@ module rooch_framework::nft { extend } ) = context::remove_object(ctx, burner_object_ref.nft); + if(type_table::contains( &extend )){ + type_table::remove( &mut extend); + }; type_table::destroy_empty(extend) } @@ -277,7 +282,9 @@ module rooch_framework::nft { #[test(sender = @0x2)] public fun test_create_nft (sender: address){ - let ctx = context::new_test_context(sender); + let storage_context = context::new_test_context(sender); + let ctx = &mut storage_context; + account::create_account_for_test(ctx, sender); let collection_object_ref = collection::create_collection( string::utf8(b"name"), @@ -285,10 +292,11 @@ module rooch_framework::nft { sender, string::utf8(b"description"), option::none(), - &mut ctx + ctx ); - let collection_mutator_ref = collection::generate_mutator_ref(&collection_object_ref, &mut ctx); + let collection_mutator_ref = collection::generate_mutator_ref(&collection_object_ref, ctx); + let collcetion_display = display::new(); display::set(&mut collcetion_display, string::utf8(b"name"), string::utf8(b"{ name }")); display::set(&mut collcetion_display, string::utf8(b"uri"), string::utf8(b"{ uri }")); @@ -299,7 +307,7 @@ module rooch_framework::nft { collection::add_display( &collection_mutator_ref, collcetion_display, - &mut ctx + ctx ); let nft_object_ref = mint( @@ -307,7 +315,7 @@ module rooch_framework::nft { string::utf8(b"uri"), &collection_mutator_ref, sender, - &mut ctx + ctx ); let nft_display = display::new(); @@ -315,23 +323,25 @@ module rooch_framework::nft { display::set(&mut nft_display, string::utf8(b"uri"), string::utf8(b"{ uri }/{ name }.png")); display::set(&mut nft_display, string::utf8(b"collection"), string::utf8(b"{ collection }")); - let nft_mutaor_ref = generate_mutator_ref(&nft_object_ref, &mut ctx); + let nft_mutaor_ref = generate_mutator_ref(&nft_object_ref, ctx); add_display( &nft_mutaor_ref, nft_display, - &mut ctx + ctx ); + let burner_ref = generate_burner_ref(&nft_object_ref, ctx); - let burner_ref = generate_burner_ref(&nft_object_ref, &mut ctx); - burn(&burner_ref, &collection_mutator_ref, &mut ctx); - + remove_display(&nft_mutaor_ref, ctx); + burn(&burner_ref, &collection_mutator_ref, ctx); + collection::remove_display(&collection_mutator_ref, ctx); collection::destroy_mutator_ref(collection_mutator_ref); + destroy_mutator_ref(nft_mutaor_ref); destroy_burner_ref(burner_ref); - context::drop_test_context(ctx); + context::drop_test_context(storage_context); } } \ No newline at end of file From c7d4208678f012dedd9c3577652bef8c893a97a2 Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Tue, 17 Oct 2023 01:31:11 +0800 Subject: [PATCH 13/17] Fix Error --- .../rooch-framework/sources/nft/collection.move | 16 ++++++++-------- crates/rooch-framework/sources/nft/nft.move | 17 +++++++++-------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/crates/rooch-framework/sources/nft/collection.move b/crates/rooch-framework/sources/nft/collection.move index 5248a5128a..10fbb518f0 100644 --- a/crates/rooch-framework/sources/nft/collection.move +++ b/crates/rooch-framework/sources/nft/collection.move @@ -17,9 +17,9 @@ module rooch_framework::collection{ friend rooch_framework::nft; - const EMutatorNotExist: u64 = 100; - const ECollectionNotExist: u64 = 101; - const ECollectionMaximumSupply: u64 = 102; + const ErrorMutatorNotExist: u64 = 1; + const ErrorCollectionNotExist: u64 = 2; + const ErrorCollectionMaximumSupply: u64 = 3; struct Collection has key{ name: String, @@ -123,7 +123,7 @@ module rooch_framework::collection{ let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); collection_mut_ref.supply.current = collection_mut_ref.supply.current + 1; if(option::is_some(&collection_mut_ref.supply.maximum)){ - assert!(collection_mut_ref.supply.current <= *option::borrow(&collection_mut_ref.supply.maximum), ECollectionMaximumSupply); + assert!(collection_mut_ref.supply.current <= *option::borrow(&collection_mut_ref.supply.maximum), ErrorCollectionMaximumSupply); option::some(collection_mut_ref.supply.current) }else{ option::none() @@ -146,20 +146,20 @@ module rooch_framework::collection{ // assert public fun assert_collection_exist_of_ref(collectionRef: &ObjectRef){ - assert!( object_ref::exist_object(collectionRef), ECollectionNotExist); + assert!( object_ref::exist_object(collectionRef), ErrorCollectionNotExist); } public fun assert_collection_exist_of_id(collectionID: ObjectID, ctx: & Context){ - assert!( context::exist_object(ctx, collectionID), ECollectionNotExist); + assert!( context::exist_object(ctx, collectionID), ErrorCollectionNotExist); context::borrow_object(ctx,collectionID); } public fun assert_mutator_exist_of_ref(mutatorRef: &ObjectRef){ - assert!( object_ref::exist_object(mutatorRef), EMutatorNotExist); + assert!( object_ref::exist_object(mutatorRef), ErrorMutatorNotExist); } public fun assert_mutator_exist_of_id(mutatorID: ObjectID, ctx: & Context){ - assert!( context::exist_object(ctx, mutatorID), EMutatorNotExist); + assert!( context::exist_object(ctx, mutatorID), ErrorMutatorNotExist); context::borrow_object(ctx, mutatorID); } diff --git a/crates/rooch-framework/sources/nft/nft.move b/crates/rooch-framework/sources/nft/nft.move index 584e07df03..7977f45229 100644 --- a/crates/rooch-framework/sources/nft/nft.move +++ b/crates/rooch-framework/sources/nft/nft.move @@ -23,8 +23,9 @@ module rooch_framework::nft { use rooch_framework::display; - const ENftNotExist: u64 = 100; - const EMutatorNotExist: u64 = 101; + const ErrorNftNotExist: u64 = 1; + const ErrorMutatorNotExist: u64 = 2; + const ErrorBurnerNotExist: u64 = 3; struct NFT has key { name: String, @@ -135,29 +136,29 @@ module rooch_framework::nft { // assert public fun assert_nft_exist_of_id(objectId: ObjectID, ctx: &Context) { - assert!(context::exist_object(ctx, objectId), ENftNotExist); + assert!(context::exist_object(ctx, objectId), ErrorNftNotExist); context::borrow_object(ctx, objectId); } public fun assert_nft_exist_of_ref(nft_object_ref: &ObjectRef) { - assert!(object_ref::exist_object(nft_object_ref), ENftNotExist); + assert!(object_ref::exist_object(nft_object_ref), ErrorNftNotExist); } public fun assert_mutator_exist_of_ref(mutator_ref: &ObjectRef) { - assert!(object_ref::exist_object(mutator_ref), EMutatorNotExist); + assert!(object_ref::exist_object(mutator_ref), ErrorMutatorNotExist); } public fun assert_mutator_exist_of_id(objectId: ObjectID, ctx: &Context) { - assert!(context::exist_object(ctx, objectId), EMutatorNotExist); + assert!(context::exist_object(ctx, objectId), ErrorMutatorNotExist); context::borrow_object(ctx, objectId); } public fun assert_burner_exist_of_ref(burner_ref: &ObjectRef) { - assert!(object_ref::exist_object(burner_ref), EMutatorNotExist); + assert!(object_ref::exist_object(burner_ref), ErrorBurnerNotExist); } public fun assert_burner_exist_of_id(objectId: ObjectID, ctx: &Context) { - assert!(context::exist_object(ctx, objectId), EMutatorNotExist); + assert!(context::exist_object(ctx, objectId), ErrorBurnerNotExist); context::borrow_object(ctx, objectId); } From 1d38d6380ab618418b0040cf628e8222176bc2c5 Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Thu, 19 Oct 2023 22:12:20 +0800 Subject: [PATCH 14/17] Singleton Object Display and NFT example --- crates/rooch-framework/doc/README.md | 2 - crates/rooch-framework/doc/collection.md | 937 ------------------ crates/rooch-framework/doc/display.md | 61 +- crates/rooch-framework/doc/nft.md | 884 ----------------- crates/rooch-framework/sources/display.move | 54 + .../sources/nft/collection.move | 291 ------ .../rooch-framework/sources/nft/display.move | 43 - crates/rooch-framework/sources/nft/nft.move | 348 ------- examples/nft/Move.toml | 17 + examples/nft/README.md | 0 examples/nft/sources/collection.move | 240 +++++ examples/nft/sources/nft.move | 270 +++++ .../moveos-stdlib/doc/context.md | 27 + .../moveos-stdlib/moveos-stdlib/doc/object.md | 39 +- .../moveos-stdlib/sources/context.move | 7 + .../moveos-stdlib/sources/object.move | 19 +- 16 files changed, 705 insertions(+), 2534 deletions(-) delete mode 100644 crates/rooch-framework/doc/collection.md delete mode 100644 crates/rooch-framework/doc/nft.md create mode 100644 crates/rooch-framework/sources/display.move delete mode 100644 crates/rooch-framework/sources/nft/collection.move delete mode 100644 crates/rooch-framework/sources/nft/display.move delete mode 100644 crates/rooch-framework/sources/nft/nft.move create mode 100644 examples/nft/Move.toml create mode 100644 examples/nft/README.md create mode 100644 examples/nft/sources/collection.move create mode 100644 examples/nft/sources/nft.move diff --git a/crates/rooch-framework/doc/README.md b/crates/rooch-framework/doc/README.md index 218cb032c4..4ab41a272f 100644 --- a/crates/rooch-framework/doc/README.md +++ b/crates/rooch-framework/doc/README.md @@ -24,7 +24,6 @@ This is the reference documentation of the Rooch Framework. - [`0x3::chain_id`](chain_id.md#0x3_chain_id) - [`0x3::coin`](coin.md#0x3_coin) - [`0x3::coin_store`](coin_store.md#0x3_coin_store) -- [`0x3::collection`](collection.md#0x3_collection) - [`0x3::core_addresses`](core_addresses.md#0x3_core_addresses) - [`0x3::decoding`](decoding.md#0x3_decoding) - [`0x3::display`](display.md#0x3_display) @@ -41,7 +40,6 @@ This is the reference documentation of the Rooch Framework. - [`0x3::hash`](hash.md#0x3_hash) - [`0x3::multichain_address`](multichain_address.md#0x3_multichain_address) - [`0x3::native_validator`](native_validator.md#0x3_native_validator) -- [`0x3::nft`](nft.md#0x3_nft) - [`0x3::schnorr`](schnorr.md#0x3_schnorr) - [`0x3::session_key`](session_key.md#0x3_session_key) - [`0x3::timestamp`](timestamp.md#0x3_timestamp) diff --git a/crates/rooch-framework/doc/collection.md b/crates/rooch-framework/doc/collection.md deleted file mode 100644 index 77eed1249e..0000000000 --- a/crates/rooch-framework/doc/collection.md +++ /dev/null @@ -1,937 +0,0 @@ - - - -# Module `0x3::collection` - - - -- [Resource `Collection`](#0x3_collection_Collection) -- [Struct `Supply`](#0x3_collection_Supply) -- [Resource `MutatorRef`](#0x3_collection_MutatorRef) -- [Struct `CreateCollectionEvent`](#0x3_collection_CreateCollectionEvent) -- [Constants](#@Constants_0) -- [Function `create_collection`](#0x3_collection_create_collection) -- [Function `generate_mutator_ref`](#0x3_collection_generate_mutator_ref) -- [Function `destroy_mutator_ref`](#0x3_collection_destroy_mutator_ref) -- [Function `get_collection_id`](#0x3_collection_get_collection_id) -- [Function `increment_supply`](#0x3_collection_increment_supply) -- [Function `decrement_supply`](#0x3_collection_decrement_supply) -- [Function `assert_collection_exist_of_ref`](#0x3_collection_assert_collection_exist_of_ref) -- [Function `assert_collection_exist_of_id`](#0x3_collection_assert_collection_exist_of_id) -- [Function `assert_mutator_exist_of_ref`](#0x3_collection_assert_mutator_exist_of_ref) -- [Function `assert_mutator_exist_of_id`](#0x3_collection_assert_mutator_exist_of_id) -- [Function `add_display`](#0x3_collection_add_display) -- [Function `borrow_display`](#0x3_collection_borrow_display) -- [Function `borrow_mut_display`](#0x3_collection_borrow_mut_display) -- [Function `remove_display`](#0x3_collection_remove_display) -- [Function `contains_display`](#0x3_collection_contains_display) -- [Function `add_extend`](#0x3_collection_add_extend) -- [Function `borrow_extend`](#0x3_collection_borrow_extend) -- [Function `borrow_mut_extend`](#0x3_collection_borrow_mut_extend) -- [Function `remove_extend`](#0x3_collection_remove_extend) -- [Function `contains_extend`](#0x3_collection_contains_extend) -- [Function `get_collection_name`](#0x3_collection_get_collection_name) -- [Function `get_collection_uri`](#0x3_collection_get_collection_uri) -- [Function `get_collection_creator`](#0x3_collection_get_collection_creator) -- [Function `get_collection_current_supply`](#0x3_collection_get_collection_current_supply) -- [Function `get_collection_maximum_supply`](#0x3_collection_get_collection_maximum_supply) - - -
use 0x1::option;
-use 0x1::string;
-use 0x2::context;
-use 0x2::event;
-use 0x2::object;
-use 0x2::object_ref;
-use 0x2::type_table;
-use 0x3::display;
-
- - - - - -## Resource `Collection` - - - -
struct Collection has key
-
- - - -
-Fields - - -
-
-name: string::String -
-
- -
-
-uri: string::String -
-
- -
-
-creator: address -
-
- -
-
-supply: collection::Supply -
-
- -
-
-extend: type_table::TypeTable -
-
- -
-
- - -
- - - -## Struct `Supply` - - - -
struct Supply has store
-
- - - -
-Fields - - -
-
-current: u64 -
-
- -
-
-maximum: option::Option<u64> -
-
- -
-
- - -
- - - -## Resource `MutatorRef` - - - -
struct MutatorRef has key
-
- - - -
-Fields - - -
-
-collection: object::ObjectID -
-
- -
-
- - -
- - - -## Struct `CreateCollectionEvent` - - - -
struct CreateCollectionEvent
-
- - - -
-Fields - - -
-
-objectID: object::ObjectID -
-
- -
-
-name: string::String -
-
- -
-
-uri: string::String -
-
- -
-
-creator: address -
-
- -
-
-maximum: option::Option<u64> -
-
- -
-
-description: string::String -
-
- -
-
- - -
- - - -## Constants - - - - - - -
const ECollectionMaximumSupply: u64 = 102;
-
- - - - - - - -
const ECollectionNotExist: u64 = 101;
-
- - - - - - - -
const EMutatorNotExist: u64 = 100;
-
- - - - - -## Function `create_collection` - - - -
public fun create_collection(name: string::String, uri: string::String, creator: address, description: string::String, max_supply: option::Option<u64>, ctx: &mut context::Context): object_ref::ObjectRef<collection::Collection>
-
- - - -
-Implementation - - -
public fun create_collection(
-    name: String,
-    uri: String,
-    creator: address,
-    description: String,
-    max_supply: Option<u64>,
-    ctx: &mut Context
-):ObjectRef<Collection> {
-
-    let collection = Collection {
-        name,
-        uri,
-        creator,
-        supply: Supply {
-            current: 0,
-            maximum: max_supply,
-        },
-        extend: type_table::new(ctx)
-    };
-
-    let object_ref = context::new_object_with_owner(
-        ctx,
-        creator,
-        collection
-    );
-
-    event::emit(
-        ctx,
-        CreateCollectionEvent {
-            objectID: object_ref::id(&object_ref),
-            name,
-            uri,
-            creator,
-            maximum: max_supply,
-            description,
-        }
-    );
-    object_ref
-}
-
- - - -
- - - -## Function `generate_mutator_ref` - - - -
public fun generate_mutator_ref(collection: &object_ref::ObjectRef<collection::Collection>, ctx: &mut context::Context): object_ref::ObjectRef<collection::MutatorRef>
-
- - - -
-Implementation - - -
public fun generate_mutator_ref(collection: &ObjectRef<Collection>, ctx: &mut Context):ObjectRef<MutatorRef>{
-    let mutator_ref = context::new_object_with_owner(
-        ctx,
-        object_ref::owner(collection),
-        MutatorRef {
-            collection: object_ref::id(collection),
-        }
-    );
-    mutator_ref
-}
-
- - - -
- - - -## Function `destroy_mutator_ref` - - - -
public fun destroy_mutator_ref(mutator_ref: object_ref::ObjectRef<collection::MutatorRef>): object::ObjectID
-
- - - -
-Implementation - - -
public fun destroy_mutator_ref(mutator_ref :ObjectRef<MutatorRef>):ObjectID{
-    assert_mutator_exist_of_ref(&mutator_ref);
-    let MutatorRef {
-        collection
-    } = object_ref::remove<MutatorRef>(mutator_ref);
-    collection
-}
-
- - - -
- - - -## Function `get_collection_id` - - - -
public fun get_collection_id(mutator: &object_ref::ObjectRef<collection::MutatorRef>): object::ObjectID
-
- - - -
-Implementation - - -
public fun get_collection_id(mutator: &ObjectRef<MutatorRef>): ObjectID{
-    assert_mutator_exist_of_ref(mutator);
-    let mutator_object_ref = object_ref::borrow(mutator);
-    mutator_object_ref.collection
-}
-
- - - -
- - - -## Function `increment_supply` - - - -
public(friend) fun increment_supply(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): option::Option<u64>
-
- - - -
-Implementation - - -
public(friend) fun increment_supply(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context): Option<u64>{
-    assert_mutator_exist_of_ref(mutator);
-    let mutator_object_ref = object_ref::borrow(mutator);
-    assert_collection_exist_of_id(mutator_object_ref.collection, ctx);
-    let collection_object_mut_ref = context::borrow_object_mut<Collection>(ctx, mutator_object_ref.collection);
-    let collection_mut_ref = object::borrow_mut(collection_object_mut_ref);
-    collection_mut_ref.supply.current = collection_mut_ref.supply.current + 1;
-    if(option::is_some(&collection_mut_ref.supply.maximum)){
-        assert!(collection_mut_ref.supply.current <= *option::borrow(&collection_mut_ref.supply.maximum), ECollectionMaximumSupply);
-        option::some(collection_mut_ref.supply.current)
-    }else{
-        option::none<u64>()
-    }
-}
-
- - - -
- - - -## Function `decrement_supply` - - - -
public(friend) fun decrement_supply(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): option::Option<u64>
-
- - - -
-Implementation - - -
public (friend) fun decrement_supply(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context): Option<u64>{
-    assert_mutator_exist_of_ref(mutator);
-    let mutator_object_ref = object_ref::borrow(mutator);
-    assert_collection_exist_of_id(mutator_object_ref.collection, ctx);
-    let collection_object_mut_ref = context::borrow_object_mut<Collection>(ctx, mutator_object_ref.collection);
-    let collection_mut_ref = object::borrow_mut(collection_object_mut_ref);
-    collection_mut_ref.supply.current = collection_mut_ref.supply.current - 1;
-    if(option::is_some(&collection_mut_ref.supply.maximum)){
-        option::some(collection_mut_ref.supply.current)
-    }else{
-        option::none<u64>()
-    }
-}
-
- - - -
- - - -## Function `assert_collection_exist_of_ref` - - - -
public fun assert_collection_exist_of_ref(collectionRef: &object_ref::ObjectRef<collection::Collection>)
-
- - - -
-Implementation - - -
public fun assert_collection_exist_of_ref(collectionRef: &ObjectRef<Collection>){
-    assert!( object_ref::exist_object(collectionRef), ECollectionNotExist);
-}
-
- - - -
- - - -## Function `assert_collection_exist_of_id` - - - -
public fun assert_collection_exist_of_id(collectionID: object::ObjectID, ctx: &context::Context)
-
- - - -
-Implementation - - -
public fun assert_collection_exist_of_id(collectionID: ObjectID, ctx: & Context){
-    assert!( context::exist_object(ctx, collectionID), ECollectionNotExist);
-    context::borrow_object<Collection>(ctx,collectionID);
-}
-
- - - -
- - - -## Function `assert_mutator_exist_of_ref` - - - -
public fun assert_mutator_exist_of_ref(mutatorRef: &object_ref::ObjectRef<collection::MutatorRef>)
-
- - - -
-Implementation - - -
public fun assert_mutator_exist_of_ref(mutatorRef: &ObjectRef<MutatorRef>){
-    assert!( object_ref::exist_object(mutatorRef), EMutatorNotExist);
-}
-
- - - -
- - - -## Function `assert_mutator_exist_of_id` - - - -
public fun assert_mutator_exist_of_id(mutatorID: object::ObjectID, ctx: &context::Context)
-
- - - -
-Implementation - - -
public fun assert_mutator_exist_of_id(mutatorID: ObjectID, ctx: & Context){
-    assert!( context::exist_object(ctx, mutatorID), EMutatorNotExist);
-    context::borrow_object<MutatorRef>(ctx, mutatorID);
-}
-
- - - -
- - - -## Function `add_display` - - - -
public fun add_display(mutator: &object_ref::ObjectRef<collection::MutatorRef>, display: display::Display, ctx: &mut context::Context)
-
- - - -
-Implementation - - -
public fun add_display(mutator: &ObjectRef<MutatorRef>, display: Display, ctx: &mut Context){
-    add_extend_internal(mutator, display, ctx);
-}
-
- - - -
- - - -## Function `borrow_display` - - - -
public fun borrow_display(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): &display::Display
-
- - - -
-Implementation - - -
public fun borrow_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&Display{
-    borrow_extend_internal(mutator, ctx)
-}
-
- - - -
- - - -## Function `borrow_mut_display` - - - -
public fun borrow_mut_display(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): &mut display::Display
-
- - - -
-Implementation - - -
public fun borrow_mut_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&mut Display{
-    borrow_mut_extend_internal(mutator, ctx)
-}
-
- - - -
- - - -## Function `remove_display` - - - -
public fun remove_display(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): display::Display
-
- - - -
-Implementation - - -
public fun remove_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):Display{
-    remove_extend_internal(mutator, ctx)
-}
-
- - - -
- - - -## Function `contains_display` - - - -
public fun contains_display(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): bool
-
- - - -
-Implementation - - -
public fun contains_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context): bool{
-    contains_extend_internal<Display>(mutator, ctx)
-}
-
- - - -
- - - -## Function `add_extend` - - - -
public fun add_extend<V: key>(mutator: &object_ref::ObjectRef<collection::MutatorRef>, val: V, ctx: &mut context::Context)
-
- - - -
-Implementation - - -
public fun add_extend<V: key>(mutator: &ObjectRef<MutatorRef>, val: V, ctx: &mut Context){
-    add_extend_internal(mutator, val, ctx);
-}
-
- - - -
- - - -## Function `borrow_extend` - - - -
public fun borrow_extend<V: key>(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): &V
-
- - - -
-Implementation - - -
public fun borrow_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&V{
-    borrow_extend_internal(mutator, ctx)
-}
-
- - - -
- - - -## Function `borrow_mut_extend` - - - -
public fun borrow_mut_extend<V: key>(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): &mut V
-
- - - -
-Implementation - - -
public fun borrow_mut_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&mut V{
-    borrow_mut_extend_internal(mutator, ctx)
-}
-
- - - -
- - - -## Function `remove_extend` - - - -
public fun remove_extend<V: key>(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): V
-
- - - -
-Implementation - - -
public fun remove_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):V{
-    remove_extend_internal(mutator, ctx)
-}
-
- - - -
- - - -## Function `contains_extend` - - - -
public fun contains_extend<V: key>(mutator: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context): bool
-
- - - -
-Implementation - - -
public fun contains_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context): bool{
-    contains_extend_internal<V>(mutator, ctx)
-}
-
- - - -
- - - -## Function `get_collection_name` - - - -
public fun get_collection_name(collectionID: object::ObjectID, ctx: &mut context::Context): string::String
-
- - - -
-Implementation - - -
public fun get_collection_name(collectionID: ObjectID, ctx: &mut Context): String{
-    assert_collection_exist_of_id(collectionID, ctx);
-    let collection_object_ref = context::borrow_object<Collection>(ctx, collectionID);
-    let collection_ref = object::borrow(collection_object_ref);
-    collection_ref.name
-}
-
- - - -
- - - -## Function `get_collection_uri` - - - -
public fun get_collection_uri(collectionID: object::ObjectID, ctx: &mut context::Context): string::String
-
- - - -
-Implementation - - -
public fun get_collection_uri(collectionID: ObjectID, ctx: &mut Context): String{
-    assert_collection_exist_of_id(collectionID, ctx);
-    let collection_object_ref = context::borrow_object<Collection>(ctx, collectionID);
-    let collection_ref = object::borrow(collection_object_ref);
-    collection_ref.uri
-}
-
- - - -
- - - -## Function `get_collection_creator` - - - -
public fun get_collection_creator(collectionID: object::ObjectID, ctx: &mut context::Context): address
-
- - - -
-Implementation - - -
public fun get_collection_creator(collectionID: ObjectID, ctx: &mut Context): address{
-    assert_collection_exist_of_id(collectionID, ctx);
-    let collection_object_ref = context::borrow_object<Collection>(ctx, collectionID);
-    let collection_ref = object::borrow(collection_object_ref);
-    collection_ref.creator
-}
-
- - - -
- - - -## Function `get_collection_current_supply` - - - -
public fun get_collection_current_supply(collectionID: object::ObjectID, ctx: &mut context::Context): u64
-
- - - -
-Implementation - - -
public fun get_collection_current_supply(collectionID: ObjectID, ctx: &mut Context): u64{
-    assert_collection_exist_of_id(collectionID, ctx);
-    let collection_object_ref = context::borrow_object<Collection>(ctx, collectionID);
-    let collection_ref = object::borrow(collection_object_ref);
-    collection_ref.supply.current
-}
-
- - - -
- - - -## Function `get_collection_maximum_supply` - - - -
public fun get_collection_maximum_supply(collectionID: object::ObjectID, ctx: &mut context::Context): option::Option<u64>
-
- - - -
-Implementation - - -
public fun get_collection_maximum_supply(collectionID: ObjectID, ctx: &mut Context): Option<u64>{
-    assert_collection_exist_of_id(collectionID, ctx);
-    let collection_object_ref = context::borrow_object<Collection>(ctx, collectionID);
-    let collection_ref = object::borrow(collection_object_ref);
-    collection_ref.supply.maximum
-}
-
- - - -
diff --git a/crates/rooch-framework/doc/display.md b/crates/rooch-framework/doc/display.md index 4355b31c96..9d36b6738e 100644 --- a/crates/rooch-framework/doc/display.md +++ b/crates/rooch-framework/doc/display.md @@ -17,6 +17,8 @@
use 0x1::string;
+use 0x2::context;
+use 0x2::object_ref;
 use 0x2::simple_map;
 
@@ -28,7 +30,7 @@ -
struct Display has copy, drop, store, key
+
struct Display<T> has copy, drop, store, key
 
@@ -55,7 +57,7 @@ -
public fun new(): display::Display
+
public fun new<T>(ctx: &mut context::Context): object_ref::ObjectRef<display::Display<T>>
 
@@ -64,10 +66,10 @@ Implementation -
public fun new (): Display {
-    Display {
+
public fun new<T>(ctx: &mut Context): ObjectRef<Display<T>> {
+    context::new_single_object(ctx, Display<T> {
         sample_map: simple_map::create()
-    }
+    })
 }
 
@@ -81,7 +83,7 @@ -
public fun set(self: &mut display::Display, key: string::String, value: string::String)
+
public fun set<T>(self: &mut object_ref::ObjectRef<display::Display<T>>, key: string::String, value: string::String)
 
@@ -90,8 +92,9 @@ Implementation -
public fun set (self: &mut Display, key: String, value: String) {
-    simple_map::add(&mut self.sample_map, key, value);
+
public fun set<T>(self: &mut ObjectRef<Display<T>>, key: String, value: String) {
+    let display_ref = object_ref::borrow_mut(self);
+    simple_map::add(&mut display_ref.sample_map, key, value);
 }
 
@@ -105,7 +108,7 @@ -
public fun borrow(self: &display::Display, key: &string::String): &string::String
+
public fun borrow<T>(self: &object_ref::ObjectRef<display::Display<T>>, key: &string::String): &string::String
 
@@ -114,8 +117,9 @@ Implementation -
public fun borrow (self: &Display, key: &String): &String {
-    simple_map::borrow(&self.sample_map, key)
+
public fun borrow<T>(self: & ObjectRef<Display<T>> , key: &String): &String {
+    let display_ref = object_ref::borrow(self);
+    simple_map::borrow(&display_ref.sample_map, key)
 }
 
@@ -129,7 +133,7 @@ -
public fun borrow_mut(self: &mut display::Display, key: &string::String): &mut string::String
+
public fun borrow_mut<T>(self: &mut object_ref::ObjectRef<display::Display<T>>, key: &string::String): &mut string::String
 
@@ -138,8 +142,9 @@ Implementation -
public fun borrow_mut (self: &mut Display, key: &String): &mut String {
-    simple_map::borrow_mut(&mut self.sample_map, key)
+
public fun borrow_mut<T>(self: &mut ObjectRef<Display<T>>, key: &String): &mut String {
+    let display_ref = object_ref::borrow_mut(self);
+    simple_map::borrow_mut(&mut display_ref.sample_map, key)
 }
 
@@ -153,7 +158,7 @@ -
public fun remove(self: &mut display::Display, key: &string::String)
+
public fun remove<T>(self: &mut object_ref::ObjectRef<display::Display<T>>, key: &string::String)
 
@@ -162,8 +167,9 @@ Implementation -
public fun remove (self: &mut Display, key: &String) {
-    simple_map::remove(&mut self.sample_map, key);
+
public fun remove<T>(self: &mut ObjectRef<Display<T>>, key: &String) {
+    let display_ref = object_ref::borrow_mut(self);
+    simple_map::remove(&mut display_ref.sample_map, key);
 }
 
@@ -177,7 +183,7 @@ -
public fun keys(self: &display::Display): vector<string::String>
+
public fun keys<T>(self: &object_ref::ObjectRef<display::Display<T>>): vector<string::String>
 
@@ -186,8 +192,9 @@ Implementation -
public fun keys (self: & Display): vector<String> {
-    simple_map::keys(& self.sample_map)
+
public fun keys<T>(self: & ObjectRef<Display<T>>): vector<String> {
+    let display_ref = object_ref::borrow(self);
+    simple_map::keys(& display_ref.sample_map)
 }
 
@@ -201,7 +208,7 @@ -
public fun values(self: &display::Display): vector<string::String>
+
public fun values<T>(self: &object_ref::ObjectRef<display::Display<T>>): vector<string::String>
 
@@ -210,8 +217,9 @@ Implementation -
public fun values (self: & Display): vector<String> {
-    simple_map::values(& self.sample_map)
+
public fun values<T>(self: & ObjectRef<Display<T>>): vector<String> {
+    let display_ref = object_ref::borrow(self);
+    simple_map::values(& display_ref.sample_map)
 }
 
@@ -225,7 +233,7 @@ -
public fun contains_key(self: &display::Display, key: &string::String): bool
+
public fun contains_key<T>(self: &object_ref::ObjectRef<display::Display<T>>, key: &string::String): bool
 
@@ -234,8 +242,9 @@ Implementation -
public fun contains_key (self: & Display, key: &String): bool {
-    simple_map::contains_key(& self.sample_map, key)
+
public fun contains_key<T>(self: & ObjectRef<Display<T>>, key: &String): bool {
+    let display_ref = object_ref::borrow(self);
+    simple_map::contains_key(& display_ref.sample_map, key)
 }
 
diff --git a/crates/rooch-framework/doc/nft.md b/crates/rooch-framework/doc/nft.md deleted file mode 100644 index 914135c63e..0000000000 --- a/crates/rooch-framework/doc/nft.md +++ /dev/null @@ -1,884 +0,0 @@ - - - -# Module `0x3::nft` - - - -- [Resource `NFT`](#0x3_nft_NFT) -- [Resource `MutatorRef`](#0x3_nft_MutatorRef) -- [Resource `BurnerRef`](#0x3_nft_BurnerRef) -- [Constants](#@Constants_0) -- [Function `mint`](#0x3_nft_mint) -- [Function `burn`](#0x3_nft_burn) -- [Function `generate_mutator_ref`](#0x3_nft_generate_mutator_ref) -- [Function `destroy_mutator_ref`](#0x3_nft_destroy_mutator_ref) -- [Function `generate_burner_ref`](#0x3_nft_generate_burner_ref) -- [Function `destroy_burner_ref`](#0x3_nft_destroy_burner_ref) -- [Function `assert_nft_exist_of_id`](#0x3_nft_assert_nft_exist_of_id) -- [Function `assert_nft_exist_of_ref`](#0x3_nft_assert_nft_exist_of_ref) -- [Function `assert_mutator_exist_of_ref`](#0x3_nft_assert_mutator_exist_of_ref) -- [Function `assert_mutator_exist_of_id`](#0x3_nft_assert_mutator_exist_of_id) -- [Function `assert_burner_exist_of_ref`](#0x3_nft_assert_burner_exist_of_ref) -- [Function `assert_burner_exist_of_id`](#0x3_nft_assert_burner_exist_of_id) -- [Function `add_display`](#0x3_nft_add_display) -- [Function `borrow_display`](#0x3_nft_borrow_display) -- [Function `borrow_mut_display`](#0x3_nft_borrow_mut_display) -- [Function `remove_display`](#0x3_nft_remove_display) -- [Function `contains_display`](#0x3_nft_contains_display) -- [Function `add_extend`](#0x3_nft_add_extend) -- [Function `borrow_extend`](#0x3_nft_borrow_extend) -- [Function `borrow_mut_extend`](#0x3_nft_borrow_mut_extend) -- [Function `remove_extend`](#0x3_nft_remove_extend) -- [Function `contains_extend`](#0x3_nft_contains_extend) -- [Function `get_name`](#0x3_nft_get_name) -- [Function `get_uri`](#0x3_nft_get_uri) -- [Function `get_collection`](#0x3_nft_get_collection) -- [Function `get_creator`](#0x3_nft_get_creator) - - -
use 0x1::option;
-use 0x1::string;
-use 0x2::context;
-use 0x2::object;
-use 0x2::object_ref;
-use 0x2::type_table;
-use 0x3::collection;
-use 0x3::display;
-
- - - - - -## Resource `NFT` - - - -
struct NFT has key
-
- - - -
-Fields - - -
-
-name: string::String -
-
- -
-
-uri: string::String -
-
- -
-
-collection: object::ObjectID -
-
- -
-
-creator: address -
-
- -
-
-extend: type_table::TypeTable -
-
- -
-
- - -
- - - -## Resource `MutatorRef` - - - -
struct MutatorRef has key
-
- - - -
-Fields - - -
-
-nft: object::ObjectID -
-
- -
-
- - -
- - - -## Resource `BurnerRef` - - - -
struct BurnerRef has key
-
- - - -
-Fields - - -
-
-nft: object::ObjectID -
-
- -
-
- - -
- - - -## Constants - - - - - - -
const EMutatorNotExist: u64 = 101;
-
- - - - - - - -
const ENftNotExist: u64 = 100;
-
- - - - - -## Function `mint` - - - -
public fun mint(name: string::String, uri: string::String, mutator_ref: &object_ref::ObjectRef<collection::MutatorRef>, creator: address, ctx: &mut context::Context): object_ref::ObjectRef<nft::NFT>
-
- - - -
-Implementation - - -
public fun mint(
-    name: String,
-    uri: String,
-    mutator_ref: &ObjectRef<collection::MutatorRef>,
-    creator: address,
-    ctx: &mut Context
-): ObjectRef<NFT> {
-    collection::assert_mutator_exist_of_ref(mutator_ref);
-    let nft = NFT {
-        name,
-        uri,
-        collection: collection::get_collection_id(mutator_ref),
-        creator,
-        extend: type_table::new(ctx)
-    };
-
-    collection::increment_supply(mutator_ref, ctx);
-
-    let object_ref = context::new_object_with_owner(
-        ctx,
-        creator,
-        nft
-    );
-
-    object_ref
-}
-
- - - -
- - - -## Function `burn` - - - -
public fun burn(burn_ref: &object_ref::ObjectRef<nft::BurnerRef>, mutator_ref: &object_ref::ObjectRef<collection::MutatorRef>, ctx: &mut context::Context)
-
- - - -
-Implementation - - -
public fun burn (
-    burn_ref: &ObjectRef<BurnerRef>,
-    mutator_ref: &ObjectRef<collection::MutatorRef>,
-    ctx: &mut Context
-) {
-    assert_burner_exist_of_ref(burn_ref);
-    let burner_object_ref = object_ref::borrow(burn_ref);
-    assert_nft_exist_of_id(burner_object_ref.nft, ctx);
-    collection::decrement_supply(mutator_ref, ctx);
-    let (
-        _,
-        _,
-        NFT {
-            name:_,
-            uri:_,
-            collection:_,
-            creator:_,
-            extend
-        }
-    ) = context::remove_object<NFT>(ctx, burner_object_ref.nft);
-    if(type_table::contains<Display>( &extend )){
-       type_table::remove<Display>( &mut extend);
-    };
-    type_table::destroy_empty(extend)
-}
-
- - - -
- - - -## Function `generate_mutator_ref` - - - -
public fun generate_mutator_ref(nft_object_ref: &object_ref::ObjectRef<nft::NFT>, ctx: &mut context::Context): object_ref::ObjectRef<nft::MutatorRef>
-
- - - -
-Implementation - - -
public fun generate_mutator_ref(nft_object_ref: &ObjectRef<NFT>, ctx: &mut Context):ObjectRef<MutatorRef>{
-    let mutator_ref = context::new_object_with_owner(
-        ctx,
-        object_ref::owner(nft_object_ref),
-        MutatorRef {
-            nft: object_ref::id(nft_object_ref),
-        }
-    );
-    mutator_ref
-}
-
- - - -
- - - -## Function `destroy_mutator_ref` - - - -
public fun destroy_mutator_ref(mutator_ref: object_ref::ObjectRef<nft::MutatorRef>): object::ObjectID
-
- - - -
-Implementation - - -
public fun destroy_mutator_ref(mutator_ref :ObjectRef<MutatorRef>):ObjectID{
-    assert_mutator_exist_of_ref(&mutator_ref);
-    let MutatorRef {
-        nft
-    } = object_ref::remove<MutatorRef>(mutator_ref);
-    nft
-}
-
- - - -
- - - -## Function `generate_burner_ref` - - - -
public fun generate_burner_ref(nft_object_ref: &object_ref::ObjectRef<nft::NFT>, ctx: &mut context::Context): object_ref::ObjectRef<nft::BurnerRef>
-
- - - -
-Implementation - - -
public fun generate_burner_ref(nft_object_ref: &ObjectRef<NFT>, ctx: &mut Context):ObjectRef<BurnerRef>{
-    let burner_ref = context::new_object_with_owner(
-        ctx,
-        object_ref::owner(nft_object_ref),
-        BurnerRef {
-            nft: object_ref::id(nft_object_ref),
-        }
-    );
-    burner_ref
-}
-
- - - -
- - - -## Function `destroy_burner_ref` - - - -
public fun destroy_burner_ref(burner_ref: object_ref::ObjectRef<nft::BurnerRef>): object::ObjectID
-
- - - -
-Implementation - - -
public fun destroy_burner_ref(burner_ref :ObjectRef<BurnerRef>):ObjectID{
-    assert_burner_exist_of_ref(&burner_ref);
-    let BurnerRef {
-        nft
-    } = object_ref::remove<BurnerRef>(burner_ref);
-    nft
-}
-
- - - -
- - - -## Function `assert_nft_exist_of_id` - - - -
public fun assert_nft_exist_of_id(objectId: object::ObjectID, ctx: &context::Context)
-
- - - -
-Implementation - - -
public fun assert_nft_exist_of_id(objectId: ObjectID, ctx: &Context) {
-    assert!(context::exist_object(ctx, objectId), ENftNotExist);
-    context::borrow_object<NFT>(ctx, objectId);
-}
-
- - - -
- - - -## Function `assert_nft_exist_of_ref` - - - -
public fun assert_nft_exist_of_ref(nft_object_ref: &object_ref::ObjectRef<nft::NFT>)
-
- - - -
-Implementation - - -
public fun assert_nft_exist_of_ref(nft_object_ref: &ObjectRef<NFT>) {
-    assert!(object_ref::exist_object(nft_object_ref), ENftNotExist);
-}
-
- - - -
- - - -## Function `assert_mutator_exist_of_ref` - - - -
public fun assert_mutator_exist_of_ref(mutator_ref: &object_ref::ObjectRef<nft::MutatorRef>)
-
- - - -
-Implementation - - -
public fun assert_mutator_exist_of_ref(mutator_ref: &ObjectRef<MutatorRef>) {
-    assert!(object_ref::exist_object(mutator_ref), EMutatorNotExist);
-}
-
- - - -
- - - -## Function `assert_mutator_exist_of_id` - - - -
public fun assert_mutator_exist_of_id(objectId: object::ObjectID, ctx: &context::Context)
-
- - - -
-Implementation - - -
public fun assert_mutator_exist_of_id(objectId: ObjectID, ctx: &Context) {
-    assert!(context::exist_object(ctx, objectId), EMutatorNotExist);
-    context::borrow_object<MutatorRef>(ctx, objectId);
-}
-
- - - -
- - - -## Function `assert_burner_exist_of_ref` - - - -
public fun assert_burner_exist_of_ref(burner_ref: &object_ref::ObjectRef<nft::BurnerRef>)
-
- - - -
-Implementation - - -
public fun assert_burner_exist_of_ref(burner_ref: &ObjectRef<BurnerRef>) {
-    assert!(object_ref::exist_object(burner_ref), EMutatorNotExist);
-}
-
- - - -
- - - -## Function `assert_burner_exist_of_id` - - - -
public fun assert_burner_exist_of_id(objectId: object::ObjectID, ctx: &context::Context)
-
- - - -
-Implementation - - -
public fun assert_burner_exist_of_id(objectId: ObjectID, ctx: &Context) {
-    assert!(context::exist_object(ctx, objectId), EMutatorNotExist);
-    context::borrow_object<BurnerRef>(ctx, objectId);
-}
-
- - - -
- - - -## Function `add_display` - - - -
public fun add_display(mutator: &object_ref::ObjectRef<nft::MutatorRef>, display: display::Display, ctx: &mut context::Context)
-
- - - -
-Implementation - - -
public fun add_display(mutator: &ObjectRef<MutatorRef>, display: Display, ctx: &mut Context){
-    add_extend_internal(mutator, display, ctx);
-}
-
- - - -
- - - -## Function `borrow_display` - - - -
public fun borrow_display(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): &display::Display
-
- - - -
-Implementation - - -
public fun borrow_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&Display{
-    borrow_extend_internal(mutator, ctx)
-}
-
- - - -
- - - -## Function `borrow_mut_display` - - - -
public fun borrow_mut_display(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): &mut display::Display
-
- - - -
-Implementation - - -
public fun borrow_mut_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&mut Display{
-    borrow_mut_extend_internal(mutator, ctx)
-}
-
- - - -
- - - -## Function `remove_display` - - - -
public fun remove_display(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): display::Display
-
- - - -
-Implementation - - -
public fun remove_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):Display{
-    remove_extend_internal(mutator, ctx)
-}
-
- - - -
- - - -## Function `contains_display` - - - -
public fun contains_display(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): bool
-
- - - -
-Implementation - - -
public fun contains_display(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context): bool{
-    contains_extend_internal<Display>(mutator, ctx)
-}
-
- - - -
- - - -## Function `add_extend` - - - -
public fun add_extend<V: key>(mutator: &object_ref::ObjectRef<nft::MutatorRef>, val: V, ctx: &mut context::Context)
-
- - - -
-Implementation - - -
public fun add_extend<V: key>(mutator: &ObjectRef<MutatorRef>, val: V, ctx: &mut Context){
-    add_extend_internal(mutator, val, ctx);
-}
-
- - - -
- - - -## Function `borrow_extend` - - - -
public fun borrow_extend<V: key>(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): &V
-
- - - -
-Implementation - - -
public fun borrow_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&V{
-    borrow_extend_internal(mutator, ctx)
-}
-
- - - -
- - - -## Function `borrow_mut_extend` - - - -
public fun borrow_mut_extend<V: key>(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): &mut V
-
- - - -
-Implementation - - -
public fun borrow_mut_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):&mut V{
-    borrow_mut_extend_internal(mutator, ctx)
-}
-
- - - -
- - - -## Function `remove_extend` - - - -
public fun remove_extend<V: key>(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): V
-
- - - -
-Implementation - - -
public fun remove_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context):V{
-    remove_extend_internal(mutator, ctx)
-}
-
- - - -
- - - -## Function `contains_extend` - - - -
public fun contains_extend<V: key>(mutator: &object_ref::ObjectRef<nft::MutatorRef>, ctx: &mut context::Context): bool
-
- - - -
-Implementation - - -
public fun contains_extend<V: key>(mutator: &ObjectRef<MutatorRef>, ctx: &mut Context): bool{
-    contains_extend_internal<V>(mutator, ctx)
-}
-
- - - -
- - - -## Function `get_name` - - - -
public fun get_name(objectId: object::ObjectID, ctx: &context::Context): string::String
-
- - - -
-Implementation - - -
public fun get_name(objectId: ObjectID, ctx: &Context): String {
-    assert_nft_exist_of_id(objectId, ctx);
-    let nft_object_ref = context::borrow_object<NFT>(ctx, objectId);
-    let nft = object::borrow(nft_object_ref);
-    nft.name
-}
-
- - - -
- - - -## Function `get_uri` - - - -
public fun get_uri(objectId: object::ObjectID, ctx: &context::Context): string::String
-
- - - -
-Implementation - - -
public fun get_uri(objectId: ObjectID, ctx: &Context): String {
-    assert_nft_exist_of_id(objectId, ctx);
-    let nft_object_ref = context::borrow_object<NFT>(ctx, objectId);
-    let nft = object::borrow(nft_object_ref);
-    nft.uri
-}
-
- - - -
- - - -## Function `get_collection` - - - -
public fun get_collection(objectId: object::ObjectID, ctx: &context::Context): object::ObjectID
-
- - - -
-Implementation - - -
public fun get_collection(objectId: ObjectID, ctx: &Context): ObjectID {
-    assert_nft_exist_of_id(objectId, ctx);
-    let nft_object_ref = context::borrow_object<NFT>(ctx, objectId);
-    let nft = object::borrow(nft_object_ref);
-    nft.collection
-}
-
- - - -
- - - -## Function `get_creator` - - - -
public fun get_creator(objectId: object::ObjectID, ctx: &context::Context): address
-
- - - -
-Implementation - - -
public fun get_creator(objectId: ObjectID, ctx: &Context): address {
-    assert_nft_exist_of_id(objectId, ctx);
-    let nft_object_ref = context::borrow_object<NFT>(ctx, objectId);
-    let nft = object::borrow(nft_object_ref);
-    nft.creator
-}
-
- - - -
diff --git a/crates/rooch-framework/sources/display.move b/crates/rooch-framework/sources/display.move new file mode 100644 index 0000000000..b7963d88f5 --- /dev/null +++ b/crates/rooch-framework/sources/display.move @@ -0,0 +1,54 @@ +module rooch_framework::display{ + use std::string::String; + use moveos_std::object_ref; + use moveos_std::context::Context; + use moveos_std::context; + use moveos_std::object_ref::ObjectRef; + use moveos_std::simple_map; + + struct Display has key, store,drop,copy { + sample_map: simple_map::SimpleMap + } + + public fun new(ctx: &mut Context): ObjectRef> { + context::new_single_object(ctx, Display { + sample_map: simple_map::create() + }) + } + + public fun set(self: &mut ObjectRef>, key: String, value: String) { + let display_ref = object_ref::borrow_mut(self); + simple_map::add(&mut display_ref.sample_map, key, value); + } + + public fun borrow(self: & ObjectRef> , key: &String): &String { + let display_ref = object_ref::borrow(self); + simple_map::borrow(&display_ref.sample_map, key) + } + + public fun borrow_mut(self: &mut ObjectRef>, key: &String): &mut String { + let display_ref = object_ref::borrow_mut(self); + simple_map::borrow_mut(&mut display_ref.sample_map, key) + } + + public fun remove(self: &mut ObjectRef>, key: &String) { + let display_ref = object_ref::borrow_mut(self); + simple_map::remove(&mut display_ref.sample_map, key); + } + + public fun keys(self: & ObjectRef>): vector { + let display_ref = object_ref::borrow(self); + simple_map::keys(& display_ref.sample_map) + } + + public fun values(self: & ObjectRef>): vector { + let display_ref = object_ref::borrow(self); + simple_map::values(& display_ref.sample_map) + } + + public fun contains_key(self: & ObjectRef>, key: &String): bool { + let display_ref = object_ref::borrow(self); + simple_map::contains_key(& display_ref.sample_map, key) + } + +} \ No newline at end of file diff --git a/crates/rooch-framework/sources/nft/collection.move b/crates/rooch-framework/sources/nft/collection.move deleted file mode 100644 index 10fbb518f0..0000000000 --- a/crates/rooch-framework/sources/nft/collection.move +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright (c) RoochNetwork -// SPDX-License-Identifier: Apache-2.0 - -module rooch_framework::collection{ - use std::option; - use std::option::Option; - use std::string::String; - use rooch_framework::display::Display; - use moveos_std::object::ObjectID; - use moveos_std::object_ref; - use moveos_std::event; - use moveos_std::context; - use moveos_std::context::Context; - use moveos_std::object; - use moveos_std::object_ref::ObjectRef; - use moveos_std::type_table; - - friend rooch_framework::nft; - - const ErrorMutatorNotExist: u64 = 1; - const ErrorCollectionNotExist: u64 = 2; - const ErrorCollectionMaximumSupply: u64 = 3; - - struct Collection has key{ - name: String, - uri: String, - creator: address, - supply: Supply, - extend: type_table::TypeTable - } - - struct Supply has store{ - current: u64, - maximum: Option, - } - - struct MutatorRef has key{ - collection: ObjectID, - } - - // event - struct CreateCollectionEvent{ - objectID: ObjectID, - name: String, - uri: String, - creator: address, - maximum: Option, - description: String, - } - - - public fun create_collection( - name: String, - uri: String, - creator: address, - description: String, - max_supply: Option, - ctx: &mut Context - ):ObjectRef { - - let collection = Collection { - name, - uri, - creator, - supply: Supply { - current: 0, - maximum: max_supply, - }, - extend: type_table::new(ctx) - }; - - let object_ref = context::new_object_with_owner( - ctx, - creator, - collection - ); - - event::emit( - ctx, - CreateCollectionEvent { - objectID: object_ref::id(&object_ref), - name, - uri, - creator, - maximum: max_supply, - description, - } - ); - object_ref - } - - public fun generate_mutator_ref(collection: &ObjectRef, ctx: &mut Context):ObjectRef{ - let mutator_ref = context::new_object_with_owner( - ctx, - object_ref::owner(collection), - MutatorRef { - collection: object_ref::id(collection), - } - ); - mutator_ref - } - - public fun destroy_mutator_ref(mutator_ref :ObjectRef):ObjectID{ - assert_mutator_exist_of_ref(&mutator_ref); - let MutatorRef { - collection - } = object_ref::remove(mutator_ref); - collection - } - - public fun get_collection_id(mutator: &ObjectRef): ObjectID{ - assert_mutator_exist_of_ref(mutator); - let mutator_object_ref = object_ref::borrow(mutator); - mutator_object_ref.collection - } - - - public(friend) fun increment_supply(mutator: &ObjectRef, ctx: &mut Context): Option{ - assert_mutator_exist_of_ref(mutator); - let mutator_object_ref = object_ref::borrow(mutator); - assert_collection_exist_of_id(mutator_object_ref.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); - let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); - collection_mut_ref.supply.current = collection_mut_ref.supply.current + 1; - if(option::is_some(&collection_mut_ref.supply.maximum)){ - assert!(collection_mut_ref.supply.current <= *option::borrow(&collection_mut_ref.supply.maximum), ErrorCollectionMaximumSupply); - option::some(collection_mut_ref.supply.current) - }else{ - option::none() - } - } - - public (friend) fun decrement_supply(mutator: &ObjectRef, ctx: &mut Context): Option{ - assert_mutator_exist_of_ref(mutator); - let mutator_object_ref = object_ref::borrow(mutator); - assert_collection_exist_of_id(mutator_object_ref.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); - let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); - collection_mut_ref.supply.current = collection_mut_ref.supply.current - 1; - if(option::is_some(&collection_mut_ref.supply.maximum)){ - option::some(collection_mut_ref.supply.current) - }else{ - option::none() - } - } - - // assert - public fun assert_collection_exist_of_ref(collectionRef: &ObjectRef){ - assert!( object_ref::exist_object(collectionRef), ErrorCollectionNotExist); - } - - public fun assert_collection_exist_of_id(collectionID: ObjectID, ctx: & Context){ - assert!( context::exist_object(ctx, collectionID), ErrorCollectionNotExist); - context::borrow_object(ctx,collectionID); - } - - public fun assert_mutator_exist_of_ref(mutatorRef: &ObjectRef){ - assert!( object_ref::exist_object(mutatorRef), ErrorMutatorNotExist); - } - - public fun assert_mutator_exist_of_id(mutatorID: ObjectID, ctx: & Context){ - assert!( context::exist_object(ctx, mutatorID), ErrorMutatorNotExist); - context::borrow_object(ctx, mutatorID); - } - - public fun add_display(mutator: &ObjectRef, display: Display, ctx: &mut Context){ - add_extend_internal(mutator, display, ctx); - } - - public fun borrow_display(mutator: &ObjectRef, ctx: &mut Context):&Display{ - borrow_extend_internal(mutator, ctx) - } - - public fun borrow_mut_display(mutator: &ObjectRef, ctx: &mut Context):&mut Display{ - borrow_mut_extend_internal(mutator, ctx) - } - - public fun remove_display(mutator: &ObjectRef, ctx: &mut Context):Display{ - remove_extend_internal(mutator, ctx) - } - - public fun contains_display(mutator: &ObjectRef, ctx: &mut Context): bool{ - contains_extend_internal(mutator, ctx) - } - - #[private_generics(V)] - public fun add_extend(mutator: &ObjectRef, val: V, ctx: &mut Context){ - add_extend_internal(mutator, val, ctx); - } - - public fun borrow_extend(mutator: &ObjectRef, ctx: &mut Context):&V{ - borrow_extend_internal(mutator, ctx) - } - - #[private_generics(V)] - public fun borrow_mut_extend(mutator: &ObjectRef, ctx: &mut Context):&mut V{ - borrow_mut_extend_internal(mutator, ctx) - } - - #[private_generics(V)] - public fun remove_extend(mutator: &ObjectRef, ctx: &mut Context):V{ - remove_extend_internal(mutator, ctx) - } - - public fun contains_extend(mutator: &ObjectRef, ctx: &mut Context): bool{ - contains_extend_internal(mutator, ctx) - } - - - fun add_extend_internal(mutator: &ObjectRef,val: V,ctx: &mut Context){ - assert_mutator_exist_of_ref(mutator); - let mutator_object_ref = object_ref::borrow(mutator); - assert_collection_exist_of_id(mutator_object_ref.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); - let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); - type_table::add( &mut collection_mut_ref.extend, val); - } - - fun borrow_extend_internal(mutator: &ObjectRef, ctx: &mut Context):&V{ - assert_mutator_exist_of_ref(mutator); - let mutator_object_ref = object_ref::borrow(mutator); - assert_collection_exist_of_id(mutator_object_ref.collection, ctx); - let collection_object_ref = context::borrow_object(ctx, mutator_object_ref.collection); - let collection_ref = object::borrow(collection_object_ref); - type_table::borrow(&collection_ref.extend) - } - - fun borrow_mut_extend_internal(mutator: &ObjectRef, ctx: &mut Context):&mut V{ - assert_mutator_exist_of_ref(mutator); - let mutator_object_ref = object_ref::borrow(mutator); - assert_collection_exist_of_id(mutator_object_ref.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); - let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); - type_table::borrow_mut(&mut collection_mut_ref.extend) - } - - fun remove_extend_internal(mutator: &ObjectRef, ctx: &mut Context):V{ - assert_mutator_exist_of_ref(mutator); - let mutator_object_ref = object_ref::borrow(mutator); - assert_collection_exist_of_id(mutator_object_ref.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.collection); - let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); - type_table::remove(&mut collection_mut_ref.extend) - } - - fun contains_extend_internal(mutator: &ObjectRef, ctx: &mut Context): bool{ - assert_mutator_exist_of_ref(mutator); - let mutator_object_ref = object_ref::borrow(mutator); - assert_collection_exist_of_id(mutator_object_ref.collection, ctx); - let collection_object_ref = context::borrow_object(ctx, mutator_object_ref.collection); - let collection_ref = object::borrow(collection_object_ref); - type_table::contains(&collection_ref.extend) - } - - // view - public fun get_collection_name(collectionID: ObjectID, ctx: &mut Context): String{ - assert_collection_exist_of_id(collectionID, ctx); - let collection_object_ref = context::borrow_object(ctx, collectionID); - let collection_ref = object::borrow(collection_object_ref); - collection_ref.name - } - - public fun get_collection_uri(collectionID: ObjectID, ctx: &mut Context): String{ - assert_collection_exist_of_id(collectionID, ctx); - let collection_object_ref = context::borrow_object(ctx, collectionID); - let collection_ref = object::borrow(collection_object_ref); - collection_ref.uri - } - - public fun get_collection_creator(collectionID: ObjectID, ctx: &mut Context): address{ - assert_collection_exist_of_id(collectionID, ctx); - let collection_object_ref = context::borrow_object(ctx, collectionID); - let collection_ref = object::borrow(collection_object_ref); - collection_ref.creator - } - - public fun get_collection_current_supply(collectionID: ObjectID, ctx: &mut Context): u64{ - assert_collection_exist_of_id(collectionID, ctx); - let collection_object_ref = context::borrow_object(ctx, collectionID); - let collection_ref = object::borrow(collection_object_ref); - collection_ref.supply.current - } - - public fun get_collection_maximum_supply(collectionID: ObjectID, ctx: &mut Context): Option{ - assert_collection_exist_of_id(collectionID, ctx); - let collection_object_ref = context::borrow_object(ctx, collectionID); - let collection_ref = object::borrow(collection_object_ref); - collection_ref.supply.maximum - } - -} diff --git a/crates/rooch-framework/sources/nft/display.move b/crates/rooch-framework/sources/nft/display.move deleted file mode 100644 index 276673745d..0000000000 --- a/crates/rooch-framework/sources/nft/display.move +++ /dev/null @@ -1,43 +0,0 @@ -module rooch_framework::display{ - use std::string::String; - use moveos_std::simple_map; - - struct Display has key, store,drop,copy { - sample_map: simple_map::SimpleMap - } - - public fun new (): Display { - Display { - sample_map: simple_map::create() - } - } - - public fun set (self: &mut Display, key: String, value: String) { - simple_map::add(&mut self.sample_map, key, value); - } - - public fun borrow (self: &Display, key: &String): &String { - simple_map::borrow(&self.sample_map, key) - } - - public fun borrow_mut (self: &mut Display, key: &String): &mut String { - simple_map::borrow_mut(&mut self.sample_map, key) - } - - public fun remove (self: &mut Display, key: &String) { - simple_map::remove(&mut self.sample_map, key); - } - - public fun keys (self: & Display): vector { - simple_map::keys(& self.sample_map) - } - - public fun values (self: & Display): vector { - simple_map::values(& self.sample_map) - } - - public fun contains_key (self: & Display, key: &String): bool { - simple_map::contains_key(& self.sample_map, key) - } - -} \ No newline at end of file diff --git a/crates/rooch-framework/sources/nft/nft.move b/crates/rooch-framework/sources/nft/nft.move deleted file mode 100644 index 7977f45229..0000000000 --- a/crates/rooch-framework/sources/nft/nft.move +++ /dev/null @@ -1,348 +0,0 @@ -// Copyright (c) RoochNetwork -// SPDX-License-Identifier: Apache-2.0 - -module rooch_framework::nft { - use std::string::String; - use rooch_framework::display::Display; - use moveos_std::object_ref; - use moveos_std::object; - use rooch_framework::collection; - use moveos_std::object_ref::ObjectRef; - use moveos_std::context::Context; - use moveos_std::context; - use moveos_std::type_table; - use moveos_std::object::ObjectID; - use moveos_std::type_table::TypeTable; - #[test_only] - use std::option; - #[test_only] - use std::string; - #[test_only] - use rooch_framework::account; - #[test_only] - use rooch_framework::display; - - - const ErrorNftNotExist: u64 = 1; - const ErrorMutatorNotExist: u64 = 2; - const ErrorBurnerNotExist: u64 = 3; - - struct NFT has key { - name: String, - uri: String, - collection: ObjectID, - creator: address, - extend: TypeTable - } - - struct MutatorRef has key { - nft: ObjectID, - } - - struct BurnerRef has key { - nft: ObjectID, - } - - public fun mint( - name: String, - uri: String, - mutator_ref: &ObjectRef, - creator: address, - ctx: &mut Context - ): ObjectRef { - collection::assert_mutator_exist_of_ref(mutator_ref); - let nft = NFT { - name, - uri, - collection: collection::get_collection_id(mutator_ref), - creator, - extend: type_table::new(ctx) - }; - - collection::increment_supply(mutator_ref, ctx); - - let object_ref = context::new_object_with_owner( - ctx, - creator, - nft - ); - - object_ref - } - - public fun burn ( - burn_ref: &ObjectRef, - mutator_ref: &ObjectRef, - ctx: &mut Context - ) { - assert_burner_exist_of_ref(burn_ref); - let burner_object_ref = object_ref::borrow(burn_ref); - assert_nft_exist_of_id(burner_object_ref.nft, ctx); - collection::decrement_supply(mutator_ref, ctx); - let ( - _, - _, - NFT { - name:_, - uri:_, - collection:_, - creator:_, - extend - } - ) = context::remove_object(ctx, burner_object_ref.nft); - if(type_table::contains( &extend )){ - type_table::remove( &mut extend); - }; - type_table::destroy_empty(extend) - } - - public fun generate_mutator_ref(nft_object_ref: &ObjectRef, ctx: &mut Context):ObjectRef{ - let mutator_ref = context::new_object_with_owner( - ctx, - object_ref::owner(nft_object_ref), - MutatorRef { - nft: object_ref::id(nft_object_ref), - } - ); - mutator_ref - } - - public fun destroy_mutator_ref(mutator_ref :ObjectRef):ObjectID{ - assert_mutator_exist_of_ref(&mutator_ref); - let MutatorRef { - nft - } = object_ref::remove(mutator_ref); - nft - } - - public fun generate_burner_ref(nft_object_ref: &ObjectRef, ctx: &mut Context):ObjectRef{ - let burner_ref = context::new_object_with_owner( - ctx, - object_ref::owner(nft_object_ref), - BurnerRef { - nft: object_ref::id(nft_object_ref), - } - ); - burner_ref - } - - public fun destroy_burner_ref(burner_ref :ObjectRef):ObjectID{ - assert_burner_exist_of_ref(&burner_ref); - let BurnerRef { - nft - } = object_ref::remove(burner_ref); - nft - } - - // assert - public fun assert_nft_exist_of_id(objectId: ObjectID, ctx: &Context) { - assert!(context::exist_object(ctx, objectId), ErrorNftNotExist); - context::borrow_object(ctx, objectId); - } - - public fun assert_nft_exist_of_ref(nft_object_ref: &ObjectRef) { - assert!(object_ref::exist_object(nft_object_ref), ErrorNftNotExist); - } - - public fun assert_mutator_exist_of_ref(mutator_ref: &ObjectRef) { - assert!(object_ref::exist_object(mutator_ref), ErrorMutatorNotExist); - } - - public fun assert_mutator_exist_of_id(objectId: ObjectID, ctx: &Context) { - assert!(context::exist_object(ctx, objectId), ErrorMutatorNotExist); - context::borrow_object(ctx, objectId); - } - - public fun assert_burner_exist_of_ref(burner_ref: &ObjectRef) { - assert!(object_ref::exist_object(burner_ref), ErrorBurnerNotExist); - } - - public fun assert_burner_exist_of_id(objectId: ObjectID, ctx: &Context) { - assert!(context::exist_object(ctx, objectId), ErrorBurnerNotExist); - context::borrow_object(ctx, objectId); - } - - public fun add_display(mutator: &ObjectRef, display: Display, ctx: &mut Context){ - add_extend_internal(mutator, display, ctx); - } - - public fun borrow_display(mutator: &ObjectRef, ctx: &mut Context):&Display{ - borrow_extend_internal(mutator, ctx) - } - - public fun borrow_mut_display(mutator: &ObjectRef, ctx: &mut Context):&mut Display{ - borrow_mut_extend_internal(mutator, ctx) - } - - public fun remove_display(mutator: &ObjectRef, ctx: &mut Context):Display{ - remove_extend_internal(mutator, ctx) - } - - public fun contains_display(mutator: &ObjectRef, ctx: &mut Context): bool{ - contains_extend_internal(mutator, ctx) - } - - #[private_generics(V)] - public fun add_extend(mutator: &ObjectRef, val: V, ctx: &mut Context){ - add_extend_internal(mutator, val, ctx); - } - - public fun borrow_extend(mutator: &ObjectRef, ctx: &mut Context):&V{ - borrow_extend_internal(mutator, ctx) - } - - #[private_generics(V)] - public fun borrow_mut_extend(mutator: &ObjectRef, ctx: &mut Context):&mut V{ - borrow_mut_extend_internal(mutator, ctx) - } - - #[private_generics(V)] - public fun remove_extend(mutator: &ObjectRef, ctx: &mut Context):V{ - remove_extend_internal(mutator, ctx) - } - - public fun contains_extend(mutator: &ObjectRef, ctx: &mut Context): bool{ - contains_extend_internal(mutator, ctx) - } - - - fun add_extend_internal(mutator: &ObjectRef,val: V,ctx: &mut Context) { - assert_mutator_exist_of_ref(mutator); - let mutator_object_ref = object_ref::borrow(mutator); - assert_nft_exist_of_id(mutator_object_ref.nft, ctx); - let nft_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.nft); - let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); - type_table::add( &mut nft_mut_ref.extend, val); - } - - fun borrow_extend_internal(mutator: &ObjectRef,ctx: &Context): &V { - assert_mutator_exist_of_ref(mutator); - let mutator_object_ref = object_ref::borrow(mutator); - assert_nft_exist_of_id(mutator_object_ref.nft, ctx); - let nft_object_ref = context::borrow_object(ctx, mutator_object_ref.nft); - let nft_mut_ref = object::borrow(nft_object_ref); - type_table::borrow(&nft_mut_ref.extend) - } - - fun borrow_mut_extend_internal(mutator: &ObjectRef,ctx: &mut Context): &mut V { - assert_mutator_exist_of_ref(mutator); - let mutator_object_ref = object_ref::borrow(mutator); - assert_nft_exist_of_id(mutator_object_ref.nft, ctx); - let nft_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.nft); - let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); - type_table::borrow_mut(&mut nft_mut_ref.extend) - } - - fun remove_extend_internal(mutator: &ObjectRef,ctx: &mut Context):V { - assert_mutator_exist_of_ref(mutator); - let mutator_object_ref = object_ref::borrow(mutator); - assert_nft_exist_of_id(mutator_object_ref.nft, ctx); - let nft_object_mut_ref = context::borrow_object_mut(ctx, mutator_object_ref.nft); - let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); - type_table::remove(&mut nft_mut_ref.extend) - } - - fun contains_extend_internal(mutator: &ObjectRef,ctx: &Context): bool { - assert_mutator_exist_of_ref(mutator); - let mutator_object_ref = object_ref::borrow(mutator); - assert_nft_exist_of_id(mutator_object_ref.nft, ctx); - let nft_object_ref = context::borrow_object(ctx, mutator_object_ref.nft); - let nft_mut_ref = object::borrow(nft_object_ref); - type_table::contains(&nft_mut_ref.extend) - } - - // view - - public fun get_name(objectId: ObjectID, ctx: &Context): String { - assert_nft_exist_of_id(objectId, ctx); - let nft_object_ref = context::borrow_object(ctx, objectId); - let nft = object::borrow(nft_object_ref); - nft.name - } - - public fun get_uri(objectId: ObjectID, ctx: &Context): String { - assert_nft_exist_of_id(objectId, ctx); - let nft_object_ref = context::borrow_object(ctx, objectId); - let nft = object::borrow(nft_object_ref); - nft.uri - } - - public fun get_collection(objectId: ObjectID, ctx: &Context): ObjectID { - assert_nft_exist_of_id(objectId, ctx); - let nft_object_ref = context::borrow_object(ctx, objectId); - let nft = object::borrow(nft_object_ref); - nft.collection - } - - public fun get_creator(objectId: ObjectID, ctx: &Context): address { - assert_nft_exist_of_id(objectId, ctx); - let nft_object_ref = context::borrow_object(ctx, objectId); - let nft = object::borrow(nft_object_ref); - nft.creator - } - - #[test(sender = @0x2)] - public fun test_create_nft (sender: address){ - let storage_context = context::new_test_context(sender); - let ctx = &mut storage_context; - account::create_account_for_test(ctx, sender); - - let collection_object_ref = collection::create_collection( - string::utf8(b"name"), - string::utf8(b"uri"), - sender, - string::utf8(b"description"), - option::none(), - ctx - ); - - let collection_mutator_ref = collection::generate_mutator_ref(&collection_object_ref, ctx); - - let collcetion_display = display::new(); - display::set(&mut collcetion_display, string::utf8(b"name"), string::utf8(b"{ name }")); - display::set(&mut collcetion_display, string::utf8(b"uri"), string::utf8(b"{ uri }")); - display::set(&mut collcetion_display, string::utf8(b"description"), string::utf8(b"{ description }")); - display::set(&mut collcetion_display, string::utf8(b"creator"), string::utf8(b"{ creator }")); - display::set(&mut collcetion_display, string::utf8(b"supply"), string::utf8(b"{ supply }")); - - collection::add_display( - &collection_mutator_ref, - collcetion_display, - ctx - ); - - let nft_object_ref = mint( - string::utf8(b"name"), - string::utf8(b"uri"), - &collection_mutator_ref, - sender, - ctx - ); - - let nft_display = display::new(); - display::set(&mut nft_display, string::utf8(b"name"), string::utf8(b"{ name }")); - display::set(&mut nft_display, string::utf8(b"uri"), string::utf8(b"{ uri }/{ name }.png")); - display::set(&mut nft_display, string::utf8(b"collection"), string::utf8(b"{ collection }")); - - let nft_mutaor_ref = generate_mutator_ref(&nft_object_ref, ctx); - add_display( - &nft_mutaor_ref, - nft_display, - ctx - ); - - let burner_ref = generate_burner_ref(&nft_object_ref, ctx); - - remove_display(&nft_mutaor_ref, ctx); - burn(&burner_ref, &collection_mutator_ref, ctx); - - collection::remove_display(&collection_mutator_ref, ctx); - collection::destroy_mutator_ref(collection_mutator_ref); - - destroy_mutator_ref(nft_mutaor_ref); - destroy_burner_ref(burner_ref); - - context::drop_test_context(storage_context); - } - -} \ No newline at end of file diff --git a/examples/nft/Move.toml b/examples/nft/Move.toml new file mode 100644 index 0000000000..1e18be048b --- /dev/null +++ b/examples/nft/Move.toml @@ -0,0 +1,17 @@ +[package] +name = "nft" +version = "0.0.1" + +[dependencies] +MoveStdlib = { local = "../../moveos/moveos-stdlib/move-stdlib" } +MoveosStdlib = { local = "../../moveos/moveos-stdlib/moveos-stdlib" } +RoochFramework = { local = "../../crates/rooch-framework" } + +[addresses] +creator = "_" +std = "0x1" +moveos_std = "0x2" +rooch_framework = "0x3" + +[dev-addresses] +creator = "0x42" \ No newline at end of file diff --git a/examples/nft/README.md b/examples/nft/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/examples/nft/sources/collection.move b/examples/nft/sources/collection.move new file mode 100644 index 0000000000..7991cbc91e --- /dev/null +++ b/examples/nft/sources/collection.move @@ -0,0 +1,240 @@ +// Copyright (c) RoochNetwork +// SPDX-License-Identifier: Apache-2.0 + +module creator::collection{ + use std::option; + use std::option::Option; + use std::string::String; + use moveos_std::object::ObjectID; + use moveos_std::object_ref; + use moveos_std::event; + use moveos_std::context; + use moveos_std::context::Context; + use moveos_std::object; + use moveos_std::object_ref::ObjectRef; + use moveos_std::type_table; + + friend creator::nft; + + const ErrorMutatorNotExist: u64 = 1; + const ErrorCollectionNotExist: u64 = 2; + const ErrorCollectionMaximumSupply: u64 = 3; + + struct Collection has key{ + name: String, + uri: String, + creator: address, + supply: Supply, + extend: type_table::TypeTable + } + + struct Supply has store{ + current: u64, + maximum: Option, + } + + struct MutatorRef has key,store{ + collection: ObjectID, + } + + // event + struct CreateCollectionEvent{ + objectID: ObjectID, + name: String, + uri: String, + creator: address, + maximum: Option, + description: String, + } + + #[private_generics(T)] + public fun create_collection( + name: String, + uri: String, + creator: address, + description: String, + max_supply: Option, + ctx: &mut Context + ):ObjectRef> { + + let collection = Collection { + name, + uri, + creator, + supply: Supply { + current: 0, + maximum: max_supply, + }, + extend: type_table::new(ctx) + }; + + let object_ref = context::new_object_with_owner( + ctx, + creator, + collection + ); + + event::emit( + ctx, + CreateCollectionEvent { + objectID: object_ref::id(&object_ref), + name, + uri, + creator, + maximum: max_supply, + description, + } + ); + object_ref + } + + public fun generate_mutator_ref(collection: &ObjectRef>):MutatorRef{ + MutatorRef { + collection: object_ref::id(collection), + } + } + + public fun destroy_mutator_ref(mutator_ref :MutatorRef):ObjectID{ + let MutatorRef { + collection, + } = mutator_ref; + collection + } + + public fun get_collection_id(mutator: &MutatorRef): ObjectID{ + mutator.collection + } + + + public(friend) fun increment_supply(mutator: &MutatorRef, ctx: &mut Context): Option{ + assert_collection_exist_of_id(mutator.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut>(ctx, mutator.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + collection_mut_ref.supply.current = collection_mut_ref.supply.current + 1; + if(option::is_some(&collection_mut_ref.supply.maximum)){ + assert!(collection_mut_ref.supply.current <= *option::borrow(&collection_mut_ref.supply.maximum), ErrorCollectionMaximumSupply); + option::some(collection_mut_ref.supply.current) + }else{ + option::none() + } + } + + public (friend) fun decrement_supply(mutator: &MutatorRef, ctx: &mut Context): Option{ + assert_collection_exist_of_id(mutator.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut>(ctx, mutator.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + collection_mut_ref.supply.current = collection_mut_ref.supply.current - 1; + if(option::is_some(&collection_mut_ref.supply.maximum)){ + option::some(collection_mut_ref.supply.current) + }else{ + option::none() + } + } + + // assert + public fun assert_collection_exist_of_ref(collectionRef: &ObjectRef>){ + assert!( object_ref::exist_object(collectionRef), ErrorCollectionNotExist); + } + + public fun assert_collection_exist_of_id(collectionID: ObjectID, ctx: & Context){ + assert!( context::exist_object(ctx, collectionID), ErrorCollectionNotExist); + context::borrow_object>(ctx,collectionID); + } + + #[private_generics(V)] + public fun add_extend(mutator: &MutatorRef, val: V, ctx: &mut Context){ + add_extend_internal(mutator, val, ctx); + } + + #[private_generics(V)] + public fun borrow_extend(mutator: &MutatorRef, ctx: &mut Context):&V{ + borrow_extend_internal(mutator, ctx) + } + + #[private_generics(V)] + public fun borrow_mut_extend(mutator: &MutatorRef, ctx: &mut Context):&mut V{ + borrow_mut_extend_internal(mutator, ctx) + } + + #[private_generics(V)] + public fun remove_extend(mutator: &MutatorRef, ctx: &mut Context):V{ + remove_extend_internal(mutator, ctx) + } + + public fun contains_extend(mutator: &MutatorRef, ctx: &mut Context): bool{ + contains_extend_internal(mutator, ctx) + } + + + fun add_extend_internal(mutator: &MutatorRef,val: V,ctx: &mut Context){ + assert_collection_exist_of_id(mutator.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut>(ctx, mutator.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + type_table::add( &mut collection_mut_ref.extend, val); + } + + fun borrow_extend_internal(mutator: &MutatorRef, ctx: &mut Context):&V{ + assert_collection_exist_of_id(mutator.collection, ctx); + let collection_object_ref = context::borrow_object>(ctx, mutator.collection); + let collection_ref = object::borrow(collection_object_ref); + type_table::borrow(&collection_ref.extend) + } + + fun borrow_mut_extend_internal(mutator: &MutatorRef, ctx: &mut Context):&mut V{ + assert_collection_exist_of_id(mutator.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut>(ctx, mutator.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + type_table::borrow_mut(&mut collection_mut_ref.extend) + } + + fun remove_extend_internal(mutator: &MutatorRef, ctx: &mut Context):V{ + assert_collection_exist_of_id(mutator.collection, ctx); + let collection_object_mut_ref = context::borrow_object_mut>(ctx, mutator.collection); + let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); + type_table::remove(&mut collection_mut_ref.extend) + } + + fun contains_extend_internal(mutator: &MutatorRef, ctx: &mut Context): bool{ + assert_collection_exist_of_id(mutator.collection, ctx); + let collection_object_ref = context::borrow_object>(ctx, mutator.collection); + let collection_ref = object::borrow(collection_object_ref); + type_table::contains(&collection_ref.extend) + } + + // view + public fun get_collection_name(collectionID: ObjectID, ctx: &mut Context): String{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object>(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.name + } + + public fun get_collection_uri(collectionID: ObjectID, ctx: &mut Context): String{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object>(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.uri + } + + public fun get_collection_creator(collectionID: ObjectID, ctx: &mut Context): address{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object>(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.creator + } + + public fun get_collection_current_supply(collectionID: ObjectID, ctx: &mut Context): u64{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object>(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.supply.current + } + + public fun get_collection_maximum_supply(collectionID: ObjectID, ctx: &mut Context): Option{ + assert_collection_exist_of_id(collectionID, ctx); + let collection_object_ref = context::borrow_object>(ctx, collectionID); + let collection_ref = object::borrow(collection_object_ref); + collection_ref.supply.maximum + } + +} diff --git a/examples/nft/sources/nft.move b/examples/nft/sources/nft.move new file mode 100644 index 0000000000..076fa743ac --- /dev/null +++ b/examples/nft/sources/nft.move @@ -0,0 +1,270 @@ +// Copyright (c) RoochNetwork +// SPDX-License-Identifier: Apache-2.0 + +module creator::nft { + use std::string::String; + use rooch_framework::display::Display; + use moveos_std::object_ref; + use moveos_std::object; + use creator::collection; + use moveos_std::object_ref::ObjectRef; + use moveos_std::context::Context; + use moveos_std::context; + use moveos_std::type_table; + use moveos_std::object::ObjectID; + use moveos_std::type_table::TypeTable; + #[test_only] + use std::option; + #[test_only] + use std::string; + #[test_only] + use rooch_framework::account; + #[test_only] + use rooch_framework::display; + + + const ErrorNftNotExist: u64 = 1; + const ErrorMutatorNotExist: u64 = 2; + const ErrorBurnerNotExist: u64 = 3; + + struct NFT has key,store { + name: String, + uri: String, + collection: ObjectID, + creator: address, + extend: TypeTable + } + + struct MutatorRef has key,store { + nft: ObjectID, + } + + struct BurnerRef has key,store { + nft: ObjectID, + } + + #[private_generics(T)] + public fun mint( + name: String, + uri: String, + mutator_ref: &collection::MutatorRef, + creator: address, + ctx: &mut Context + ): ObjectRef> { + let nft = NFT { + name, + uri, + collection: collection::get_collection_id(mutator_ref), + creator, + extend: type_table::new(ctx) + }; + + collection::increment_supply(mutator_ref, ctx); + + let object_ref = context::new_object_with_owner( + ctx, + creator, + nft + ); + + object_ref + } + + public fun burn ( + burn_ref: &BurnerRef, + mutator_ref: & collection::MutatorRef, + ctx: &mut Context + ) { + assert_nft_exist_of_id(burn_ref.nft, ctx); + collection::decrement_supply(mutator_ref, ctx); + let ( + _, + _, + NFT { + name:_, + uri:_, + collection:_, + creator:_, + extend + } + ) = context::remove_object>(ctx, burn_ref.nft); + if(type_table::contains>( &extend )){ + type_table::remove>( &mut extend); + }; + type_table::destroy_empty(extend) + } + + public fun generate_mutator_ref(nft_object_ref: &ObjectRef>):MutatorRef{ + MutatorRef { + nft: object_ref::id(nft_object_ref), + } + } + + public fun destroy_mutator_ref(mutator_ref :MutatorRef):ObjectID{ + let MutatorRef { + nft + } = mutator_ref ; + nft + } + + public fun generate_burner_ref(nft_object_ref: &ObjectRef>):BurnerRef{ + BurnerRef { + nft: object_ref::id(nft_object_ref), + } + } + + public fun destroy_burner_ref(burner_ref :BurnerRef):ObjectID{ + let BurnerRef { + nft + } = burner_ref; + nft + } + + // assert + public fun assert_nft_exist_of_id(objectId: ObjectID, ctx: &Context) { + assert!(context::exist_object(ctx, objectId), ErrorNftNotExist); + context::borrow_object>(ctx, objectId); + } + + public fun assert_nft_exist_of_ref(nft_object_ref: &ObjectRef>) { + assert!(object_ref::exist_object(nft_object_ref), ErrorNftNotExist); + } + + #[private_generics(V)] + public fun add_extend(mutator: &MutatorRef, val: V, ctx: &mut Context){ + add_extend_internal(mutator, val, ctx); + } + + public fun borrow_extend(mutator: &MutatorRef, ctx: &mut Context):&V{ + borrow_extend_internal(mutator, ctx) + } + + #[private_generics(V)] + public fun borrow_mut_extend(mutator: &MutatorRef, ctx: &mut Context):&mut V{ + borrow_mut_extend_internal(mutator, ctx) + } + + #[private_generics(V)] + public fun remove_extend(mutator: &MutatorRef, ctx: &mut Context):V{ + remove_extend_internal(mutator, ctx) + } + + public fun contains_extend(mutator: &MutatorRef, ctx: &mut Context): bool{ + contains_extend_internal(mutator, ctx) + } + + + fun add_extend_internal(mutator: &MutatorRef,val: V,ctx: &mut Context) { + let nft_object_mut_ref = context::borrow_object_mut>(ctx, mutator.nft); + let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); + type_table::add( &mut nft_mut_ref.extend, val); + } + + fun borrow_extend_internal(mutator: &MutatorRef,ctx: &Context): &V { + let nft_object_ref = context::borrow_object>(ctx, mutator.nft); + let nft_mut_ref = object::borrow(nft_object_ref); + type_table::borrow(&nft_mut_ref.extend) + } + + fun borrow_mut_extend_internal(mutator: &MutatorRef,ctx: &mut Context): &mut V { + let nft_object_mut_ref = context::borrow_object_mut>(ctx, mutator.nft); + let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); + type_table::borrow_mut(&mut nft_mut_ref.extend) + } + + fun remove_extend_internal(mutator: &MutatorRef,ctx: &mut Context):V { + let nft_object_mut_ref = context::borrow_object_mut>(ctx, mutator.nft); + let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); + type_table::remove(&mut nft_mut_ref.extend) + } + + fun contains_extend_internal(mutator: &MutatorRef,ctx: &Context): bool { + let nft_object_ref = context::borrow_object>(ctx, mutator.nft); + let nft_mut_ref = object::borrow(nft_object_ref); + type_table::contains(&nft_mut_ref.extend) + } + + // view + + public fun get_name(objectId: ObjectID, ctx: &Context): String { + assert_nft_exist_of_id(objectId, ctx); + let nft_object_ref = context::borrow_object>(ctx, objectId); + let nft = object::borrow(nft_object_ref); + nft.name + } + + public fun get_uri(objectId: ObjectID, ctx: &Context): String { + assert_nft_exist_of_id(objectId, ctx); + let nft_object_ref = context::borrow_object>(ctx, objectId); + let nft = object::borrow(nft_object_ref); + nft.uri + } + + public fun get_collection(objectId: ObjectID, ctx: &Context): ObjectID { + assert_nft_exist_of_id(objectId, ctx); + let nft_object_ref = context::borrow_object>(ctx, objectId); + let nft = object::borrow(nft_object_ref); + nft.collection + } + + public fun get_creator(objectId: ObjectID, ctx: &Context): address { + assert_nft_exist_of_id(objectId, ctx); + let nft_object_ref = context::borrow_object>(ctx, objectId); + let nft = object::borrow(nft_object_ref); + nft.creator + } + + #[test_only] + struct Test has key {} + + + #[test(sender = @0x2)] + public fun test_create_nft (sender: address){ + let storage_context = context::new_test_context(sender); + let ctx = &mut storage_context; + account::create_account_for_test(ctx, sender); + + let collection_object_ref = collection::create_collection( + string::utf8(b"name"), + string::utf8(b"uri"), + sender, + string::utf8(b"description"), + option::none(), + ctx + ); + + let collection_mutator_ref = collection::generate_mutator_ref(&collection_object_ref); + + let collcetion_display = display::new(ctx); + display::set(&mut collcetion_display, string::utf8(b"name"), string::utf8(b"{ name }")); + display::set(&mut collcetion_display, string::utf8(b"uri"), string::utf8(b"{ uri }")); + display::set(&mut collcetion_display, string::utf8(b"description"), string::utf8(b"{ description }")); + display::set(&mut collcetion_display, string::utf8(b"creator"), string::utf8(b"{ creator }")); + display::set(&mut collcetion_display, string::utf8(b"supply"), string::utf8(b"{ supply }")); + + + let nft_object_ref = mint( + string::utf8(b"name"), + string::utf8(b"uri"), + &collection_mutator_ref, + sender, + ctx + ); + + let nft_mutaor_ref = generate_mutator_ref(&nft_object_ref); + + + let burner_ref = generate_burner_ref(&nft_object_ref); + + + burn(&burner_ref, &collection_mutator_ref, ctx); + + collection::destroy_mutator_ref(collection_mutator_ref); + + destroy_mutator_ref(nft_mutaor_ref); + destroy_burner_ref(burner_ref); + + context::drop_test_context(storage_context); + } + +} \ No newline at end of file diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/context.md b/moveos/moveos-stdlib/moveos-stdlib/doc/context.md index 1ff0bc4fe5..7f6adebae6 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/context.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/context.md @@ -28,6 +28,7 @@ and let developers customize the storage - [Function `new_object`](#0x2_context_new_object) - [Function `new_object_with_owner`](#0x2_context_new_object_with_owner) - [Function `new_object_with_id`](#0x2_context_new_object_with_id) +- [Function `new_single_object`](#0x2_context_new_single_object)
use 0x1::option;
@@ -37,6 +38,7 @@ and let developers customize the storage
 use 0x2::tx_context;
 use 0x2::tx_meta;
 use 0x2::tx_result;
+use 0x2::type_info;
 
@@ -557,4 +559,29 @@ Add the Object to the global object storage and return the ObjectRef + + + + +## Function `new_single_object` + + + +
public fun new_single_object<T: key>(self: &mut context::Context, value: T): object_ref::ObjectRef<T>
+
+ + + +
+Implementation + + +
public fun new_single_object<T: key>(self: &mut Context, value: T): ObjectRef<T> {
+    let object_id = object::singleton_object_id<T>();
+    new_object_with_id(self, object_id, type_info::account_address(&type_info::type_of<T>()), value)
+}
+
+ + +
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/object.md b/moveos/moveos-stdlib/moveos-stdlib/doc/object.md index bdb46c7c27..0908662a47 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/object.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/object.md @@ -13,6 +13,7 @@ The differents with the Object in [Sui](https://github.com/MystenLabs/sui/blob/5 - [Struct `Object`](#0x2_object_Object) - [Struct `ObjectID`](#0x2_object_ObjectID) - [Function `address_to_object_id`](#0x2_object_address_to_object_id) +- [Function `singleton_object_id`](#0x2_object_singleton_object_id) - [Function `new`](#0x2_object_new) - [Function `borrow`](#0x2_object_borrow) - [Function `internal_borrow`](#0x2_object_internal_borrow) @@ -25,7 +26,11 @@ The differents with the Object in [Sui](https://github.com/MystenLabs/sui/blob/5 - [Function `unpack_internal`](#0x2_object_unpack_internal) -
+
use 0x1::hash;
+use 0x2::address;
+use 0x2::bcs;
+use 0x2::type_info;
+
@@ -121,6 +126,38 @@ Generate a new ObjectID from an address + + + + +## Function `singleton_object_id` + + + +
public(friend) fun singleton_object_id<T>(): object::ObjectID
+
+ + + +
+Implementation + + +
public(friend) fun singleton_object_id<T>(): ObjectID {
+    address_to_object_id(
+        address::from_bytes(
+            hash::sha3_256(
+                bcs::to_bytes(
+                    &type_info::type_of<T>()
+                )
+            )
+        )
+    )
+}
+
+ + +
diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/context.move b/moveos/moveos-stdlib/moveos-stdlib/sources/context.move index 44d1d97e1a..ace37b1f90 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/context.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/context.move @@ -7,6 +7,7 @@ module moveos_std::context { use std::option::Option; + use moveos_std::type_info; use moveos_std::storage_context::{Self, StorageContext}; use moveos_std::tx_context::{Self, TxContext}; use moveos_std::object::{Self, Object, ObjectID}; @@ -142,6 +143,12 @@ module moveos_std::context { obj_ref } + #[private_generics(T)] + public fun new_single_object(self: &mut Context, value: T): ObjectRef { + let object_id = object::singleton_object_id(); + new_object_with_id(self, object_id, type_info::account_address(&type_info::type_of()), value) + } + #[test_only] /// Create a Context for unit test public fun new_test_context(sender: address): Context { diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/object.move b/moveos/moveos-stdlib/moveos-stdlib/sources/object.move index 3a94b45469..91671cf4cd 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/object.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/object.move @@ -7,8 +7,11 @@ /// 1. The Object is a struct in Move /// 2. The Object is a use case of the Hot Potato pattern in Move. Objects do not have any ability, so they cannot be drop, copy, or store, and can only be handled by StorageContext API after creation. module moveos_std::object { - - + + use std::hash; + use moveos_std::type_info; + use moveos_std::bcs; + use moveos_std::address; friend moveos_std::context; friend moveos_std::account_storage; friend moveos_std::storage_context; @@ -39,6 +42,18 @@ module moveos_std::object { ObjectID { id: address } } + public(friend) fun singleton_object_id(): ObjectID { + address_to_object_id( + address::from_bytes( + hash::sha3_256( + bcs::to_bytes( + &type_info::type_of() + ) + ) + ) + ) + } + /// Create a new object, the object is owned by `owner` public(friend) fun new(id: ObjectID, owner: address, value: T): Object { Object{id, value, owner} From 915619d00f2cd11adfa2d3469d4b2ff1aa49e611 Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Fri, 20 Oct 2023 01:59:23 +0800 Subject: [PATCH 15/17] Singleton Object Display and NFT example --- examples/nft/sources/collection.move | 10 ++++-- examples/nft/sources/nft.move | 54 ++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/examples/nft/sources/collection.move b/examples/nft/sources/collection.move index 7991cbc91e..739c272101 100644 --- a/examples/nft/sources/collection.move +++ b/examples/nft/sources/collection.move @@ -5,6 +5,8 @@ module creator::collection{ use std::option; use std::option::Option; use std::string::String; + use rooch_framework::display; + use rooch_framework::display::Display; use moveos_std::object::ObjectID; use moveos_std::object_ref; use moveos_std::event; @@ -37,7 +39,6 @@ module creator::collection{ collection: ObjectID, } - // event struct CreateCollectionEvent{ objectID: ObjectID, name: String, @@ -47,8 +48,7 @@ module creator::collection{ description: String, } - #[private_generics(T)] - public fun create_collection( + public(friend) fun create_collection( name: String, uri: String, creator: address, @@ -94,6 +94,10 @@ module creator::collection{ } } + public(friend) fun new_display(ctx: &mut Context):ObjectRef>>{ + display::new>(ctx) + } + public fun destroy_mutator_ref(mutator_ref :MutatorRef):ObjectID{ let MutatorRef { collection, diff --git a/examples/nft/sources/nft.move b/examples/nft/sources/nft.move index 076fa743ac..4b926317fb 100644 --- a/examples/nft/sources/nft.move +++ b/examples/nft/sources/nft.move @@ -2,7 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 module creator::nft { + use std::option::{Option}; use std::string::String; + use creator::collection::Collection; + use rooch_framework::display; use rooch_framework::display::Display; use moveos_std::object_ref; use moveos_std::object; @@ -19,9 +22,6 @@ module creator::nft { use std::string; #[test_only] use rooch_framework::account; - #[test_only] - use rooch_framework::display; - const ErrorNftNotExist: u64 = 1; const ErrorMutatorNotExist: u64 = 2; @@ -43,6 +43,29 @@ module creator::nft { nft: ObjectID, } + #[private_generics(T)] + public fun create_collection( + name: String, + uri: String, + creator: address, + description: String, + supply: Option, + ctx: &mut Context + ):(ObjectRef>,ObjectRef>>,ObjectRef>>) { + let collection_object_ref = collection::create_collection( + name, + uri, + creator, + description, + supply, + ctx + ); + let collection_display_object_ref = collection::new_display(ctx); + let nft_display_object_ref = display::new>(ctx); + + (collection_object_ref, collection_display_object_ref, nft_display_object_ref) + } + #[private_generics(T)] public fun mint( name: String, @@ -153,7 +176,6 @@ module creator::nft { contains_extend_internal(mutator, ctx) } - fun add_extend_internal(mutator: &MutatorRef,val: V,ctx: &mut Context) { let nft_object_mut_ref = context::borrow_object_mut>(ctx, mutator.nft); let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); @@ -217,14 +239,17 @@ module creator::nft { #[test_only] struct Test has key {} - - #[test(sender = @0x2)] + #[test(sender = @creator)] public fun test_create_nft (sender: address){ let storage_context = context::new_test_context(sender); let ctx = &mut storage_context; account::create_account_for_test(ctx, sender); - let collection_object_ref = collection::create_collection( + let ( + collection_object_ref, + collection_display_object_ref, + nft_display_object_ref + ) = create_collection( string::utf8(b"name"), string::utf8(b"uri"), sender, @@ -235,13 +260,14 @@ module creator::nft { let collection_mutator_ref = collection::generate_mutator_ref(&collection_object_ref); - let collcetion_display = display::new(ctx); - display::set(&mut collcetion_display, string::utf8(b"name"), string::utf8(b"{ name }")); - display::set(&mut collcetion_display, string::utf8(b"uri"), string::utf8(b"{ uri }")); - display::set(&mut collcetion_display, string::utf8(b"description"), string::utf8(b"{ description }")); - display::set(&mut collcetion_display, string::utf8(b"creator"), string::utf8(b"{ creator }")); - display::set(&mut collcetion_display, string::utf8(b"supply"), string::utf8(b"{ supply }")); + display::set(&mut collection_display_object_ref, string::utf8(b"name"), string::utf8(b"{ name }")); + display::set(&mut collection_display_object_ref, string::utf8(b"uri"), string::utf8(b"{ uri }")); + display::set(&mut collection_display_object_ref, string::utf8(b"description"), string::utf8(b"{ description }")); + display::set(&mut collection_display_object_ref, string::utf8(b"creator"), string::utf8(b"{ creator }")); + display::set(&mut collection_display_object_ref, string::utf8(b"supply"), string::utf8(b"{ supply }")); + display::set(&mut nft_display_object_ref, string::utf8(b"name"), string::utf8(b"{ name }")); + display::set(&mut nft_display_object_ref, string::utf8(b"uri"), string::utf8(b"{ uri }")); let nft_object_ref = mint( string::utf8(b"name"), @@ -253,10 +279,8 @@ module creator::nft { let nft_mutaor_ref = generate_mutator_ref(&nft_object_ref); - let burner_ref = generate_burner_ref(&nft_object_ref); - burn(&burner_ref, &collection_mutator_ref, ctx); collection::destroy_mutator_ref(collection_mutator_ref); From ba12bf6922b01295cfd6e24b7963724eb0d895dd Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Fri, 20 Oct 2023 02:03:34 +0800 Subject: [PATCH 16/17] fix context singleton object create function --- crates/rooch-framework/doc/display.md | 2 +- crates/rooch-framework/sources/display.move | 2 +- moveos/moveos-stdlib/moveos-stdlib/doc/context.md | 10 +++++----- .../moveos-stdlib/moveos-stdlib/sources/context.move | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/rooch-framework/doc/display.md b/crates/rooch-framework/doc/display.md index 9d36b6738e..d9e563b594 100644 --- a/crates/rooch-framework/doc/display.md +++ b/crates/rooch-framework/doc/display.md @@ -67,7 +67,7 @@
public fun new<T>(ctx: &mut Context): ObjectRef<Display<T>> {
-    context::new_single_object(ctx, Display<T> {
+    context::new_singleton_object(ctx, Display<T> {
         sample_map: simple_map::create()
     })
 }
diff --git a/crates/rooch-framework/sources/display.move b/crates/rooch-framework/sources/display.move
index b7963d88f5..3fb5223385 100644
--- a/crates/rooch-framework/sources/display.move
+++ b/crates/rooch-framework/sources/display.move
@@ -11,7 +11,7 @@ module rooch_framework::display{
     }
 
     public fun new(ctx: &mut Context): ObjectRef> {
-        context::new_single_object(ctx, Display {
+        context::new_singleton_object(ctx, Display {
             sample_map: simple_map::create()
         })
     }
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/context.md b/moveos/moveos-stdlib/moveos-stdlib/doc/context.md
index 7f6adebae6..238f5472f0 100644
--- a/moveos/moveos-stdlib/moveos-stdlib/doc/context.md
+++ b/moveos/moveos-stdlib/moveos-stdlib/doc/context.md
@@ -28,7 +28,7 @@ and let developers customize the storage
 -  [Function `new_object`](#0x2_context_new_object)
 -  [Function `new_object_with_owner`](#0x2_context_new_object_with_owner)
 -  [Function `new_object_with_id`](#0x2_context_new_object_with_id)
--  [Function `new_single_object`](#0x2_context_new_single_object)
+-  [Function `new_singleton_object`](#0x2_context_new_singleton_object)
 
 
 
use 0x1::option;
@@ -561,13 +561,13 @@ Add the Object to the global object storage and return the ObjectRef
 
 
 
-
+
 
-## Function `new_single_object`
+## Function `new_singleton_object`
 
 
 
-
public fun new_single_object<T: key>(self: &mut context::Context, value: T): object_ref::ObjectRef<T>
+
public fun new_singleton_object<T: key>(self: &mut context::Context, value: T): object_ref::ObjectRef<T>
 
@@ -576,7 +576,7 @@ Add the Object to the global object storage and return the ObjectRef Implementation -
public fun new_single_object<T: key>(self: &mut Context, value: T): ObjectRef<T> {
+
public fun new_singleton_object<T: key>(self: &mut Context, value: T): ObjectRef<T> {
     let object_id = object::singleton_object_id<T>();
     new_object_with_id(self, object_id, type_info::account_address(&type_info::type_of<T>()), value)
 }
diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/context.move b/moveos/moveos-stdlib/moveos-stdlib/sources/context.move
index ace37b1f90..1cfde4e72a 100644
--- a/moveos/moveos-stdlib/moveos-stdlib/sources/context.move
+++ b/moveos/moveos-stdlib/moveos-stdlib/sources/context.move
@@ -144,7 +144,7 @@ module moveos_std::context {
     }
 
     #[private_generics(T)]
-    public fun new_single_object(self: &mut Context, value: T): ObjectRef {
+    public fun new_singleton_object(self: &mut Context, value: T): ObjectRef {
         let object_id = object::singleton_object_id();
         new_object_with_id(self, object_id, type_info::account_address(&type_info::type_of()), value)
     }

From a4799b422558b17961b62083438dfb4a38e3e02c Mon Sep 17 00:00:00 2001
From: WGB5445 <919603023@qq.com>
Date: Fri, 20 Oct 2023 21:51:49 +0800
Subject: [PATCH 17/17] fix examples name_address

---
 examples/nft/Move.toml               |  7 ++-----
 examples/nft/sources/collection.move | 16 ++++++----------
 examples/nft/sources/nft.move        | 21 ++++++++-------------
 3 files changed, 16 insertions(+), 28 deletions(-)

diff --git a/examples/nft/Move.toml b/examples/nft/Move.toml
index 1e18be048b..2142484e39 100644
--- a/examples/nft/Move.toml
+++ b/examples/nft/Move.toml
@@ -8,10 +8,7 @@ MoveosStdlib = { local = "../../moveos/moveos-stdlib/moveos-stdlib" }
 RoochFramework = { local = "../../crates/rooch-framework" }
 
 [addresses]
-creator =  "_"
-std =  "0x1"
-moveos_std =  "0x2"
-rooch_framework =  "0x3"
+nft =  "_"
 
 [dev-addresses]
-creator = "0x42"
\ No newline at end of file
+nft = "0x42"
\ No newline at end of file
diff --git a/examples/nft/sources/collection.move b/examples/nft/sources/collection.move
index 739c272101..2d6844deeb 100644
--- a/examples/nft/sources/collection.move
+++ b/examples/nft/sources/collection.move
@@ -1,22 +1,18 @@
 // Copyright (c) RoochNetwork
 // SPDX-License-Identifier: Apache-2.0
 
-module creator::collection{
+module nft::collection{
     use std::option;
     use std::option::Option;
     use std::string::String;
-    use rooch_framework::display;
-    use rooch_framework::display::Display;
-    use moveos_std::object::ObjectID;
-    use moveos_std::object_ref;
+    use rooch_framework::display::{Self, Display};
+    use moveos_std::object::{Self, ObjectID};
     use moveos_std::event;
-    use moveos_std::context;
-    use moveos_std::context::Context;
-    use moveos_std::object;
-    use moveos_std::object_ref::ObjectRef;
+    use moveos_std::context::{Self, Context};
+    use moveos_std::object_ref::{Self, ObjectRef};
     use moveos_std::type_table;
 
-    friend creator::nft;
+    friend nft::nft;
 
     const ErrorMutatorNotExist: u64 = 1;
     const ErrorCollectionNotExist: u64 = 2;
diff --git a/examples/nft/sources/nft.move b/examples/nft/sources/nft.move
index 4b926317fb..110c11bb87 100644
--- a/examples/nft/sources/nft.move
+++ b/examples/nft/sources/nft.move
@@ -1,20 +1,15 @@
 // Copyright (c) RoochNetwork
 // SPDX-License-Identifier: Apache-2.0
 
-module creator::nft {
-    use std::option::{Option};
+module nft::nft {
+    use std::option::Option;
     use std::string::String;
-    use creator::collection::Collection;
-    use rooch_framework::display;
-    use rooch_framework::display::Display;
-    use moveos_std::object_ref;
-    use moveos_std::object;
-    use creator::collection;
-    use moveos_std::object_ref::ObjectRef;
-    use moveos_std::context::Context;
-    use moveos_std::context;
+    use nft::collection::{Self, Collection};
+    use rooch_framework::display::{Self, Display};
+    use moveos_std::object_ref::{Self, ObjectRef};
+    use moveos_std::context::{Self, Context};
     use moveos_std::type_table;
-    use moveos_std::object::ObjectID;
+    use moveos_std::object::{Self, ObjectID};
     use moveos_std::type_table::TypeTable;
     #[test_only]
     use std::option;
@@ -239,7 +234,7 @@ module creator::nft {
     #[test_only]
     struct Test has key {}
 
-    #[test(sender = @creator)]
+    #[test(sender = @nft)]
     public fun test_create_nft (sender: address){
         let storage_context = context::new_test_context(sender);
         let ctx = &mut storage_context;