第一个 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 两个账户。在 devnet 上,可轻松为它们注入测试 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文件:// Update the TODOs below to customize this digital asset to your needs.// You will want to customize the Collection values and individual Digital Asset values.// This example demonstrates creating a collection, populating it with digital assets, and transferring them.import "dotenv/config";import {Account,Aptos,AptosConfig,Network,NetworkToNetworkName,} from "@aptos-labs/ts-sdk";// Verify environment variables are loadedconsole.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: Update these values to customize your Digital Asset!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: Update the values of the Digital Assets you are minting!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");// Wait for the indexer to update with the latest data from on-chainawait new Promise((resolve) => setTimeout(resolve, 5000));const aliceDigitalAssets = await aptos.getOwnedDigitalAssets({ownerAddress: alice.accountAddress,});// Check if Alice has any digital assets before accessing themif (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若一切设置正确,将看到详细说明每个步骤、交易哈希和最终余额的输出日志。
-
在 Explorer 中查看交易
运行代码后,控制台中会显示交易哈希,尤其是第 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=devnet可在 Aptos Explorer 中查看这些交易:
- 从控制台复制交易哈希
- 访问 Aptos Explorer
- 确保处于正确网络(Devnet)
- 将交易哈希粘贴到搜索栏
- 查看交易详细信息,包括:
- 发送者和接收者地址
- 交易处理的准确时间
- 支付的 Gas 费用
- 被转移的数字资产
这是验证交易并了解其如何记录在区块链上的好方法。