token - [mainnet]
This defines an object-based Token. The key differentiating features from the Aptos standard token are:
- Decoupled token ownership from token data.
- Explicit data model for token metadata via adjacent resources
- Extensible framework for tokens
use 0x1::aggregator_v2;use 0x1::error;use 0x1::event;use 0x1::features;use 0x1::object;use 0x1::option;use 0x1::signer;use 0x1::string;use 0x1::vector;use 0x4::collection;use 0x4::royalty;
Constants
The URI is over the maximum length
const EURI_TOO_LONG: u64 = 5;
const MAX_URI_LENGTH: u64 = 512;
The calling signer is not the owner
const ENOT_OWNER: u64 = 8;
The collection owner feature is not supported
const ECOLLECTION_OWNER_NOT_SUPPORTED: u64 = 9;
The description is over the maximum length
const EDESCRIPTION_TOO_LONG: u64 = 6;
const MAX_DESCRIPTION_LENGTH: u64 = 2048;
The field being changed is not mutable
const EFIELD_NOT_MUTABLE: u64 = 3;
The provided signer is not the creator
const ENOT_CREATOR: u64 = 2;
The seed is over the maximum length
const ESEED_TOO_LONG: u64 = 7;
The token does not exist
const ETOKEN_DOES_NOT_EXIST: u64 = 1;
The token name is over the maximum length
const ETOKEN_NAME_TOO_LONG: u64 = 4;
const MAX_TOKEN_NAME_LENGTH: u64 = 128;
const MAX_TOKEN_SEED_LENGTH: u64 = 128;
Structs
BurnRef
This enables burning an NFT, if possible, it will also delete the object. Note, the data in inner and self occupies 32-bytes each, rather than have both, this data structure makes a small optimization to support either and take a fixed amount of 34-bytes.
struct BurnRef has drop, store
Fields
-
inner: option::Option<object::DeleteRef>
-
self: option::Option<address>
MutatorRef
This enables mutating description and URI by higher level services.
struct MutatorRef has drop, store
Fields
-
self: address
MutationEvent
Contains the mutated fields name. This makes the life of indexers easier, so that they can directly understand the behavior in a writeset.
struct MutationEvent has drop, store
Fields
-
mutated_field_name: string::String
-
old_value: string::String
-
new_value: string::String
Mutation
#[event]struct Mutation has drop, store
Fields
-
token_address: address
-
mutated_field_name: string::String
-
old_value: string::String
-
new_value: string::String
Resources
Token
Represents the common fields to all tokens.
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]struct Token has key
Fields
-
collection: object::Object<collection::Collection>
- The collection from which this token resides.
-
index: u64
-
Deprecated in favor of
index
inside TokenIdentifiers. Was populated until concurrent_token_v2_enabled feature flag was enabled.Unique identifier within the collection, optional, 0 means unassigned
-
description: string::String
- A brief description of the token.
-
name: string::String
-
Deprecated in favor of
name
inside TokenIdentifiers. Was populated until concurrent_token_v2_enabled feature flag was enabled.The name of the token, which should be unique within the collection; the length of name should be smaller than 128, characters, eg: “Aptos Animal #1234”
-
uri: string::String
- The Uniform Resource Identifier (uri) pointing to the JSON file stored in off-chain storage; the URL length will likely need a maximum any suggestions?
-
mutation_events: event::EventHandle<token::MutationEvent>
- Emitted upon any mutation of the token.
TokenIdentifiers
Represents first addition to the common fields for all tokens Started being populated once aggregator_v2_api_enabled was enabled.
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]struct TokenIdentifiers has key
Fields
-
index: aggregator_v2::AggregatorSnapshot<u64>
- Unique identifier within the collection, optional, 0 means unassigned
-
name: aggregator_v2::DerivedStringSnapshot
- The name of the token, which should be unique within the collection; the length of name should be smaller than 128, characters, eg: "Aptos Animal #1234"
ConcurrentTokenIdentifiers
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]#[deprecated]struct ConcurrentTokenIdentifiers has key
Fields
-
index: aggregator_v2::AggregatorSnapshot<u64>
-
name: aggregator_v2::AggregatorSnapshot<string::String>
Functions
create_common
fun create_common(creator: &signer, constructor_ref: &object::ConstructorRef, collection_name: string::String, description: string::String, name_prefix: string::String, name_with_index_suffix: option::Option<string::String>, royalty: option::Option<royalty::Royalty>, uri: string::String)
Implementation
inline fun create_common( creator: &signer, constructor_ref: &ConstructorRef, collection_name: String, description: String, name_prefix: String, // If option::some, numbered token is created - i.e. index is appended to the name. // If option::none, name_prefix is the full name of the token. name_with_index_suffix: Option<String>, royalty: Option<Royalty>, uri: String,) { let creator_address = signer::address_of(creator); let collection_addr = collection::create_collection_address(&creator_address, &collection_name); let collection = object::address_to_object<Collection>(collection_addr);
create_common_with_collection( creator, constructor_ref, collection, description, name_prefix, name_with_index_suffix, royalty, uri )}
create_common_with_collection
fun create_common_with_collection(creator: &signer, constructor_ref: &object::ConstructorRef, collection: object::Object<collection::Collection>, description: string::String, name_prefix: string::String, name_with_index_suffix: option::Option<string::String>, royalty: option::Option<royalty::Royalty>, uri: string::String)
Implementation
inline fun create_common_with_collection( creator: &signer, constructor_ref: &ConstructorRef, collection: Object<Collection>, description: String, name_prefix: String, // If option::some, numbered token is created - i.e. index is appended to the name. // If option::none, name_prefix is the full name of the token. name_with_index_suffix: Option<String>, royalty: Option<Royalty>, uri: String,) { assert!(collection::creator(collection) == signer::address_of(creator), error::unauthenticated(ENOT_CREATOR));
create_common_with_collection_internal( constructor_ref, collection, description, name_prefix, name_with_index_suffix, royalty, uri );}
create_common_with_collection_as_owner
fun create_common_with_collection_as_owner(owner: &signer, constructor_ref: &object::ConstructorRef, collection: object::Object<collection::Collection>, description: string::String, name_prefix: string::String, name_with_index_suffix: option::Option<string::String>, royalty: option::Option<royalty::Royalty>, uri: string::String)
Implementation
inline fun create_common_with_collection_as_owner( owner: &signer, constructor_ref: &ConstructorRef, collection: Object<Collection>, description: String, name_prefix: String, // If option::some, numbered token is created - i.e. index is appended to the name. // If option::none, name_prefix is the full name of the token. name_with_index_suffix: Option<String>, royalty: Option<Royalty>, uri: String,) { assert!(features::is_collection_owner_enabled(), error::unavailable(ECOLLECTION_OWNER_NOT_SUPPORTED)); assert!(object::owner(collection) == signer::address_of(owner), error::unauthenticated(ENOT_OWNER));
create_common_with_collection_internal( constructor_ref, collection, description, name_prefix, name_with_index_suffix, royalty, uri );}
create_common_with_collection_internal
fun create_common_with_collection_internal(constructor_ref: &object::ConstructorRef, collection: object::Object<collection::Collection>, description: string::String, name_prefix: string::String, name_with_index_suffix: option::Option<string::String>, royalty: option::Option<royalty::Royalty>, uri: string::String)
Implementation
inline fun create_common_with_collection_internal( constructor_ref: &ConstructorRef, collection: Object<Collection>, description: String, name_prefix: String, // If option::some, numbered token is created - i.e. index is appended to the name. // If option::none, name_prefix is the full name of the token. name_with_index_suffix: Option<String>, royalty: Option<Royalty>, uri: String,) { if (name_with_index_suffix.is_some()) { // Be conservative, as we don't know what length the index will be, and assume worst case (20 chars in MAX_U64) assert!( name_prefix.length() + 20 + name_with_index_suffix.borrow().length() <= MAX_TOKEN_NAME_LENGTH, error::out_of_range(ETOKEN_NAME_TOO_LONG) ); } else { assert!(name_prefix.length() <= MAX_TOKEN_NAME_LENGTH, error::out_of_range(ETOKEN_NAME_TOO_LONG)); }; assert!(description.length() <= MAX_DESCRIPTION_LENGTH, error::out_of_range(EDESCRIPTION_TOO_LONG)); assert!(uri.length() <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG));
let object_signer = object::generate_signer(constructor_ref);
let index = collection::increment_supply(&collection, signer::address_of(&object_signer)).destroy_with_default( aggregator_v2::create_snapshot<u64>(0) );
// If create_numbered_token called us, add index to the name. let name = if (name_with_index_suffix.is_some()) { aggregator_v2::derive_string_concat(name_prefix, &index, name_with_index_suffix.extract()) } else { aggregator_v2::create_derived_string(name_prefix) };
let deprecated_index = 0; let deprecated_name = string::utf8(b"");
let token_concurrent = TokenIdentifiers { index, name, }; move_to(&object_signer, token_concurrent);
let token = Token { collection, index: deprecated_index, description, name: deprecated_name, uri, mutation_events: object::new_event_handle(&object_signer), }; move_to(&object_signer, token);
if (royalty.is_some()) { royalty::init(constructor_ref, royalty.extract()) };}
create_token
Creates a new token object with a unique address and returns the ConstructorRef for additional specialization. This takes in the collection object instead of the collection name. This function must be called if the collection name has been previously changed.
public fun create_token(creator: &signer, collection: object::Object<collection::Collection>, description: string::String, name: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String): object::ConstructorRef
Implementation
public fun create_token( creator: &signer, collection: Object<Collection>, description: String, name: String, royalty: Option<Royalty>, uri: String,): ConstructorRef { let creator_address = signer::address_of(creator); let constructor_ref = object::create_object(creator_address); create_common_with_collection( creator, &constructor_ref, collection, description, name, option::none(), royalty, uri ); constructor_ref}
create
Creates a new token object with a unique address and returns the ConstructorRef for additional specialization.
public fun create(creator: &signer, collection_name: string::String, description: string::String, name: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String): object::ConstructorRef
Implementation
public fun create( creator: &signer, collection_name: String, description: String, name: String, royalty: Option<Royalty>, uri: String,): ConstructorRef { let creator_address = signer::address_of(creator); let constructor_ref = object::create_object(creator_address); create_common( creator, &constructor_ref, collection_name, description, name, option::none(), royalty, uri ); constructor_ref}
create_token_as_collection_owner
Same functionality as create_token
, but the token can only be created by the collection owner.
public fun create_token_as_collection_owner(creator: &signer, collection: object::Object<collection::Collection>, description: string::String, name: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String): object::ConstructorRef
Implementation
public fun create_token_as_collection_owner( creator: &signer, collection: Object<Collection>, description: String, name: String, royalty: Option<Royalty>, uri: String,): ConstructorRef { let creator_address = signer::address_of(creator); let constructor_ref = object::create_object(creator_address); create_common_with_collection_as_owner( creator, &constructor_ref, collection, description, name, option::none(), royalty, uri ); constructor_ref}
create_numbered_token_object
Creates a new token object with a unique address and returns the ConstructorRef for additional specialization. The name is created by concatenating the (name_prefix, index, name_suffix). This function allows creating tokens in parallel, from the same collection, while providing sequential names.
This takes in the collection object instead of the collection name. This function must be called if the collection name has been previously changed.
public fun create_numbered_token_object(creator: &signer, collection: object::Object<collection::Collection>, description: string::String, name_with_index_prefix: string::String, name_with_index_suffix: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String): object::ConstructorRef
Implementation
public fun create_numbered_token_object( creator: &signer, collection: Object<Collection>, description: String, name_with_index_prefix: String, name_with_index_suffix: String, royalty: Option<Royalty>, uri: String,): ConstructorRef { let creator_address = signer::address_of(creator); let constructor_ref = object::create_object(creator_address); create_common_with_collection( creator, &constructor_ref, collection, description, name_with_index_prefix, option::some(name_with_index_suffix), royalty, uri ); constructor_ref}
create_numbered_token
Creates a new token object with a unique address and returns the ConstructorRef for additional specialization. The name is created by concatenating the (name_prefix, index, name_suffix). This function will allow creating tokens in parallel, from the same collection, while providing sequential names.
public fun create_numbered_token(creator: &signer, collection_name: string::String, description: string::String, name_with_index_prefix: string::String, name_with_index_suffix: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String): object::ConstructorRef
Implementation
public fun create_numbered_token( creator: &signer, collection_name: String, description: String, name_with_index_prefix: String, name_with_index_suffix: String, royalty: Option<Royalty>, uri: String,): ConstructorRef { let creator_address = signer::address_of(creator); let constructor_ref = object::create_object(creator_address); create_common( creator, &constructor_ref, collection_name, description, name_with_index_prefix, option::some(name_with_index_suffix), royalty, uri ); constructor_ref}
create_numbered_token_as_collection_owner
Same functionality as create_numbered_token_object
, but the token can only be created by the collection owner.
public fun create_numbered_token_as_collection_owner(creator: &signer, collection: object::Object<collection::Collection>, description: string::String, name_with_index_prefix: string::String, name_with_index_suffix: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String): object::ConstructorRef
Implementation
public fun create_numbered_token_as_collection_owner( creator: &signer, collection: Object<Collection>, description: String, name_with_index_prefix: String, name_with_index_suffix: String, royalty: Option<Royalty>, uri: String,): ConstructorRef { let creator_address = signer::address_of(creator); let constructor_ref = object::create_object(creator_address); create_common_with_collection_as_owner( creator, &constructor_ref, collection, description, name_with_index_prefix, option::some(name_with_index_suffix), royalty, uri ); constructor_ref}
create_named_token_object
Creates a new token object from a token name and returns the ConstructorRef for additional specialization. This function must be called if the collection name has been previously changed.
public fun create_named_token_object(creator: &signer, collection: object::Object<collection::Collection>, description: string::String, name: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String): object::ConstructorRef
Implementation
public fun create_named_token_object( creator: &signer, collection: Object<Collection>, description: String, name: String, royalty: Option<Royalty>, uri: String,): ConstructorRef { let seed = create_token_seed(&collection::name(collection), &name); let constructor_ref = object::create_named_object(creator, seed); create_common_with_collection( creator, &constructor_ref, collection, description, name, option::none(), royalty, uri ); constructor_ref}
create_named_token
Creates a new token object from a token name and returns the ConstructorRef for additional specialization.
public fun create_named_token(creator: &signer, collection_name: string::String, description: string::String, name: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String): object::ConstructorRef
Implementation
public fun create_named_token( creator: &signer, collection_name: String, description: String, name: String, royalty: Option<Royalty>, uri: String,): ConstructorRef { let seed = create_token_seed(&collection_name, &name);
let constructor_ref = object::create_named_object(creator, seed); create_common( creator, &constructor_ref, collection_name, description, name, option::none(), royalty, uri ); constructor_ref}
create_named_token_as_collection_owner
Same functionality as create_named_token_object
, but the token can only be created by the collection owner.
public fun create_named_token_as_collection_owner(creator: &signer, collection: object::Object<collection::Collection>, description: string::String, name: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String): object::ConstructorRef
Implementation
public fun create_named_token_as_collection_owner( creator: &signer, collection: Object<Collection>, description: String, name: String, royalty: Option<Royalty>, uri: String,): ConstructorRef { let seed = create_token_seed(&collection::name(collection), &name); let constructor_ref = object::create_named_object(creator, seed); create_common_with_collection_as_owner( creator, &constructor_ref, collection, description, name, option::none(), royalty, uri ); constructor_ref}
create_named_token_from_seed
Creates a new token object from a token name and seed. Returns the ConstructorRef for additional specialization. This function must be called if the collection name has been previously changed.
public fun create_named_token_from_seed(creator: &signer, collection: object::Object<collection::Collection>, description: string::String, name: string::String, seed: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String): object::ConstructorRef
Implementation
public fun create_named_token_from_seed( creator: &signer, collection: Object<Collection>, description: String, name: String, seed: String, royalty: Option<Royalty>, uri: String,): ConstructorRef { let seed = create_token_name_with_seed(&collection::name(collection), &name, &seed); let constructor_ref = object::create_named_object(creator, seed); create_common_with_collection(creator, &constructor_ref, collection, description, name, option::none(), royalty, uri); constructor_ref}
create_named_token_from_seed_as_collection_owner
Same functionality as create_named_token_from_seed
, but the token can only be created by the collection owner.
public fun create_named_token_from_seed_as_collection_owner(creator: &signer, collection: object::Object<collection::Collection>, description: string::String, name: string::String, seed: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String): object::ConstructorRef
Implementation
public fun create_named_token_from_seed_as_collection_owner( creator: &signer, collection: Object<Collection>, description: String, name: String, seed: String, royalty: Option<Royalty>, uri: String,): ConstructorRef { let seed = create_token_name_with_seed(&collection::name(collection), &name, &seed); let constructor_ref = object::create_named_object(creator, seed); create_common_with_collection_as_owner( creator, &constructor_ref, collection, description, name, option::none(), royalty, uri ); constructor_ref}
create_from_account
DEPRECATED: Use create
instead for identical behavior.
Creates a new token object from an account GUID and returns the ConstructorRef for additional specialization.
#[deprecated]public fun create_from_account(creator: &signer, collection_name: string::String, description: string::String, name: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String): object::ConstructorRef
Implementation
public fun create_from_account( creator: &signer, collection_name: String, description: String, name: String, royalty: Option<Royalty>, uri: String,): ConstructorRef { let constructor_ref = object::create_object_from_account(creator); create_common( creator, &constructor_ref, collection_name, description, name, option::none(), royalty, uri ); constructor_ref}
create_token_address
Generates the token’s address based upon the creator’s address, the collection’s name and the token’s name.
public fun create_token_address(creator: &address, collection: &string::String, name: &string::String): address
Implementation
public fun create_token_address(creator: &address, collection: &String, name: &String): address { object::create_object_address(creator, create_token_seed(collection, name))}
create_token_address_with_seed
Generates the token’s address based upon the creator’s address, the collection object and the token’s name and seed.
#[view]public fun create_token_address_with_seed(creator: address, collection: string::String, name: string::String, seed: string::String): address
Implementation
public fun create_token_address_with_seed(creator: address, collection: String, name: String, seed: String): address { let seed = create_token_name_with_seed(&collection, &name, &seed); object::create_object_address(&creator, seed)}
create_token_seed
Named objects are derived from a seed, the token’s seed is its name appended to the collection’s name.
public fun create_token_seed(collection: &string::String, name: &string::String): vector<u8>
Implementation
public fun create_token_seed(collection: &String, name: &String): vector<u8> { assert!(name.length() <= MAX_TOKEN_NAME_LENGTH, error::out_of_range(ETOKEN_NAME_TOO_LONG)); let seed = *collection.bytes(); seed.append(b"::"); seed.append(*name.bytes()); seed}
create_token_name_with_seed
public fun create_token_name_with_seed(collection: &string::String, name: &string::String, seed: &string::String): vector<u8>
Implementation
public fun create_token_name_with_seed(collection: &String, name: &String, seed: &String): vector<u8> { assert!(seed.length() <= MAX_TOKEN_SEED_LENGTH, error::out_of_range(ESEED_TOO_LONG)); let seeds = create_token_seed(collection, name); seeds.append(*seed.bytes()); seeds}
generate_mutator_ref
Creates a MutatorRef, which gates the ability to mutate any fields that support mutation.
public fun generate_mutator_ref(ref: &object::ConstructorRef): token::MutatorRef
Implementation
public fun generate_mutator_ref(ref: &ConstructorRef): MutatorRef { let object = object::object_from_constructor_ref<Token>(ref); MutatorRef { self: object::object_address(&object) }}
generate_burn_ref
Creates a BurnRef, which gates the ability to burn the given token.
public fun generate_burn_ref(ref: &object::ConstructorRef): token::BurnRef
Implementation
public fun generate_burn_ref(ref: &ConstructorRef): BurnRef { let (inner, self) = if (object::can_generate_delete_ref(ref)) { let delete_ref = object::generate_delete_ref(ref); (option::some(delete_ref), option::none()) } else { let addr = object::address_from_constructor_ref(ref); (option::none(), option::some(addr)) }; BurnRef { self, inner }}
address_from_burn_ref
Extracts the tokens address from a BurnRef.
public fun address_from_burn_ref(ref: &token::BurnRef): address
Implementation
public fun address_from_burn_ref(ref: &BurnRef): address { if (ref.inner.is_some()) { object::address_from_delete_ref(ref.inner.borrow()) } else { *ref.self.borrow() }}
borrow
fun borrow<T: key>(token: &object::Object<T>): &token::Token
Implementation
inline fun borrow<T: key>(token: &Object<T>): &Token acquires Token { let token_address = object::object_address(token); assert!( exists<Token>(token_address), error::not_found(ETOKEN_DOES_NOT_EXIST), ); &Token[token_address]}
creator
#[view]public fun creator<T: key>(token: object::Object<T>): address
Implementation
public fun creator<T: key>(token: Object<T>): address acquires Token { collection::creator(borrow(&token).collection)}
collection_name
#[view]public fun collection_name<T: key>(token: object::Object<T>): string::String
Implementation
public fun collection_name<T: key>(token: Object<T>): String acquires Token { collection::name(borrow(&token).collection)}
collection_object
#[view]public fun collection_object<T: key>(token: object::Object<T>): object::Object<collection::Collection>
Implementation
public fun collection_object<T: key>(token: Object<T>): Object<Collection> acquires Token { borrow(&token).collection}
description
#[view]public fun description<T: key>(token: object::Object<T>): string::String
Implementation
public fun description<T: key>(token: Object<T>): String acquires Token { borrow(&token).description}
name
Avoid this method in the same transaction as the token is minted as that would prohibit transactions to be executed in parallel.
#[view]public fun name<T: key>(token: object::Object<T>): string::String
Implementation
public fun name<T: key>(token: Object<T>): String acquires Token, TokenIdentifiers { let token_address = object::object_address(&token); if (exists<TokenIdentifiers>(token_address)) { aggregator_v2::read_derived_string(&TokenIdentifiers[token_address].name) } else { borrow(&token).name }}
uri
#[view]public fun uri<T: key>(token: object::Object<T>): string::String
Implementation
public fun uri<T: key>(token: Object<T>): String acquires Token { borrow(&token).uri}
royalty
#[view]public fun royalty<T: key>(token: object::Object<T>): option::Option<royalty::Royalty>
Implementation
public fun royalty<T: key>(token: Object<T>): Option<Royalty> acquires Token { borrow(&token); let royalty = royalty::get(token); if (royalty.is_some()) { royalty } else { let creator = creator(token); let collection_name = collection_name(token); let collection_address = collection::create_collection_address(&creator, &collection_name); let collection = object::address_to_object<collection::Collection>(collection_address); royalty::get(collection) }}
index
Avoid this method in the same transaction as the token is minted as that would prohibit transactions to be executed in parallel.
#[view]public fun index<T: key>(token: object::Object<T>): u64
Implementation
public fun index<T: key>(token: Object<T>): u64 acquires Token, TokenIdentifiers { let token_address = object::object_address(&token); if (exists<TokenIdentifiers>(token_address)) { aggregator_v2::read_snapshot(&TokenIdentifiers[token_address].index) } else { borrow(&token).index }}
borrow_mut
fun borrow_mut(mutator_ref: &token::MutatorRef): &mut token::Token
Implementation
inline fun borrow_mut(mutator_ref: &MutatorRef): &mut Token acquires Token { assert!( exists<Token>(mutator_ref.self), error::not_found(ETOKEN_DOES_NOT_EXIST), ); &mut Token[mutator_ref.self]}
burn
public fun burn(burn_ref: token::BurnRef)
Implementation
public fun burn(burn_ref: BurnRef) acquires Token, TokenIdentifiers { let (addr, previous_owner) = if (burn_ref.inner.is_some()) { let delete_ref = burn_ref.inner.extract(); let addr = object::address_from_delete_ref(&delete_ref); let previous_owner = object::owner(object::address_to_object<Token>(addr)); object::delete(delete_ref); (addr, previous_owner) } else { let addr = burn_ref.self.extract(); let previous_owner = object::owner(object::address_to_object<Token>(addr)); (addr, previous_owner) };
if (royalty::exists_at(addr)) { royalty::delete(addr) };
let Token { collection, index: deprecated_index, description: _, name: _, uri: _, mutation_events, } = move_from<Token>(addr);
let index = if (exists<TokenIdentifiers>(addr)) { let TokenIdentifiers { index, name: _, } = move_from<TokenIdentifiers>(addr); aggregator_v2::read_snapshot(&index) } else { deprecated_index };
event::destroy_handle(mutation_events); collection::decrement_supply(&collection, addr, option::some(index), previous_owner);}
set_description
public fun set_description(mutator_ref: &token::MutatorRef, description: string::String)
Implementation
public fun set_description(mutator_ref: &MutatorRef, description: String) acquires Token { assert!(description.length() <= MAX_DESCRIPTION_LENGTH, error::out_of_range(EDESCRIPTION_TOO_LONG)); let token = borrow_mut(mutator_ref); if (std::features::module_event_migration_enabled()) { event::emit(Mutation { token_address: mutator_ref.self, mutated_field_name: string::utf8(b"description"), old_value: token.description, new_value: description }) } else { event::emit_event( &mut token.mutation_events, MutationEvent { mutated_field_name: string::utf8(b"description"), old_value: token.description, new_value: description }, ); }; token.description = description;}
set_name
public fun set_name(mutator_ref: &token::MutatorRef, name: string::String)
Implementation
public fun set_name(mutator_ref: &MutatorRef, name: String) acquires Token, TokenIdentifiers { assert!(name.length() <= MAX_TOKEN_NAME_LENGTH, error::out_of_range(ETOKEN_NAME_TOO_LONG));
let token = borrow_mut(mutator_ref);
let old_name = if (exists<TokenIdentifiers>(mutator_ref.self)) { let token_concurrent = &mut TokenIdentifiers[mutator_ref.self]; let old_name = aggregator_v2::read_derived_string(&token_concurrent.name); token_concurrent.name = aggregator_v2::create_derived_string(name); old_name } else { let old_name = token.name; token.name = name; old_name };
if (std::features::module_event_migration_enabled()) { event::emit(Mutation { token_address: mutator_ref.self, mutated_field_name: string::utf8(b"name"), old_value: old_name, new_value: name }) } else { event::emit_event( &mut token.mutation_events, MutationEvent { mutated_field_name: string::utf8(b"name"), old_value: old_name, new_value: name }, ); };}
set_uri
public fun set_uri(mutator_ref: &token::MutatorRef, uri: string::String)
Implementation
public fun set_uri(mutator_ref: &MutatorRef, uri: String) acquires Token { assert!(uri.length() <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG)); let token = borrow_mut(mutator_ref); if (std::features::module_event_migration_enabled()) { event::emit(Mutation { token_address: mutator_ref.self, mutated_field_name: string::utf8(b"uri"), old_value: token.uri, new_value: uri, }) } else { event::emit_event( &mut token.mutation_events, MutationEvent { mutated_field_name: string::utf8(b"uri"), old_value: token.uri, new_value: uri, }, ); }; token.uri = uri;}