콘텐츠로 이동

첫 번째 대체 가능한 자산

이 튜토리얼은 FACoin이라는 이름의 자체 대체 가능한 자산(FA)을 생성하는 방법을 알려줍니다. 대체 가능한 자산 표준은 민팅, 전송, 소각 및 계정 잔액 추적에 대한 내장 지원을 제공하므로 대체 가능한 자산을 나타내는 데 유용합니다. TypeScript SDK를 사용하여 컨트랙트를 배포하고 온체인에 올라간 후 테스트할 것입니다.

높은 수준에서 대체 가능한 자산 표준은 두 가지 주요 객체를 통해 작동합니다:

  1. 대체 가능한 자산에 대한 정보를 저장하는 Metadata 객체
  2. 대체 가능한 자산을 가진 각 계정의 현재 계정 잔액을 추적하는 FungibleStore

누군가에게 대체 가능한 자산을 보내면 FungibleStore를 받고 두 계정의 잔액이 적절히 업데이트됩니다.

여기서는 대체 가능한 자산 표준이 어떻게 작동하는지 보기 위해 예제 FACoin 컨트랙트를 수정, 배포 및 테스트할 것입니다. 자체 대체 가능한 자산 컨트랙트를 작성하는 경우 여기에서 Stablecoin 예제 컨트랙트를 참조할 수도 있습니다.

  1. 설치하세요.

    이것은 배포 스크립트에서 FACoin 컨트랙트를 온체인에 게시하는 데 사용됩니다.

  2. TypeScript SDK 저장소를 복제합니다.

    이 저장소에는 대체 가능한 자산 예제 코드가 포함되어 있습니다.

    Terminal window
    git clone https://github.com/aptos-labs/aptos-ts-sdk.git
  3. 복제된 저장소의 최상위 수준으로 이동합니다.

    Terminal window
    cd aptos-ts-sdk
  4. SDK의 의존성을 설치합니다.

    Terminal window
    pnpm install
  5. TypeScript SDK를 빌드합니다.

    예제에는 TypeScript SDK의 로컬 빌드가 필요합니다.

    Terminal window
    pnpm build
  6. 편집기에서 fa_coin.move를 엽니다.

    fa_coin.moveexamples/typescript/move/facoin/sources/fa_coin.move에서 찾을 수 있습니다.

    이것은 컨트랙트 로직의 대부분을 포함하는 Move 파일입니다. 실제 작동 예제를 보여준 후에 이 컨트랙트가 어떻게 작동하는지에 대한 세부 사항을 살펴보겠습니다.

  7. ASSET_NAME을 새 대체 가능한 자산의 이름으로 편집합니다.

    예: “Tutorial Token”. 여기서 설정한 값은 배포된 컨트랙트와 작동 방식을 테스트할 때 나타납니다.

  8. examples/typescript로 이동합니다.

    Terminal window
    cd examples/typescript
  9. 예제의 의존성을 설치합니다.

    Terminal window
    pnpm install
  10. your_fungible_asset를 실행합니다.

    Terminal window
    pnpm run your_fungible_asset

    대체 가능한 자산이 생성되고 전송되는 방법을 보여주는 다음과 같은 출력을 볼 수 있습니다:

    Terminal window
    === Addresses ===
    Alice: 0x0c5dd7abbd67db06325fa1a2f37a1833f9a92ff2beb90f32495a9d80972429cd
    Bob: 0x2a796f4255d5c23684fe6cc521069d684516031bb5ae1ad2061ddc5414450807
    Charlie: 0xd824909be65a224f651ff6e9b82ec99ad5707fcef739d1003be20fc69fb93d7a
    === Compiling FACoin package locally ===
    In order to run compilation, you must have the `aptos` CLI installed.
    Running the compilation locally, in a real situation you may want to compile this ahead of time.
    aptos move build-publish-payload --json-output-file move/facoin/facoin.json --package-dir move/facoin --named-addresses FACoin=0x0c5dd7abbd67db06325fa1a2f37a1833f9a92ff2beb90f32495a9d80972429cd --assume-yes
    Compiling, may take a little while to download git dependencies...
    UPDATING GIT DEPENDENCY https://github.com/aptos-labs/aptos-core.git
    INCLUDING DEPENDENCY AptosFramework
    INCLUDING DEPENDENCY AptosStdlib
    INCLUDING DEPENDENCY MoveStdlib
    BUILDING facoin
    ===Publishing FACoin package===
    Transaction hash: 0x0c8a24987bdf2e5e40d8a00f6c97ac55419757bc440097d76959a64dbeafc351
    metadata address: 0x2e0e90c701233467f27150f42d365e27e72eb0be8e2a74ee529c31b813bbb321
    All the balances in this example refer to balance in primary fungible stores of each account.
    Alice's initial balance: 0.
    Bob's initial balance: 0.
    Charlie's initial balance: 0.
    Alice mints Charlie 100 coins.
    Charlie's updated "Tutorial Token" primary fungible store balance: 0.
    Alice freezes Bob's account.
    Alice as the admin forcefully transfers the newly minted coins of Charlie to Bob ignoring that Bob's account is frozen.
    Bob's updated "Tutorial Token" balance: 0.
    Alice unfreezes Bob's account.
    Alice burns 50 coins from Bob.
    Bob's updated "Tutorial Token" balance: 0.
    Bob transfers 10 coins to Alice as the owner.
    Alice's updated "Tutorial Token" balance: 0.
    Bob's updated "Tutorial Token" balance: 0.
    done.

