Fungible Asset
Deploy your Fungible Asset!
์์ ํํ ๋ฆฌ์ผ์ ํตํด Module์ ์์ฑํ๊ณ ๋ฐฐํฌํ๋ ๋ฐฉ๋ฒ๊ณผ ํธ๋์ญ์ ์ ํตํด Module์ ํจ์๋ฅผ ํธ์ถํ์ฌ Module๊ณผ ์ํธ์์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์์ต๋๋ค.
์ด๋ฒ ํํ ๋ฆฌ์ผ์์๋ ์ง๊ธ๊น์ง ๋ฐฐ์ด ๋ด์ฉ์ ์ด์ฉํ์ฌ Fungible Asset Module์ ๋ฐฐํฌํ๊ณ ๋๋ง์ Fungible Asset์ ๋ง๋ค์ด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์ด ํํ ๋ฆฌ์ผ์ ํตํด ์๋ ๋ด์ฉ์ ๋ฐฐ์ธ ์ ์์ต๋๋ค!
- Fungible Asset์ ์์ฑํ๋ ๋ก์ง๊ณผ ๋ฐฉ๋ฒ์ ๋ฐฐ์ธ ์ ์์ต๋๋ค.
- Fungible Asset Module๊ณผ ์ํธ์์ฉํ์ฌ ์ ์กํ๊ณ ์๊ฐํ ์ ์์ต๋๋ค.
- ์ ์ฒด ํํ ๋ฆฌ์ผ ์ฝ๋๋ ์๋ ๋งํฌ๋ฅผ ํตํด ํ์ธํ ์ ์์ต๋๋ค.
Step 1. Initializing Move environment and Profile
ํํ ๋ฆฌ์ผ ์งํ์ ์ํด ์๋ก์ด ํ๋ก์ ํธ ๋๋ ํ ๋ฆฌ๋ฅผ ์์ฑํ๊ณ ํฐ๋ฏธ๋์ ๊ฒฝ๋ก๋ฅผ ํด๋น ๋๋ ํ ๋ฆฌ๋ก ๋ณ๊ฒฝํฉ๋๋ค.
$ mkdir FungibleAsset
$ cd FungibleAsset
Move environment๋ฅผ ์ด๊ธฐํํ๊ธฐ ์ํด ์๋ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํฉ๋๋ค.
$ aptos move init --name <your_porject_name>
์๋ ๋ช ๋ น์ด๋ฅผ ์คํํ์ฌ ์ด๊ธฐ ๊ณ์ ์ ๋ณด๋ฅผ ์ค์ ํฉ๋๋ค.
$ aptos init --network testnet
config.yaml
ํ์ผ์์ account ๊ฐ์ ๋ณต์ฌํ ๋ค Move.toml
ํ์ผ์ [addresses]์ ๋ถ์ฌ๋ฃ์ด ๋ฐฐํฌํ Account์ address๋ฅผ ์ค์ ํฉ๋๋ค. ์ค์ ์๋ฃ ํ sources
๋๋ ํ ๋ฆฌ ๋ด์ move ํ์ผ์ ์์ฑํฉ๋๋ค.
$ cd sources
$ touch fungible_asset.move
Step 2. Writing Fungible Asset Module
์ ์ฒด์ ์ธ Fungible Asset์ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ํด๋น ์ฝ๋๋ Aptos ์ฌ๋จ์์ ์ ๊ณตํ๋ ๊ธฐ๋ณธ์ ์ธ Fungible Asset ๋ชจ๋์ ์ผ๋ถ ์์ ํ ๊ฒ์ผ๋ก ์ ์ฒด ์ฝ๋๋ ์ฌ๊ธฐ์์ ํ์ธํ ์ ์์ต๋๋ค.
// fungible_asset.move
module myAddress::fa_coin {
use aptos_framework::fungible_asset::{Self, MintRef, TransferRef, BurnRef, Metadata, FungibleAsset};
use aptos_framework::object::{Self, Object};
use aptos_framework::primary_fungible_store;
use aptos_framework::function_info;
use aptos_framework::dispatchable_fungible_asset;
use std::error;
use std::signer;
use std::string::{Self, utf8};
use std::option;
/// Only fungible asset metadata owner can make changes.
const ENOT_OWNER: u64 = 1;
const ASSET_SYMBOL: vector<u8> = b"MFA";
#[resource_group_member(group = aptos_framework::object::ObjectGroup)]
/// Hold refs to control the minting, transfer and burning of fungible assets.
struct ManagedFungibleAsset has key {
mint_ref: MintRef,
transfer_ref: TransferRef,
burn_ref: BurnRef,
}
/// Initialize metadata object and store the refs.
// :!:>initialize
fun init_module(admin: &signer) {
let constructor_ref = &object::create_named_object(admin, ASSET_SYMBOL);
primary_fungible_store::create_primary_store_enabled_fungible_asset(
constructor_ref,
option::none(),
utf8(b"MyFAToken"), /* name */
utf8(ASSET_SYMBOL), /* symbol */
8, /* decimals */
utf8(b"http://example.com/favicon.ico"), /* icon */
utf8(b"http://example.com"), /* project */
);
// Create mint/burn/transfer refs to allow creator to manage the fungible asset.
let mint_ref = fungible_asset::generate_mint_ref(constructor_ref);
let burn_ref = fungible_asset::generate_burn_ref(constructor_ref);
let transfer_ref = fungible_asset::generate_transfer_ref(constructor_ref);
let metadata_object_signer = object::generate_signer(constructor_ref);
move_to(
&metadata_object_signer,
ManagedFungibleAsset { mint_ref, transfer_ref, burn_ref }
); // <:!:initialize
// Override the deposit and withdraw functions which mean overriding transfer.
// This ensures all transfer will call withdraw and deposit functions in this module
// and perform the necessary checks.
// This is OPTIONAL. It is an advanced feature and we don't NEED a global state to pause the FA coin.
let deposit = function_info::new_function_info(
admin,
string::utf8(b"fa_coin"),
string::utf8(b"deposit"),
);
let withdraw = function_info::new_function_info(
admin,
string::utf8(b"fa_coin"),
string::utf8(b"withdraw"),
);
dispatchable_fungible_asset::register_dispatch_functions(
constructor_ref,
option::some(withdraw),
option::some(deposit),
option::none(),
);
}
#[view]
/// Return the address of the managed fungible asset that's created when this module is deployed.
public fun get_metadata(): Object<Metadata> {
let asset_address = object::create_object_address(&@myAddress, ASSET_SYMBOL);
object::address_to_object<Metadata>(asset_address)
}
/// Deposit function override to ensure that the account is not denylisted and the FA coin is not paused.
/// OPTIONAL
public fun deposit<T: key>(
store: Object<T>,
fa: FungibleAsset,
transfer_ref: &TransferRef,
) {
fungible_asset::deposit_with_ref(transfer_ref, store, fa);
}
/// Withdraw function override to ensure that the account is not denylisted and the FA coin is not paused.
/// OPTIONAL
public fun withdraw<T: key>(
store: Object<T>,
amount: u64,
transfer_ref: &TransferRef,
): FungibleAsset {
fungible_asset::withdraw_with_ref(transfer_ref, store, amount)
}
// :!:>mint
/// Mint as the owner of metadata object.
public entry fun mint(admin: &signer, to: address, amount: u64) acquires ManagedFungibleAsset {
let asset = get_metadata();
let managed_fungible_asset = authorized_borrow_refs(admin, asset);
let to_wallet = primary_fungible_store::ensure_primary_store_exists(to, asset);
let fa = fungible_asset::mint(&managed_fungible_asset.mint_ref, amount);
fungible_asset::deposit_with_ref(&managed_fungible_asset.transfer_ref, to_wallet, fa);
}// <:!:mint
/// Transfer as the owner of metadata object ignoring `frozen` field.
public entry fun transfer(admin: &signer, from: address, to: address, amount: u64) acquires ManagedFungibleAsset {
let asset = get_metadata();
let transfer_ref = &authorized_borrow_refs(admin, asset).transfer_ref;
let from_wallet = primary_fungible_store::primary_store(from, asset);
let to_wallet = primary_fungible_store::ensure_primary_store_exists(to, asset);
let fa = withdraw(from_wallet, amount, transfer_ref);
deposit(to_wallet, fa, transfer_ref);
}
/// Burn fungible assets as the owner of metadata object.
public entry fun burn(admin: &signer, from: address, amount: u64) acquires ManagedFungibleAsset {
let asset = get_metadata();
let burn_ref = &authorized_borrow_refs(admin, asset).burn_ref;
let from_wallet = primary_fungible_store::primary_store(from, asset);
fungible_asset::burn_from(burn_ref, from_wallet, amount);
}
/// Borrow the immutable reference of the refs of `metadata`.
/// This validates that the signer is the metadata object's owner.
inline fun authorized_borrow_refs(
owner: &signer,
asset: Object<Metadata>,
): &ManagedFungibleAsset acquires ManagedFungibleAsset {
assert!(object::is_owner(asset, signer::address_of(owner)), error::permission_denied(ENOT_OWNER));
borrow_global<ManagedFungibleAsset>(object::object_address(&asset))
}
}
์ต์ด Module ๋ฐฐํฌ ์ init_module ํจ์๋ฅผ ์คํํ์ฌ Object๋ฅผ ์์ฑํ๊ณ Metadata๋ฅผ Object์๊ฒ Resource๋ก ํ ๋นํฉ๋๋ค. ์ดํ ํด๋น Metadata Resource๋ฅผ ์ด์ฉํ์ฌ Fungible Asset์ ๊ด๋ฆฌํ ์ ์๋ ๊ถํ(Ref)์ ์์ฑํ ๋ค Object์๊ฒ Resource๋ก ํ ๋นํฉ๋๋ค.
์ด๋ฌํ ๋ฐฉ์์ผ๋ก Module์ ์์ฑํ๋ฉด ํด๋น Object์ Owner๋ Mint, Transfer, Burn ๋ฑ์ ํจ์๋ฅผ ์คํํ ์ ์๋ ๊ถํ์ ํ๋ํ๊ฒ ๋ฉ๋๋ค. ์ดํ Module์ ์ ์ํ ํจ์๋ฅผ ์คํํ์ฌ Mint, Transfer, Burn ๋ฑ ์ํ๋ ๋ก์ง์ ๊ตฌํํ ์ ์์ต๋๋ค.
๐ก **Ref๋ ๊ถํ์ ๊ด๋ฆฌํ ์ ์๋ ๊ฐ๋ ฅํ ๋ฐฉ๋ฒ ์ค ํ๋ ์ ๋๋ค!**
๋ณธ ํํ ๋ฆฌ์ผ์ Ref ์ฌ์ฉ ์์๋ฅผ ์ํด Object์ Owner๋ง Ref๋ฅผ ๊ฐ์ง ์ ์๋๋ก ์์ฑ๋์์ต๋๋ค. ์ค์ ์๋น์ค๋ฅผ ์ํ Module ์์ฑ ์ ๋ณธ์ธ์ ๋ก์ง์ ๋ง๊ฒ ์ค์ ํ์ฌ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋๋ก ์ฃผ์ํด์ผ ํฉ๋๋ค.
Step 3. Understanding Module
์ด๋ฒ Step์์๋ Module์ด ์ด๋ป๊ฒ ๊ตฌ์ฑ๋์ด ์๋์ง ์์๋ด ๋๋ค.
struct ManagedFungibleAsset
: ๊ถํ์ ๊ด๋ฆฌํ๋ Ref๋ฅผ ์ ์ฅํ๊ธฐ ์ํ ๊ตฌ์กฐ์ฒด ์ ๋๋ค. ํ์ฌ ์ฝ๋์์๋ mint, transfer, burn 3๊ฐ์ง ๊ธฐ๋ฅ์ ์คํํ๊ธฐ ์ํ ๊ถํ์ ํ์ธํ๋ Ref๋ฅผ ๊ด๋ฆฌํ๋๋ก ์์ฑ๋์ด ์์ต๋๋ค.
#[resource_group_member(group = aptos_framework::object::ObjectGroup)]
struct ManagedFungibleAsset has key {
mint_ref: MintRef,
transfer_ref: TransferRef,
burn_ref: BurnRef,
}
- ๊ฐ์ฒด ์์ฑ ๋ฐ ์ด๊ธฐํ
Module ๋ฐฐํฌ ์ ์คํ๋๋ constructor ํจ์ ์ ๋๋ค. Object๋ฅผ ์์ฑํ๊ณ ๊ตฌ์กฐ์ฒด๋ฅผ ํด๋น Object์ ํ ๋นํ ํ constructor_ref๋ฅผ ๋ฐํํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ constructor_ref์ ์ ๋ ฅํ ์ธ์ ๊ฐ์ ์ด์ฉํด ์ญ์ ๊ฐ ๋ถ๊ฐ๋ฅํ ๊ตฌ์กฐ์ฒด๋ฅผ ์์ฑํ๊ณ Object์ ํ ๋นํฉ๋๋ค.
fun init_module(admin: &signer) {
let constructor_ref = &object::create_named_object(admin, ASSET_SYMBOL);
primary_fungible_store::create_primary_store_enabled_fungible_asset(
constructor_ref,
option::none(),
utf8(b"MyFAToken"), /* name */
utf8(ASSET_SYMBOL), /* symbol */
8, /* decimals */
utf8(b"http://example.com/favicon.ico"), /* icon */
utf8(b"http://nodit.lambda256.io"), /* project */
);
- ๊ด๋ฆฌ ์ฐธ์กฐ(Ref) ์์ฑ
์์ฑํ constructor_ref๋ฅผ ์ด์ฉํด mint_ref, burn_ref, transfer_ref์ ์์ฑํ๊ณ ๊ตฌ์กฐ์ฒด์ ์ ๋ ฅ ํ Object์ ํ ๋นํฉ๋๋ค.
์ด๋ฅผ ํตํด Mint, Burn, Transfer ๊ธฐ๋ฅ์ ์คํํ ์ ์๋ ๊ถํ์ ๊ด๋ฆฌํฉ๋๋ค.
// Create mint/burn/transfer refs to allow creator to manage the fungible asset.
let mint_ref = fungible_asset::generate_mint_ref(constructor_ref);
let burn_ref = fungible_asset::generate_burn_ref(constructor_ref);
let transfer_ref = fungible_asset::generate_transfer_ref(constructor_ref);
let metadata_object_signer = object::generate_signer(constructor_ref);
move_to(
&metadata_object_signer,
ManagedFungibleAsset { mint_ref, transfer_ref, burn_ref }
); // <:!:initialize
- ํจ์ ๊ตฌ์กฐ์ฒด ์์ฑ ๋ฐ ํ ๋น
function_info::new_function_info ํจ์๋ฅผ ์ด์ฉํด fa_coin ๋ชจ๋์ deposit ํจ์์ withdraw ํจ์์ ๋ํ ๊ตฌ์กฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์ด๋ฅผ Object์ ํ ๋นํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ ์ ๋ deposit, withdraw ํจ์์ ์ปค์คํ ๋ก์ง์ ์์ฑํ์ฌ ์คํํ ์ ์์ต๋๋ค.
let deposit = function_info::new_function_info(
admin,
string::utf8(b"fa_coin"),
string::utf8(b"deposit"),
);
let withdraw = function_info::new_function_info(
admin,
string::utf8(b"fa_coin"),
string::utf8(b"withdraw"),
);
dispatchable_fungible_asset::register_dispatch_functions(
constructor_ref,
option::some(withdraw),
option::some(deposit),
option::none(),
);
}
- Object ๊ฐ์ ธ์ค๊ธฐ
Account Address์ Seed ๊ฐ(๋ณธ ํํ ๋ฆฌ์ผ์์๋ Symbol ๊ฐ)์ ์ด์ฉํด Object์ ์ฃผ์๋ฅผ ์์ฑํ๊ณ ํด๋น ์ฃผ์์ ์ผ์นํ๋ Object๋ฅผ ๋ฐํํฉ๋๋ค.
public fun get_metadata(): Object<Metadata> {
let asset_address = object::create_object_address(&@myAddress, ASSET_SYMBOL);
object::address_to_object<Metadata>(asset_address)
}
- deposit ํจ์ ์ ์
Object์ FungibleAsset ๊ตฌ์กฐ์ฒด, transfer_ref๋ฅผ ์ด์ฉํด deposit_with_ref ํจ์๋ฅผ ์คํํฉ๋๋ค. ํด๋น ํจ์์ ์คํ ๊ฒฐ๊ณผ๋ก Object์ ํ ๋น๋ balance์ amount ๋งํผ ์ฆ๊ฐ์ํต๋๋ค.
public fun deposit<T: key>(
store: Object<T>,
fa: FungibleAsset,
transfer_ref: &TransferRef,
) {
fungible_asset::deposit_with_ref(transfer_ref, store, fa);
}
- withdraw ํจ์ ์ ์
Object์ FungibleAsset ๊ตฌ์กฐ์ฒด, transfer_ref๋ฅผ ์ด์ฉํด withdraw_with_ref ํจ์๋ฅผ ์คํํฉ๋๋ค. ํด๋น ํจ์์ ์คํ ๊ฒฐ๊ณผ๋ก Object์ ํ ๋น๋ balance์ amount ๋งํผ ๊ฐ์์ํต๋๋ค.
public fun withdraw<T: key>(
store: Object<T>,
amount: u64,
transfer_ref: &TransferRef,
): FungibleAsset {
fungible_asset::withdraw_with_ref(transfer_ref, store, amount)
}
- mint ํจ์ ์ ์
Object๋ฅผ ๋ถ๋ฌ์จ ํ signer์ Object๋ฅผ ์ด์ฉํ์ฌ Mint ๊ถํ์ ๊ฐ์ ธ์ต๋๋ค. ์์ฐ์ ์ ์ก๋ฐ๋ ์ฃผ์์ ์์ก์ ํ์ธํ ์ ์๋ ๊ตฌ์กฐ์ฒด ์กด์ฌ ์ ๋ฌด ํ์ธ ํ ์์ผ๋ฉด ์ด๋ฅผ ์์ฑํฉ๋๋ค. ์ดํ fungible_asset::mint ํจ์๋ฅผ ์คํํ์ฌ ๊ตฌ์กฐ์ฒด๋ฅผ ์์ฑํ๊ณ to ์ฃผ์์ ๊ตฌ์กฐ์ฒด์ ์๊ณ ๋ฅผ ๊ตฌ์กฐ์ฒด์ amount ๋งํผ ์ฆ๊ฐ์ํต๋๋ค.
public entry fun mint(admin: &signer, to: address, amount: u64) acquires ManagedFungibleAsset {
let asset = get_metadata();
let managed_fungible_asset = authorized_borrow_refs(admin, asset);
let to_wallet = primary_fungible_store::ensure_primary_store_exists(to, asset);
let fa = fungible_asset::mint(&managed_fungible_asset.mint_ref, amount);
fungible_asset::deposit_with_ref(&managed_fungible_asset.transfer_ref, to_wallet, fa);
}
- transfer ํจ์ ์ ์
Object๋ฅผ ๋ถ๋ฌ์จ ํ signer์ Object๋ฅผ ์ด์ฉํ์ฌ Transfer ๊ถํ์ ๊ฐ์ ธ์ต๋๋ค. ์์ฐ์ ์ ์กํ๋ ์ฃผ์์ FungibleStore๋ฅผ ํ์ธํ ๋ค ์ ๋ ฅํ amount ๋งํผ ์์ฐ์ ๊ฐ์์ํค๊ณ ์์ฐ์ ์ ์ก๋ฐ๋ ์ฃผ์์ FungibleStore์ ์์ฐ์ ํ์ธํ ํ amount ๋งํผ ์์ฐ์ ์ฆ๊ฐ์ํต๋๋ค.
public entry fun transfer(admin: &signer, from: address, to: address, amount: u64) acquires ManagedFungibleAsset {
let asset = get_metadata();
let transfer_ref = &authorized_borrow_refs(admin, asset).transfer_ref;
let from_wallet = primary_fungible_store::primary_store(from, asset);
let to_wallet = primary_fungible_store::ensure_primary_store_exists(to, asset);
let fa = withdraw(from_wallet, amount, transfer_ref);
deposit(to_wallet, fa, transfer_ref);
}
- burn ํจ์ ์ ์
Object๋ฅผ ๋ถ๋ฌ์จ ํ signer์ Object๋ฅผ ์ด์ฉํ์ฌ Burn ๊ถํ์ ๊ฐ์ ธ์จ ํ from ์ฃผ์๊ฐ ๋ณด์ ํ ์๋์์ amount ๋งํผ ์ฐจ๊ฐํฉ๋๋ค.
public entry fun burn(admin: &signer, from: address, amount: u64) acquires ManagedFungibleAsset {
let asset = get_metadata();
let burn_ref = &authorized_borrow_refs(admin, asset).burn_ref;
let from_wallet = primary_fungible_store::primary_store(from, asset);
fungible_asset::burn_from(burn_ref, from_wallet, amount);
}
- ๊ฒ์ฆ๋ Ref ๋ถ๋ฌ์ค๊ธฐ
Owner์ signer ๊ฐ๊ณผ Object๋ฅผ ์ด์ฉํ์ฌ ์์ ์๋ฅผ ๊ฒ์ฆํ๊ณ ๊ตฌ์กฐ์ฒด๋ฅผ ๋ถ๋ฌ์ต๋๋ค. ์ด๋ฅผ ๋ฐํ์ผ๋ก Mint, Transfer, Burn ๋ฑ์ Ref๊ฐ ํ์ํ ๋ก์ง์ ์ด์ฉํ ์ ์์ต๋๋ค.
inline fun authorized_borrow_refs(
owner: &signer,
asset: Object<Metadata>,
): &ManagedFungibleAsset acquires ManagedFungibleAsset {
assert!(object::is_owner(asset, signer::address_of(owner)), error::permission_denied(ENOT_OWNER));
borrow_global<ManagedFungibleAsset>(object::object_address(&asset))
}
}
Step 4. Deploy your Module
์ต์ข ์ ์ผ๋ก ์์ฑํ Module์ Aptos CLI๋ฅผ ์ด์ฉํด Aptos ๋คํธ์ํฌ์ ๋ฐฐํฌํ ์ ์์ต๋๋ค. ๋ฐฐํฌ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- Module Compile
move ํ์ผ์ด ์์ฑ๋์ด ์๋ ๊ฒฝ๋ก์์ Aptos CLI๋ฅผ ์ด์ฉํด Module์ ์ปดํ์ผ ํฉ๋๋ค.
$ aptos move compile
- Module Deploy
Compile์ด ์๋ฃ๋ move ํ์ผ์ Aptos CLI๋ฅผ ์ด์ฉํด Aptos ๋คํธ์ํฌ์ ๋ฐฐํฌํฉ๋๋ค. move ํ์ผ์ด ์์ฑ๋์ด ์๋ ๊ฒฝ๋ก์์ ์๋ ๋ช ๋ น์ด๋ฅผ ์คํํฉ๋๋ค.
$ aptos move publish
Nodit์์ ์ ๊ณตํ๋ Aptos Node API ์ค Get account module API๋ฅผ ์ด์ฉํ๋ฉด ํน์ Account๊ฐ ๋ฐฐํฌํ Module์ ํ์ธํ ์ ์์ต๋๋ค.
Nodit Aptos Node API๋ ์ด๋ป๊ฒ ์ฌ์ฉํ ์ ์๋์?
์๋ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ Get account module API๋ฅผ ๋์ฑ ์์ธํ ์์๋ณด์ธ์!
Get account module API๋ Query Params๋ก Account Address์ moduleName์ ์ด์ฉํฉ๋๋ค. header๋ก X-API-KEY๋ฅผ ์ถ๊ฐํ๊ณ Nodit์ ํตํด ๋ฐ๊ธ๋ฐ์ X-API-KEY๋ฅผ ์ ๋ ฅํ ํ API๋ฅผ ํธ์ถํด ๋ณด์ธ์!
curl --request GET \
--url https://aptos-testnet.nodit.io/v1/accounts/<account_address>/module/<module_name> \
--header 'X-API-KEY: <Your X-API-KEY>' \
--header 'accept: application/json'
์๋์ ๊ฐ์ด ๋ฐฐํฌํ Module์ ํ์ธํ ์ ์์ต๋๋ค.
{
"bytecode": "0xa11ceb0b060000...",
"abi": {
"address": "0xabc...90",
"name": "<your_module_name>",
...
}
}
Step 5. Interact to Module
Module ๋ฐฐํฌ์ ์ฑ๊ณตํ๋ค๋ฉด ํธ๋์ญ์ ์ ํตํด Module์ ์์ฑ๋ ํจ์๋ฅผ ํธ์ถํ์ฌ Fungible Asset์ ๋ฐํํ ์ ์์ต๋๋ค. ํธ๋์ญ์ ์ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ํธ๋์ญ์ ๋น๋
- ํธ๋์ญ์ ์๋ฎฌ๋ ์ด์
- ํธ๋์ญ์ ์๋ช
- ํธ๋์ญ์ ์ ์ถ
- ํธ๋์ญ์ ๊ฒฐ๊ณผ ํ์ธ
Aptos Typescript SDK๋ฅผ ์ด์ฉํ์ฌ ํธ๋์ญ์ ์ ์คํํด ๋ณด์ธ์!
import {
Account,
Aptos,
AptosConfig,
Ed25519PrivateKey,
} from "@aptos-labs/ts-sdk";
const config = new AptosConfig({
fullnode: "your_Nodit_Aptos_testnet_node_endpoint",
indexer: "your_Nodit_Aptos_indexer_endpoint",
});
const aptos = new Aptos(config);
const privateKey = "your_private_key"; // 0x12345...
const ed25519Scheme = new Ed25519PrivateKey(privateKey);
const senderAccount = Account.fromPrivateKey({
privateKey: ed25519Scheme,
});
const amount: number = 100_000_000_000; // change amount to mint
(async (senderAccount: Account, amount: number) => {
try {
const senderAddress = senderAccount.accountAddress.toString();
const transaction = await aptos.transaction.build.simple({
sender: senderAddress,
data: {
function: "module_owner_address::fungible_asset::mint", //0x1::aptos_account::transfer
functionArguments: [
senderAddress,
amount, // mint function requires to_address and amount as arguments
],
},
});
const senderAuthenticator = aptos.transaction.sign({
signer: senderAccount,
transaction,
});
const submitTx = await aptos.transaction.submit.simple({
transaction,
senderAuthenticator,
});
const executedTransaction = await aptos.waitForTransaction({
transactionHash: submitTx.hash,
});
console.log(executedTransaction);
} catch (error) {
console.error(error);
}
})(senderAccount, amount);
์ฑ๊ณต์ ์ผ๋ก ๋ฐํ์ด ๋์๋ค๋ฉด ๋ค๋ฅธ ์ฃผ์๋ก ์ ์กํ๋ transfer ํจ์๋ฅผ ์ด์ฉํด ๋ฐฉ๊ธ ๋ฐํํ Fungible Asset์ ์ ์กํด ๋ณด์ธ์!
์์ ์ฝ๋๋ฅผ ์คํํ์ฌ Module๊ณผ Fungible Asset์ ๋ฐฐํฌํ๊ณ ์์ฑํ ์ ์๋์?
- ํ์ธ์ด ๋์ง ์๋๋ค๋ฉด ์์ ์ฝ๋์ ๋ค๋ฅธ ๋ถ๋ถ์ด ์๋์ง ํ์ธํด ๋ณด์ธ์.
- ์์ ์ฝ๋์ ์ฐจ์ด๊ฐ ์๋๋ฐ ๋์ง ์๋์? ์ฌ๊ธฐ[QnA ๋งํฌ]๋ฅผ ํด๋ฆญํ์ฌ QnA๋ก ๋จ๊ฒจ์ฃผ์ธ์!
Aptos๋ ๋งค์ฐ ๋น ๋ฅด๊ฒ ์ ๋ฐ์ดํธ ๋๊ณ ์์ต๋๋ค!
Aptos ์ฌ๋จ์์ ๋ฐฐํฌํ SDK ๋ฒ์ ์ ๋ฐ๋ผ ๋ณ๊ฒฝ๋๋ ์ ์ด ์์ ์ ์์ต๋๋ค. Nodit์ ํญ์ ์ด๋ฅผ ํ์ธํ๊ณ ์์ผ๋ ์์ ์ ๋ฐ๋ผ ์ฝ๋ ๋ณ๊ฒฝ์ผ๋ก ์ธํ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
Updated 12 days ago