From 5c1d6ca3b71d1a860b1cb81be524a1924f0ade98 Mon Sep 17 00:00:00 2001 From: Greg Nazario Date: Mon, 7 Aug 2023 10:20:34 -0700 Subject: [PATCH] [framework] Add Aptos-token mint function that returns object --- .../aptos-token-objects/doc/aptos_token.md | 166 +++++++++++++++++- .../sources/aptos_token.move | 120 ++++++++++--- 2 files changed, 256 insertions(+), 30 deletions(-) diff --git a/aptos-move/framework/aptos-token-objects/doc/aptos_token.md b/aptos-move/framework/aptos-token-objects/doc/aptos_token.md index 8414f43ddfb13..0025b7d31f326 100644 --- a/aptos-move/framework/aptos-token-objects/doc/aptos_token.md +++ b/aptos-move/framework/aptos-token-objects/doc/aptos_token.md @@ -17,8 +17,11 @@ The key features are: - [Resource `AptosToken`](#0x4_aptos_token_AptosToken) - [Constants](#@Constants_0) - [Function `create_collection`](#0x4_aptos_token_create_collection) +- [Function `create_collection_object`](#0x4_aptos_token_create_collection_object) - [Function `mint`](#0x4_aptos_token_mint) +- [Function `mint_token_object`](#0x4_aptos_token_mint_token_object) - [Function `mint_soul_bound`](#0x4_aptos_token_mint_soul_bound) +- [Function `mint_soul_bound_token_object`](#0x4_aptos_token_mint_soul_bound_token_object) - [Function `mint_internal`](#0x4_aptos_token_mint_internal) - [Function `borrow`](#0x4_aptos_token_borrow) - [Function `are_properties_mutable`](#0x4_aptos_token_are_properties_mutable) @@ -300,6 +303,64 @@ Create a new collection royalty_numerator: u64, royalty_denominator: u64, ) { + create_collection_object( + creator, + description, + max_supply, + name, + uri, + mutable_description, + mutable_royalty, + mutable_uri, + mutable_token_description, + mutable_token_name, + mutable_token_properties, + mutable_token_uri, + tokens_burnable_by_creator, + tokens_freezable_by_creator, + royalty_numerator, + royalty_denominator + ); +} + + + + + + + + +## Function `create_collection_object` + + + +
public fun create_collection_object(creator: &signer, description: string::String, max_supply: u64, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_token_description: bool, mutable_token_name: bool, mutable_token_properties: bool, mutable_token_uri: bool, tokens_burnable_by_creator: bool, tokens_freezable_by_creator: bool, royalty_numerator: u64, royalty_denominator: u64): object::Object<aptos_token::AptosCollection>
+
+ + + +
+Implementation + + +
public fun create_collection_object(
+    creator: &signer,
+    description: String,
+    max_supply: u64,
+    name: String,
+    uri: String,
+    mutable_description: bool,
+    mutable_royalty: bool,
+    mutable_uri: bool,
+    mutable_token_description: bool,
+    mutable_token_name: bool,
+    mutable_token_properties: bool,
+    mutable_token_uri: bool,
+    tokens_burnable_by_creator: bool,
+    tokens_freezable_by_creator: bool,
+    royalty_numerator: u64,
+    royalty_denominator: u64,
+): Object<AptosCollection> {
     let creator_addr = signer::address_of(creator);
     let royalty = royalty::create(royalty_numerator, royalty_denominator, creator_addr);
     let constructor_ref = collection::create_fixed_collection(
@@ -337,6 +398,7 @@ Create a new collection
         tokens_freezable_by_creator,
     };
     move_to(&object_signer, aptos_collection);
+    object::object_from_constructor_ref(&constructor_ref)
 }
 
@@ -370,6 +432,40 @@ With an existing collection, directly mint a viable token into the creators acco property_types: vector<String>, property_values: vector<vector<u8>>, ) acquires AptosCollection, AptosToken { + mint_token_object(creator, collection, description, name, uri, property_keys, property_types, property_values); +} + + + + +
+ + + +## Function `mint_token_object` + +Mint a token into an existing collection, and retrieve the object / address of the token. + + +
public fun mint_token_object(creator: &signer, collection: string::String, description: string::String, name: string::String, uri: string::String, property_keys: vector<string::String>, property_types: vector<string::String>, property_values: vector<vector<u8>>): object::Object<aptos_token::AptosToken>
+
+ + + +
+Implementation + + +
public fun mint_token_object(
+    creator: &signer,
+    collection: String,
+    description: String,
+    name: String,
+    uri: String,
+    property_keys: vector<String>,
+    property_types: vector<String>,
+    property_values: vector<vector<u8>>,
+): Object<AptosToken> acquires AptosCollection, AptosToken {
     let constructor_ref = mint_internal(
         creator,
         collection,
@@ -382,15 +478,17 @@ With an existing collection, directly mint a viable token into the creators acco
     );
 
     let collection = collection_object(creator, &collection);
+
+    // If tokens are freezable, add a transfer ref to be able to freeze transfers
     let freezable_by_creator = are_collection_tokens_freezable(collection);
-    if (!freezable_by_creator) {
-        return
+    if (freezable_by_creator) {
+        let aptos_token_addr = object::address_from_constructor_ref(&constructor_ref);
+        let aptos_token = borrow_global_mut<AptosToken>(aptos_token_addr);
+        let transfer_ref = object::generate_transfer_ref(&constructor_ref);
+        option::fill(&mut aptos_token.transfer_ref, transfer_ref);
     };
 
-    let aptos_token_addr = object::address_from_constructor_ref(&constructor_ref);
-    let aptos_token = borrow_global_mut<AptosToken>(aptos_token_addr);
-    let transfer_ref = object::generate_transfer_ref(&constructor_ref);
-    option::fill(&mut aptos_token.transfer_ref, transfer_ref);
+    object::object_from_constructor_ref(&constructor_ref)
 }
 
@@ -425,6 +523,51 @@ With an existing collection, directly mint a soul bound token into the recipient property_values: vector<vector<u8>>, soul_bound_to: address, ) acquires AptosCollection { + mint_soul_bound_token_object( + creator, + collection, + description, + name, + uri, + property_keys, + property_types, + property_values, + soul_bound_to + ); +} + + + + +
+ + + +## Function `mint_soul_bound_token_object` + +With an existing collection, directly mint a soul bound token into the recipient's account. + + +
public fun mint_soul_bound_token_object(creator: &signer, collection: string::String, description: string::String, name: string::String, uri: string::String, property_keys: vector<string::String>, property_types: vector<string::String>, property_values: vector<vector<u8>>, soul_bound_to: address): object::Object<aptos_token::AptosToken>
+
+ + + +
+Implementation + + +
public fun mint_soul_bound_token_object(
+    creator: &signer,
+    collection: String,
+    description: String,
+    name: String,
+    uri: String,
+    property_keys: vector<String>,
+    property_types: vector<String>,
+    property_values: vector<vector<u8>>,
+    soul_bound_to: address,
+): Object<AptosToken> acquires AptosCollection {
     let constructor_ref = mint_internal(
         creator,
         collection,
@@ -440,6 +583,8 @@ With an existing collection, directly mint a soul bound token into the recipient
     let linear_transfer_ref = object::generate_linear_transfer_ref(&transfer_ref);
     object::transfer_with_ref(linear_transfer_ref, soul_bound_to);
     object::disable_ungated_transfer(&transfer_ref);
+
+    object::object_from_constructor_ref(&constructor_ref)
 }
 
@@ -499,8 +644,8 @@ With an existing collection, directly mint a soul bound token into the recipient let mutator_ref = if ( collection.mutable_token_description - || collection.mutable_token_name - || collection.mutable_token_uri + || collection.mutable_token_name + || collection.mutable_token_uri ) { option::some(token::generate_mutator_ref(&constructor_ref)) } else { @@ -829,7 +974,10 @@ With an existing collection, directly mint a soul bound token into the recipient Implementation -
public entry fun unfreeze_transfer<T: key>(creator: &signer, token: Object<T>) acquires AptosCollection, AptosToken {
+
public entry fun unfreeze_transfer<T: key>(
+    creator: &signer,
+    token: Object<T>
+) acquires AptosCollection, AptosToken {
     let aptos_token = authorized_borrow(&token, creator);
     assert!(
         are_collection_tokens_freezable(token::collection_object(token))
diff --git a/aptos-move/framework/aptos-token-objects/sources/aptos_token.move b/aptos-move/framework/aptos-token-objects/sources/aptos_token.move
index f20cd7b600025..b2ef0280e0886 100644
--- a/aptos-move/framework/aptos-token-objects/sources/aptos_token.move
+++ b/aptos-move/framework/aptos-token-objects/sources/aptos_token.move
@@ -88,6 +88,44 @@ module aptos_token_objects::aptos_token {
         royalty_numerator: u64,
         royalty_denominator: u64,
     ) {
+        create_collection_object(
+            creator,
+            description,
+            max_supply,
+            name,
+            uri,
+            mutable_description,
+            mutable_royalty,
+            mutable_uri,
+            mutable_token_description,
+            mutable_token_name,
+            mutable_token_properties,
+            mutable_token_uri,
+            tokens_burnable_by_creator,
+            tokens_freezable_by_creator,
+            royalty_numerator,
+            royalty_denominator
+        );
+    }
+
+    public fun create_collection_object(
+        creator: &signer,
+        description: String,
+        max_supply: u64,
+        name: String,
+        uri: String,
+        mutable_description: bool,
+        mutable_royalty: bool,
+        mutable_uri: bool,
+        mutable_token_description: bool,
+        mutable_token_name: bool,
+        mutable_token_properties: bool,
+        mutable_token_uri: bool,
+        tokens_burnable_by_creator: bool,
+        tokens_freezable_by_creator: bool,
+        royalty_numerator: u64,
+        royalty_denominator: u64,
+    ): Object {
         let creator_addr = signer::address_of(creator);
         let royalty = royalty::create(royalty_numerator, royalty_denominator, creator_addr);
         let constructor_ref = collection::create_fixed_collection(
@@ -125,6 +163,7 @@ module aptos_token_objects::aptos_token {
             tokens_freezable_by_creator,
         };
         move_to(&object_signer, aptos_collection);
+        object::object_from_constructor_ref(&constructor_ref)
     }
 
     /// With an existing collection, directly mint a viable token into the creators account.
@@ -138,6 +177,20 @@ module aptos_token_objects::aptos_token {
         property_types: vector,
         property_values: vector>,
     ) acquires AptosCollection, AptosToken {
+        mint_token_object(creator, collection, description, name, uri, property_keys, property_types, property_values);
+    }
+
+    /// Mint a token into an existing collection, and retrieve the object / address of the token.
+    public fun mint_token_object(
+        creator: &signer,
+        collection: String,
+        description: String,
+        name: String,
+        uri: String,
+        property_keys: vector,
+        property_types: vector,
+        property_values: vector>,
+    ): Object acquires AptosCollection, AptosToken {
         let constructor_ref = mint_internal(
             creator,
             collection,
@@ -150,15 +203,17 @@ module aptos_token_objects::aptos_token {
         );
 
         let collection = collection_object(creator, &collection);
+
+        // If tokens are freezable, add a transfer ref to be able to freeze transfers
         let freezable_by_creator = are_collection_tokens_freezable(collection);
-        if (!freezable_by_creator) {
-            return
+        if (freezable_by_creator) {
+            let aptos_token_addr = object::address_from_constructor_ref(&constructor_ref);
+            let aptos_token = borrow_global_mut(aptos_token_addr);
+            let transfer_ref = object::generate_transfer_ref(&constructor_ref);
+            option::fill(&mut aptos_token.transfer_ref, transfer_ref);
         };
 
-        let aptos_token_addr = object::address_from_constructor_ref(&constructor_ref);
-        let aptos_token = borrow_global_mut(aptos_token_addr);
-        let transfer_ref = object::generate_transfer_ref(&constructor_ref);
-        option::fill(&mut aptos_token.transfer_ref, transfer_ref);
+        object::object_from_constructor_ref(&constructor_ref)
     }
 
     /// With an existing collection, directly mint a soul bound token into the recipient's account.
@@ -173,6 +228,31 @@ module aptos_token_objects::aptos_token {
         property_values: vector>,
         soul_bound_to: address,
     ) acquires AptosCollection {
+        mint_soul_bound_token_object(
+            creator,
+            collection,
+            description,
+            name,
+            uri,
+            property_keys,
+            property_types,
+            property_values,
+            soul_bound_to
+        );
+    }
+
+    /// With an existing collection, directly mint a soul bound token into the recipient's account.
+    public fun mint_soul_bound_token_object(
+        creator: &signer,
+        collection: String,
+        description: String,
+        name: String,
+        uri: String,
+        property_keys: vector,
+        property_types: vector,
+        property_values: vector>,
+        soul_bound_to: address,
+    ): Object acquires AptosCollection {
         let constructor_ref = mint_internal(
             creator,
             collection,
@@ -188,6 +268,8 @@ module aptos_token_objects::aptos_token {
         let linear_transfer_ref = object::generate_linear_transfer_ref(&transfer_ref);
         object::transfer_with_ref(linear_transfer_ref, soul_bound_to);
         object::disable_ungated_transfer(&transfer_ref);
+
+        object::object_from_constructor_ref(&constructor_ref)
     }
 
     fun mint_internal(
@@ -227,8 +309,8 @@ module aptos_token_objects::aptos_token {
 
         let mutator_ref = if (
             collection.mutable_token_description
-            || collection.mutable_token_name
-            || collection.mutable_token_uri
+                || collection.mutable_token_name
+                || collection.mutable_token_uri
         ) {
             option::some(token::generate_mutator_ref(&constructor_ref))
         } else {
@@ -341,7 +423,10 @@ module aptos_token_objects::aptos_token {
         object::disable_ungated_transfer(option::borrow(&aptos_token.transfer_ref));
     }
 
-    public entry fun unfreeze_transfer(creator: &signer, token: Object) acquires AptosCollection, AptosToken {
+    public entry fun unfreeze_transfer(
+        creator: &signer,
+        token: Object
+    ) acquires AptosCollection, AptosToken {
         let aptos_token = authorized_borrow(&token, creator);
         assert!(
             are_collection_tokens_freezable(token::collection_object(token))
@@ -631,9 +716,8 @@ module aptos_token_objects::aptos_token {
 
         let creator_addr = signer::address_of(creator);
         account::create_account_for_test(creator_addr);
-        let token_creation_num = account::get_guid_next_creation_num(creator_addr);
 
-        mint_soul_bound(
+        let token = mint_soul_bound_token_object(
             creator,
             collection_name,
             string::utf8(b""),
@@ -645,8 +729,6 @@ module aptos_token_objects::aptos_token {
             signer::address_of(bob),
         );
 
-        let token_addr = object::create_guid_object_address(creator_addr, token_creation_num);
-        let token = object::address_to_object(token_addr);
         object::transfer(bob, token, @0x345);
     }
 
@@ -1007,7 +1089,7 @@ module aptos_token_objects::aptos_token {
         collection_name: String,
         flag: bool,
     ): Object {
-        create_collection(
+        create_collection_object(
             creator,
             string::utf8(b"collection description"),
             1,
@@ -1024,9 +1106,7 @@ module aptos_token_objects::aptos_token {
             flag,
             1,
             100,
-        );
-
-        collection_object(creator, &collection_name)
+        )
     }
 
     #[test_only]
@@ -1037,9 +1117,8 @@ module aptos_token_objects::aptos_token {
     ): Object acquires AptosCollection, AptosToken {
         let creator_addr = signer::address_of(creator);
         account::create_account_for_test(creator_addr);
-        let token_creation_num = account::get_guid_next_creation_num(creator_addr);
 
-        mint(
+        mint_token_object(
             creator,
             collection_name,
             string::utf8(b"description"),
@@ -1048,7 +1127,6 @@ module aptos_token_objects::aptos_token {
             vector[string::utf8(b"bool")],
             vector[string::utf8(b"bool")],
             vector[vector[0x01]],
-        );
-        object::address_to_object(object::create_guid_object_address(creator_addr, token_creation_num))
+        )
     }
 }