Author's Introduction:
I'm Aladeen, fresh graduate student and novi blockchain developer. I love meeting people across the globe and make new connections. 'm looking for people that have interest in coding and problem solving to join me for a wonderful journey so if you're interested feel free to reach out. I'm looking for people that have interest in coding and problem solving to join me for a wonderful journey so if you're interested feel free to reach out.
Author Github:https://github.com/Aladeenb
Move Learning Camp:
https://github.com/NonceGeek/Web3-dApp-Camp
The term "Token" usually refers to both on-chain homogenized tokens and non-homogenized tokens. As the blockchain evolves, so do the standards and models for defining tokens. In Aptos, 'Token V2' refers to the upgraded standard for non-homogenized tokens. While the original model "Token V1" used Resource as the representation of tokens on the chain, the new model uses Object. this upgrade breaks the limitations of the initial version and allows it to benefit from the Object Model.
0x01 Token V1: Overview
The original homogenized token model in the Aptos blockchain called 'Token V1' uses resources as a way to represent tokens on the chain. This model has advantages and disadvantages.
1.1 Advantages
The "Token V1" can be stored in on-chain resources, minimizing the number of manual interactions with the Module Modules themselves and ensuring the invariance of Token properties.
It also uses a 'PropertyMap' to represent the characteristics of the Token on the chain. This allows for more extensibility, which means we can dynamically store properties for various data types to add more features to the Token after its initial creation. It also uses allows storing different types of data after serialization and deserialization via Binary Canonical Serialization (BCS)
1.2 Disadvantages
In this Token model, data is stored in resource accounts, which means that Token can be nested in multiple layers of data, leading to various issues such as querying the owner.
"PropertyMap provides great flexibility and robustness, but this comes at the cost of increased memory usage and computational overhead.
0x02 Token V2: A New Era
Token V2 refers to the upgraded non-homogenized token standard within the Aptos blockchain, using the object model.
2.1 Token V2 Components
The Aptos token object model consists of the following modules:
collection.move
: Define object-based collections.token.move
: Define the core logic of object-based Token (TokenV2).royalty.move
: Defines an object-based royalty system. Royalties can be used for Token Collections or standalone Token.aptos_token.move
: Defines a basic Token for code-free solutions, similar to the original Token in the 0x3::token module. has basic Token and Collection functionality. Allows the creator to control how the Token changes and whether it can be frozen, burned, and minted. It also has standard methods for transferring objects and related events, and attribute types for metadata.property_map.move
: Provides generic metadata help for "AptosToken". It is a specific version of "SimpleMap" that ensures precise data types and saves storage space by utilizing the constant u64 to represent types and storing values in bcs format.
2.2 Features of Token V2
Token V2 is built on top of the object model, which means that a Token is an object that is part of a collection (which is also an object). This provides a variety of new features while still being inexpensive.
The object model separates ownership from data, which means that all object resources are top-level data, making them globally addressable and queryable.
In terms of scalability, you can add resources to objects even after they are initially created, which allows for more scalability and flexibility in the future.
In terms of composability, objects are so similar to accounts that they can even have other objects, which allows for the creation of true on-chain object composability, i.e. the ability to store native, typed objects with each other.
Click to read more about the object model:
https://noncegeek.medium.com/aptos-object-model-learning-move-0x01-550708f0fd33
2.3 Token V2 Life Cycle
- Entity calls create on the top-level object type.
- The top-level object type calls create on its direct ancestor.
- Repeat this until the top ancestor is an "Object" structure that defines the
create_object
function. create_object
Generate a new address in theObjectGroup
This address within the resource group stores aObject
structure and returns aConstructorRef
The- A previously called create function can be created using the
ConstructorRef
to get the signer in theObjectGroup
resource to store the appropriate structure, make any other modifications, and then move theConstructorRef
Returns the stack. - Properties such as ownership, deletion, transferability and mutability can be defined for any module in the object creation stack.
0x03 Comparison of Token V1 and Token V2
Token V1 | Token V2 |
Based on a resource model | object-based model |
Costly to store their features on the chain | Inexpensive to store their features on the chain |
Unable to own Token | Inexpensive to store their features on the chain |
scalable | More scalable |
In some cases, data is neither addressable nor queryable | Data is always globally addressable and queryable |
In short, the evolution from Token V1 to Token V2 represents a super-major leap in the Aptos blockchain's token standard.
The new model offers greater flexibility, scalability and composability, paving the way for more complex and dynamic interactions along the chain.
0x04 Practical application of Tolem V2:hero.move
There is no better way to learn a language than from its pioneers, and Aptos Labs provides examples of how to use the new token model in the aptos-core repository:
https://github.com/aptos-labs/aptos-core/tree/main/aptos-move/move-examples/token_objects/hero
As of this writing, "hero.move" is the simplest but most complete example of token V2.
Smart Contracts allow to create a Hero, add properties to it, and transfer the Hero itself and its properties to another account:
struct Hero has key {
armor: Option<Object>, gender: String, String, String, String, String, String, String, String, String.
gender: String, race: String, String: String, String: String, String: String.
armor: Option<Object>, gender: String, race: String, shield: Option<Object>, weapon: Option<Object>, weapon: Option<Object>, String
weapon: Option<Object>, mutator_ref: token::token::weapon
mutator_ref: token::MutatorRef,
}
"hero" is the token, "armor", "gender", "race", "shield", "weapon" are the tokens in "hero" that represent its attributes. ", "armor", "gender", "race", "shield", and "weapon" are the tokens of "hero" that represent its attributes.
- "Hero" can have "armor", "shield" and "weapon". weapon".
- "weapon", "shield" and "armor" can have "gems". .
- "gems" can change the "attack" and "defense" values of "weapon", "shield" and "armor". Attack" and "Defense" values of "weapon", "shield" and "armor". They also have "magic" properties.
The life cycle of the code is shown below:
4.1 Initialization module
Before creating the hero, we need to initialize the module
fun init_module(account: &signer) {
let collection = string::utf8(b "Hero Quest!");
collection::create_unlimited_collection(
account,
string::utf8(b "collection description"),
collection,
option::none(),
string::utf8(b "collection uri"), collection, option::none(), collection
);
let on_chain_config = OnChainConfig {
collection, }; let on_chain_config = OnChainConfig {
}; let on_chain_config = OnChainConfig { collection, }; }
move_to(account, on_chain_config);
}
This is done by creating a collection and storing it in the "OnChainConfig" resource, which has the "key" keyword to store it globally. The collection will be queried briefly later.
struct OnChainConfig has key {
collection: String, }
}
4.2 Creating Hero
public fun create_hero(
creator: &signer,
creator: &signer, description: String, gender.
name: String, &signer
uri: String, &signer
): Object acquires OnChainConfig {
let constructor_ref = create(creator, description, name, uri);
let token_signer = object::generate_signer(&constructor_ref);
let hero = Hero {
armor: option::none(),
gender, race, and
race, shield: option::none(), gender, race, shield.
mutator_ref: token::generate_mutator_ref(&constructor_ref),
};
move_to(&token_signer, hero).
object::address_to_object(signer::address_of(&token_signer))
}
A Hero is essentially an object.create_hero
function creates a Hero and returns it before the function ends.
public fun create_hero(
): Object
...
object::address_to_object()
The newly created Hero data is stored in the resource account.
let hero = Hero {
armor: option::none(),
armor::option::none(, gender,
race, shield: option::none(), gender, race, shield
mutator_ref: token::generate_mutator_ref(&constructor_ref),
};
move_to(&token_signer, hero).
constructor_ref
Yes, it is. hero
A reference to the object. It generates a signer that is used to complete the storage operation.
create_hero
will eventually be wrapped in the entry function mint_hero
Center.
entry fun mint_hero(
account: &signer, description: String, &signer, &signer, &signer, &signer
account: &signer, description: String, gender: String, mint_hero(
description: String, gender: String, name: String, mint_hero(
name: String, race: String, mint_hero(
uri: String, ) acquires OnChainConfig {
) acquires OnChainConfig {
create_hero(account, description, gender, name, race, uri); }
}
4.3 Creating Shields, Armors, Weapons, and Gems
Creating these objects follows the same pattern as creating a Hero.
public fun create_weapon(
creator: &signer, attack: u64, u64, u64, u64, u64, u64, u64, u64
attack: u64,
description: String, name: String, weapon
description: String, name: String, uri: String, weapon_type.
weight: u64, ): Object acquires
): Object acquires OnChainConfig {
let constructor_ref = create(creator, description, name, uri);
let token_signer = object::generate_signer(&constructor_ref);
let weapon = Weapon {
attack, gem: option::none(); let weapon = weapon
gem: option::none(),
weapon_type, weight, weapon_type, weapon_type, weight, weapon_type, weapon_type
weapon_type, weight, }; let weapon = Weapon
};
move_to(&token_signer, weapon);
object::address_to_object(signer::address_of(&token_signer))
}
4.4 Adding/Removing Hero Attributes
Adding an attribute to Hero (or a Gem to Weapon, Armor, Shield) is a simple procedure:
- Getting objects
- Place the object into the Hero object
- Transferring objects to a new owner
public fun weapon_equip_gem(owner: &signer, weapon: Object, gem: Object) acquires Weapon {
let weapon_obj = borrow_global_mut(object::object_address(&weapon));
option::fill(&mut weapon_obj.gem, gem);
object::transfer_to_object(owner, gem, weapon);
}
Deleting an attribute is the same, except that we need to check if the attribute exists in the hero object.
public fun weapon_unequip_gem(owner: &signer, weapon: Object, gem: Object) acquires Weapon {
let weapon_obj = borrow_global_mut(object::object_address(&weapon));
let stored_gem = option::extract(&mut weapon_obj.gem);
assert!(stored_gem == gem, error::not_found(EINVALID_GEM_UNEQUIP));
object::transfer(owner, gem, signer::address_of(owner));
}
0x05 Reference
- Token v1 code base: https://github.com/aptos-labs/aptos-core/tree/main/aptos-move/framework/aptos-token
- Token v2 code base: https://github.com/aptos-labs/aptos-core/tree/main/aptos-move/framework/aptos-token-objects
- Object Model article: https://noncegeek.medium.com/aptos-object-model-learning-move-0x01-550708f0fd33
- Gas Calculation rules: https://aptos.dev/concepts/base-gas/#instruction-gas
- hero.move: https://github.com/aptos-labs/aptos-core/tree/main/aptos-move/move-examples/token_objects/hero
All of the above content is reproduced from the Internet, does not represent the position of AptosNews, is not investment advice, investment risk, the market need to be cautious, such as infringement, please contact the administrator to delete.