fa_coin.move 예제 컨트랙트 이해하기

섹션 제목: “fa_coin.move 예제 컨트랙트 이해하기”

FACoin.move의 전체 컨트랙트는 여기에서 찾을 수 있습니다.

이 컨트랙트가 어떻게 작성되었는지 단계별로 살펴보겠습니다.

  1. Move.toml

    Move.toml 파일을 통해 Move는 의존성을 가져오고, 사용할 주소를 결정하며, 컨트랙트에 대한 메타데이터를 포함할 수 있습니다.

    대체 가능한 자산에 어떤 기능을 추가하든 관계없이 Move.toml은 최소한 이와 비슷한 필드를 가질 것입니다. 이 경우 배포 시 지정해야 하는 기본 컨트랙트 주소 FACoin이 있습니다(값을 ”_“로 두어 표시). 또한 “AptosFramework”에서 대체 가능한 자산 표준을 가져오기 위한 GitHub 의존성을 포함합니다.

    [package]
    name = "facoin"
    version = "1.0.0"
    authors = []
    [addresses]
    FACoin = "_"
    [dependencies.AptosFramework]
    git = "https://github.com/aptos-labs/aptos-core.git"
    rev = "mainnet"
    subdir = "aptos-move/framework/aptos-framework"
  2. 가져오기

    FACoin 모듈은 여러 중요한 모듈을 사용합니다:

    1. fungible_asset에는 FungibleAsset을 민팅, 전송, 소각 및 생성하는 권한을 부여하는 로직이 포함되어 있습니다.
    2. object는 Aptos 객체 생성을 허용합니다.
    3. primary_fungible_store에는 새로운 대체 가능한 자산에 대한 계정 잔액을 추적하는 로직이 포함되어 있습니다.
    module FACoin::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 std::error;
    use std::signer;
    use std::string::utf8;
    use std::option;
    //...
    }

    이러한 가져오기는 Move.toml 파일에서 GitHub 의존성으로 정의됩니다.

  3. init_module

    이 함수는 모듈이 처음 게시될 때 적절한 권한과 객체를 설정하기 위해 호출됩니다. FACoin의 경우 자산의 MetaData 객체(자산의 이름 및 심볼과 같은 것들을 포함)를 초기화하고 대체 가능한 자산이 사용될 방법에 대한 관련 참조를 가져오는 데 사용됩니다.

    ManagedFungibleAsset 표준은 이 모듈이 사용할 수 있는 권한을 추적하는 데 도움이 됩니다.

    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(ASSET_NAME),
    utf8(ASSET_SYMBOL),
    8,
    utf8(b"http://example.com/favicon.ico"),
    utf8(b"http://example.com"),
    );
    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 }
    )
    }
  4. 뷰 함수

    자체 대체 가능한 자산을 생성할 때 나중에 필요한 데이터에 대한 뷰 함수를 추가하는 것이 도움이 될 수 있습니다. 이 경우 예제 시나리오에서 어떤 자산이 거래되고 있는지 보고하기 위해 자산의 이름을 보고 싶었습니다.

    #[view]
    public fun get_metadata(): Object<Metadata> {
    let asset_address = object::create_object_address(&@FACoin, ASSET_SYMBOL);
    object::address_to_object<Metadata>(asset_address)
    }
    #[view]
    public fun get_name(): string::String {
    let metadata = get_metadata();
    fungible_asset::name(metadata)
    }
  5. 엔트리 함수

    모든 대체 가능한 자산은 비슷한 인터페이스(민트, 전송, 소각, 동결, 동결 해제, 입금, 출금)를 가집니다. 다음은 자금을 민팅하고 적절한 수신자에게 전송하는 최소한의 민트 함수의 예입니다:

    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);
    }

자체 대체 가능한 자산을 구축하려면 fa_coin.move를 시작점으로 사용하거나 여기에서 다른 코드 예제를 살펴볼 수 있습니다.

어쨌든 대체 가능한 자산 표준은 온체인에서 나타내고자 하는 대체 가능한 자산에 대해 민팅, 전송, 소각 및 잔액 추적을 자동으로 도와줍니다.

함수 시그니처 및 구현 세부 사항에 대한 자세한 내용은 대체 가능한 자산에 대한 Move 참조를 찾을 수 있습니다.