첫 번째 NFT
이 튜토리얼은 Aptos TypeScript SDK (@aptos-labs/ts-sdk
)를 사용하여 Aptos에서 새로운 디지털 자산(흔히 NFT라고 불림)을 생성하는 과정을 안내합니다. 이 튜토리얼을 마치면 다음을 수행하는 방법을 알게 됩니다:
- 디지털 자산(NFT) 컬렉션 생성
- 해당 컬렉션 내에서 새로운 디지털 자산(NFT) 민팅
- 계정 간 디지털 자산(NFT) 전송
- 업데이트된 잔액을 확인하여 디지털 자산(NFT)의 이동 검증
코드 살펴보기
섹션 제목: “코드 살펴보기”아래는 온체인에서 디지털 자산을 생성, 전송 및 상호 작용하는 방법에 대한 단계별 설명입니다. 예제 코드(끝에 전체 코드가 표시됨)가 어떻게 작동하는지 살펴보겠습니다. 코드 실행으로 바로 이동하려면 예제 실행을 참조하세요.
코드 연습
섹션 제목: “코드 연습”-
클라이언트 설정
SDK에서
Aptos
클라이언트를 가져와서 지정된 네트워크에 연결하도록 구성합니다:const APTOS_NETWORK = NetworkToNetworkName[process.env.APTOS_NETWORK] || Network.DEVNET;const config = new AptosConfig({ network: APTOS_NETWORK });const aptos = new Aptos(config);이
aptos
객체를 통해 Aptos 블록체인과 상호 작용할 수 있습니다(계정 펀딩, 자산 생성, 거래 제출 등). -
계정 생성 및 펀딩
Alice와 Bob이라는 두 계정을 생성합니다. 개발넷에서는 테스트 APT로 쉽게 펀딩할 수 있습니다.
const alice = Account.generate();const bob = Account.generate();await aptos.fundAccount({ accountAddress: alice.accountAddress, amount: INITIAL_BALANCE });await aptos.fundAccount({ accountAddress: bob.accountAddress, amount: INITIAL_BALANCE }); -
컬렉션 생성
Alice의 계정에 컬렉션을 생성합니다. 컬렉션은 디지털 자산의 “폴더”나 “카테고리” 역할을 합니다. 이 경우
"Example Collection"
을 생성합니다.const createCollectionTransaction = await aptos.createCollectionTransaction({creator: alice,description: "This is an example collection.",name: "Example Collection",uri: "aptos.dev",});const committedTxn = await aptos.signAndSubmitTransaction({signer: alice,transaction: createCollectionTransaction,});await aptos.waitForTransaction({ transactionHash: committedTxn.hash }); -
디지털 자산 민팅
컬렉션이 생성되면 이제 컬렉션에 대한 디지털 자산(NFT)을 민팅할 수 있습니다. 이름, 설명, URI(종종 이미지와 같은 메타데이터에 링크)와 같은 세부 정보를 제공해야 합니다.
const mintTokenTransaction = await aptos.mintDigitalAssetTransaction({creator: alice,collection: "Example Collection",description: "This is an example digital asset.",name: "Example Asset",uri: "https://aptos.dev/asset.png",});const mintTxn = await aptos.signAndSubmitTransaction({signer: alice,transaction: mintTokenTransaction,});await aptos.waitForTransaction({ transactionHash: mintTxn.hash }); -
디지털 자산 전송
민팅되면 자산은 Alice에게 속합니다. Alice의 디지털 자산을 가져와서 이를 확인할 수 있습니다. 그런 다음 이 자산을 Bob에게 전송하는 거래를 구축하고 제출합니다.
const aliceDigitalAssets = await aptos.getOwnedDigitalAssets({ ownerAddress: alice.accountAddress });const digitalAssetAddress = aliceDigitalAssets[0].token_data_id;const transferTransaction = await aptos.transferDigitalAssetTransaction({sender: alice,digitalAssetAddress,recipient: bob.accountAddress,});const transferTxn = await aptos.signAndSubmitTransaction({signer: alice,transaction: transferTransaction,});await aptos.waitForTransaction({ transactionHash: transferTxn.hash });완료 후 자산이 이제 Bob의 계정에 나타나야 합니다.
-
잔액 확인
마지막으로 Alice와 Bob의 계정을 모두 확인하여 Alice가 더 이상 자산을 갖고 있지 않고 Bob이 이제 자산을 갖고 있는지 확인합니다.
const aliceDigitalAssetsAfter = await aptos.getOwnedDigitalAssets({ ownerAddress: alice.accountAddress });const bobDigitalAssetsAfter = await aptos.getOwnedDigitalAssets({ ownerAddress: bob.accountAddress });console.log(`Alice's digital asset balance: ${aliceDigitalAssetsAfter.length}`);console.log(`Bob's digital asset balance: ${bobDigitalAssetsAfter.length}`);
예제 실행
섹션 제목: “예제 실행”시작하기
섹션 제목: “시작하기”-
프로젝트 설정
프로젝트를 위한 새 디렉토리를 생성하고 Node.js 프로젝트를 초기화합니다:
Terminal window mkdir aptos-digital-asset-tutorialcd aptos-digital-asset-tutorialnpm init -y이렇게 하면
package.json
파일이 생성되어 의존성을 설치하고 스크립트를 실행할 수 있습니다. -
의존성 설치
Aptos TypeScript SDK와 환경 변수를 관리하기 위한
dotenv
가 필요합니다:Terminal window npm install @aptos-labs/ts-sdk dotenvnpm install --save-dev @types/node -
tsconfig.json 생성
다음 내용으로
tsconfig.json
파일을 생성합니다:{"compilerOptions": {"target": "es2020","module": "commonjs","esModuleInterop": true,"forceConsistentCasingInFileNames": true,"strict": true,"skipLibCheck": true,"types": ["node"],"lib": ["es2020"]}}이 구성은 TypeScript가 Node.js 타입을 올바르게 인식하고 적절한 타입 검사를 제공하도록 합니다.
-
환경 변수 구성
다음 내용으로
.env
파일을 생성합니다:Terminal window APTOS_NETWORK=devnet -
index.ts 추가
다음 내용으로
index.ts
파일을 생성합니다:// 아래 TODO를 업데이트하여 이 디지털 자산을 필요에 맞게 사용자 정의하세요.// 컬렉션 값과 개별 디지털 자산 값을 사용자 정의하고 싶을 것입니다.// 이 예제는 컬렉션 생성, 디지털 자산으로 채우기, 전송하는 방법을 보여줍니다.import "dotenv/config";import {Account,Aptos,AptosConfig,Network,NetworkToNetworkName,} from "@aptos-labs/ts-sdk";// 환경 변수가 로드되었는지 확인console.log("Environment variables loaded:", {APTOS_NETWORK: process.env.APTOS_NETWORK || "not set"});const INITIAL_BALANCE = 100_000_000;console.log("Step 1: Setting up a client to connect to Aptos");const APTOS_NETWORK = NetworkToNetworkName[process.env.APTOS_NETWORK!] || Network.DEVNET;const config = new AptosConfig({ network: APTOS_NETWORK });const aptos = new Aptos(config);async function example() {console.log("\n=== Step 2: Creating and funding accounts ===\n");const alice = Account.generate();const bob = Account.generate();console.log(`Alice's address: ${alice.accountAddress}`);console.log(`Bob's address: ${bob.accountAddress}`);console.log("Funding Alice's account...");await aptos.fundAccount({ accountAddress: alice.accountAddress, amount: INITIAL_BALANCE });console.log("Alice's account funded!");console.log("Funding Bob's account...");await aptos.fundAccount({ accountAddress: bob.accountAddress, amount: INITIAL_BALANCE });console.log("Bob's account funded!");console.log("\n=== Step 3: Creating a collection ===\n");// TODO: 디지털 자산을 사용자 정의하려면 이러한 값을 업데이트하세요!const collectionName = "Example Collection";const collectionDescription = "This is an example collection.";const collectionURI = "aptos.dev";console.log("Building the collection creation transaction...");const createCollectionTransaction = await aptos.createCollectionTransaction({creator: alice,description: collectionDescription,name: collectionName,uri: collectionURI,});console.log("Submitting the collection creation transaction...");const committedTxn = await aptos.signAndSubmitTransaction({signer: alice,transaction: createCollectionTransaction,});console.log("Waiting for the collection creation transaction to complete...");await aptos.waitForTransaction({ transactionHash: committedTxn.hash });console.log("Collection created successfully!");console.log("\n=== Step 4: Minting a digital asset ===\n");// TODO: 민팅하는 디지털 자산의 값을 업데이트하세요!const tokenName = "Example Asset";const tokenDescription = "This is an example digital asset.";const tokenURI = "aptos.dev/asset";console.log("Building the mint transaction...");const mintTokenTransaction = await aptos.mintDigitalAssetTransaction({creator: alice,collection: collectionName,description: tokenDescription,name: tokenName,uri: tokenURI,});console.log(mintTokenTransaction)console.log("Submitting the mint transaction...");const mintTxn = await aptos.signAndSubmitTransaction({signer: alice,transaction: mintTokenTransaction,});console.log(mintTxn)console.log("Waiting for the mint transaction to complete...");await aptos.waitForTransaction({ transactionHash: mintTxn.hash });console.log("Digital asset minted successfully!");console.log("\n=== Step 5: Transferring the digital asset ===\n");// 인덱서가 온체인의 최신 데이터로 업데이트될 때까지 기다림await new Promise((resolve) => setTimeout(resolve, 5000));const aliceDigitalAssets = await aptos.getOwnedDigitalAssets({ownerAddress: alice.accountAddress,});// 액세스하기 전에 Alice가 디지털 자산을 가지고 있는지 확인if (aliceDigitalAssets.length === 0) {console.error("No digital assets found for Alice. Make sure the minting was successful.");return;}const digitalAssetAddress = aliceDigitalAssets[0].token_data_id;console.log("Building the transfer transaction...");const transferTransaction = await aptos.transferDigitalAssetTransaction({sender: alice,digitalAssetAddress,recipient: bob.accountAddress,});console.log("Submitting the transfer transaction...");const transferTxn = await aptos.signAndSubmitTransaction({signer: alice,transaction: transferTransaction,});console.log("Waiting for the transfer transaction to complete...");await aptos.waitForTransaction({ transactionHash: transferTxn.hash });console.log("Digital asset transferred successfully!");console.log("\n=== Step 6: Verifying digital asset balances ===\n");const aliceDigitalAssetsAfter = await aptos.getOwnedDigitalAssets({ownerAddress: alice.accountAddress,});const bobDigitalAssetsAfter = await aptos.getOwnedDigitalAssets({ownerAddress: bob.accountAddress,});console.log(`Alice's digital asset balance: ${aliceDigitalAssetsAfter.length}`);console.log(`Bob's digital asset balance: ${bobDigitalAssetsAfter.length}`);console.log("\n=== Step 7: Transaction hashes for explorer ===\n");console.log(`Collection creation transaction: ${committedTxn.hash}`);console.log(`Mint transaction: ${mintTxn.hash}`);console.log(`Transfer transaction: ${transferTxn.hash}`);console.log("\nYou can view these transactions on the Aptos Explorer:");console.log("https://explorer.aptoslabs.com/?network=devnet");}example(); -
코드 실행
Terminal window npx ts-node index.ts모든 것이 올바르게 설정되었다면 각 단계, 거래 해시 및 최종 잔액을 자세히 설명하는 출력 로그를 볼 수 있습니다.
-
탐색기에서 거래 보기
코드를 실행한 후 콘솔 출력에서 거래 해시를 볼 수 있습니다. 특히 쉬운 참조를 위해 모든 거래 해시를 표시하는 Step 7에서:
Terminal window === Step 7: Transaction hashes for explorer ===Collection creation transaction: 0x8c5d2a4ce32d76349bfb4f3830740c1c103399e8cbc31d6e2c7a871c88e6ad48Mint transaction: 0x673d2cbb9fef468fe41f271c0fcf20872e9fa79afb6a2000368394000071b02eTransfer transaction: 0x3a1e99d6fd3f8e7e962c311f3dfd92c11e468da5b6084123b8f7e0248a37ffa7You can view these transactions on the Aptos Explorer:https://explorer.aptoslabs.com/?network=devnetAptos 탐색기에서 이러한 거래를 볼 수 있습니다:
- 콘솔에서 거래 해시를 복사합니다
- Aptos 탐색기를 방문합니다
- 올바른 네트워크(Devnet)에 있는지 확인합니다
- 검색창에 거래 해시를 붙여넣습니다
- 다음을 포함하여 거래의 세부 정보를 확인합니다:
- 발신자 및 수신자 주소
- 거래가 처리된 정확한 시간
- 지불된 가스 수수료
- 전송된 디지털 자산
이는 거래를 확인하고 블록체인에 어떻게 기록되는지 이해하는 좋은 방법입니다.