콘텐츠로 이동

첫 번째 코인

이 튜토리얼은 MoonCoin이라는 이름의 자체 코인(여기에 정의된 대로)을 컴파일, 배포 및 민팅하는 방법을 소개합니다.

아래 목록에서 선호하는 SDK를 설치하세요:


Aptos CLI용 사전 컴파일된 바이너리를 설치하세요.


aptos-ts-sdk 저장소를 복제하고 빌드하세요:

Terminal window
git clone https://github.com/aptos-labs/aptos-ts-sdk.git
cd aptos-ts-sdk
pnpm install
pnpm build

TypeScript 예제 디렉토리로 이동하세요:

Terminal window
cd examples/typescript/

필요한 의존성을 설치하세요:

Terminal window
pnpm install

TypeScript your_coin 예제를 실행하세요:

Terminal window
pnpm run your_coin

애플리케이션이 완료되면서 다음과 같이 출력됩니다:

Terminal window
Bob's initial MoonCoin balance: 0.
Alice mints herself 100 MoonCoin.
Alice transfers 100 MoonCoin to Bob.
Bob's updated MoonCoin balance: 100.

4.1단계: MoonCoin 패키지 빌드 및 게시

섹션 제목: “4.1단계: MoonCoin 패키지 빌드 및 게시”

Move 컨트랙트는 패키지로 알려진 Move 모듈 집합입니다. 새 패키지를 배포하거나 업그레이드할 때 패키지를 게시하려면 컴파일러를 --save-metadata와 함께 호출해야 합니다. MoonCoin의 경우 다음 출력 파일이 중요합니다:

  • build/Examples/package-metadata.bcs: 패키지와 관련된 메타데이터를 포함합니다.
  • build/Examples/bytecode_modules/moon_coin.mv: moon_coin.move 모듈의 바이트코드를 포함합니다.

이것들은 예제에서 읽혀서 Aptos 블록체인에 게시됩니다:

TypeScript 예제에서는 aptos move build-publish-payload 명령을 사용하여 모듈을 컴파일하고 빌드합니다. 이 명령은 package-metadata.bcsmoon_coin.mv 모듈의 바이트코드를 포함하는 build 폴더를 빌드합니다. 이 명령은 또한 게시 거래 페이로드를 빌드하고 JSON 출력 파일에 저장하여 나중에 읽어서 metadataBytesbyteCode를 가져와 체인에 컨트랙트를 게시할 수 있습니다.

패키지 컴파일:

export function compilePackage(
packageDir: string,
outputFile: string,
namedAddresses: Array<{ name: string; address: AccountAddress }>,
) {
const addressArg = namedAddresses
.map(({ name, address }) => `${name}=${address}`)
.join(" ");
// Assume-yes는 이전 컴파일된 버전을 자동으로 덮어씁니다. 이전 버전을 덮어쓰려는 것이 확실한 경우에만 수행하세요.
const compileCommand = `aptos move build-publish-payload --json-output-file ${outputFile} --package-dir ${packageDir} --named-addresses ${addressArg} --assume-yes`;
execSync(compileCommand);
}
compilePackage("move/moonCoin", "move/moonCoin/moonCoin.json", [
{ name: "MoonCoin", address: alice.accountAddress },
]);

체인에 패키지 게시:

export function getPackageBytesToPublish(filePath: string) {
// 현재 작업 디렉토리 - 이 저장소의 루트 폴더
const cwd = process.cwd();
// 대상 디렉토리 - 현재 작업 디렉토리 + filePath (filePath JSON 파일은 이전 compilePackage CLI 명령으로 생성됨)
const modulePath = path.join(cwd, filePath);
const jsonData = JSON.parse(fs.readFileSync(modulePath, "utf8"));
const metadataBytes = jsonData.args[0].value;
const byteCode = jsonData.args[1].value;
return { metadataBytes, byteCode };
}
const { metadataBytes, byteCode } = getPackageBytesToPublish(
"move/moonCoin/moonCoin.json",
);
// 체인에 MoonCoin 패키지 게시
const transaction = await aptos.publishPackageTransaction({
account: alice.accountAddress,
metadataBytes,
moduleBytecode: byteCode,
});
const pendingTransaction = await aptos.signAndSubmitTransaction({
signer: alice,
transaction,
});
await aptos.waitForTransaction({ transactionHash: pendingTransaction.hash });

MoonCoin 모듈은 MoonCoin 구조체, 즉 고유한 코인 타입을 정의합니다. 또한 init_module이라는 함수를 포함합니다. init_module 함수는 모듈이 게시될 때 호출됩니다. 이 경우 MoonCoin은 계정 소유자가 유지 관리하는 ManagedCoin으로 MoonCoin 코인 타입을 초기화합니다.

module MoonCoin::moon_coin {
struct MoonCoin {}
fun init_module(sender: &signer) {
aptos_framework::managed_coin::initialize<MoonCoin>(
sender,
b"Moon Coin",
b"MOON",
6,
false,
);
}
}

코인에는 여러 기본 요소가 있습니다:

  • 민팅: 새로운 코인 생성
  • 소각: 코인 삭제
  • 동결: 계정이 CoinStore에 코인을 저장하는 것을 방지
  • 등록: 코인을 저장하기 위해 계정에 CoinStore 리소스 생성
  • 전송: CoinStore에서 코인을 인출하고 입금

코인 타입이 Aptos 블록체인에 게시되면, 해당 코인 타입을 게시한 엔티티가 이를 초기화할 수 있습니다:

module 0x1::coin {
public fun initialize<CoinType>(
account: &signer,
name: string::String,
symbol: string::String,
decimals: u8,
monitor_supply: bool,
): (BurnCapability<CoinType>, FreezeCapability<CoinType>, MintCapability<CoinType>) {
let account_addr = signer::address_of(account);
assert!(
coin_address<CoinType>() == account_addr,
error::invalid_argument(ECOIN_INFO_ADDRESS_MISMATCH),
);
assert!(
!exists<CoinInfo<CoinType>>(account_addr),
error::already_exists(ECOIN_INFO_ALREADY_PUBLISHED),
);
let coin_info = CoinInfo<CoinType> {
name,
symbol,
decimals,
supply: if (monitor_supply) { option::some(optional_aggregator::new(MAX_U128, false)) } else { option::none() },
};
move_to(account, coin_info);
(BurnCapability<CoinType>{ }, FreezeCapability<CoinType>{ }, MintCapability<CoinType>{ })
}
}

이는 이 코인 타입이 이전에 초기화된 적이 없음을 보장합니다. 10번째와 15번째 줄의 검사를 주목하세요. 이는 initialize를 호출하는 사람이 실제로 이 모듈을 게시한 사람과 동일하고, 그들의 계정에 CoinInfo가 저장되지 않았음을 확인합니다. 두 조건이 모두 확인되면 CoinInfo가 저장되고 호출자는 소각, 동결 및 민팅 기능을 얻습니다.


코인을 사용하려면 엔티티가 자신의 계정에 해당 코인에 대한 CoinStore를 등록해야 합니다:

public entry fun registerCoinType(account: &signer) {

MoonCoin은 엔트리 함수 래퍼를 제공하는 ManagedCoin을 사용합니다: managed_coin::register. 등록을 위한 예제 스크립트는 다음과 같습니다:

script {
fun register(account: &signer) {
aptos_framework::managed_coin::register<MoonCoin::moon_coin::MoonCoin>(account)
}
}

코인 민팅에는 초기화 중에 생성된 민트 기능이 필요합니다. 아래 mint 함수는 해당 기능과 양을 받아서 해당 양의 코인을 포함하는 Coin<T> 구조체를 반환합니다. 코인이 공급량을 추적하는 경우 업데이트됩니다.

module 0x1::coin {
public fun mint<CoinType>(
amount: u64,
_cap: &MintCapability<CoinType>,
): Coin<CoinType> acquires CoinInfo {
if (amount == 0) {
return zero<CoinType>()
};
let maybe_supply = &mut borrow_global_mut<CoinInfo<CoinType>>(coin_address<CoinType>()).supply;
if (option::is_some(maybe_supply)) {
let supply = option::borrow_mut(maybe_supply);
optional_aggregator::add(supply, (amount as u128));
};
Coin<CoinType> { value: amount }
}
}

ManagedCoin은 엔트리 함수 managed_coin::mint를 제공하여 이를 더 쉽게 만듭니다.


Aptos는 코인 전송을 지원하는 여러 구성 요소를 제공합니다:

  • coin::deposit<CoinType>: 모든 엔티티가 이미 coin::register<CoinType>을 호출한 계정에 코인을 입금할 수 있게 합니다.
  • coin::withdraw<CoinType>: 모든 엔티티가 자신의 계정에서 코인 양을 추출할 수 있게 합니다.
  • aptos_account::transfer_coins<CoinType>: 특정 CoinType의 코인을 수신자에게 전송합니다.