メインコンテンツまでスキップ

NFT入門

このチュートリアルでは、Aptos ブロックチェーン上で代替不可能な資産を作成および転送する方法について解説します。代替不可能なデジタル資産に対する Aptos のノーコード実装は、aptos_token.moveMoveモジュールにあります。

ステップ 1 : SDK を選ぶ

以下のリストからお好みの SDK をインストールします。


ステップ 2 : サンプルを実行する

aptos-ts-sdkリポジトリのクローンを作成します。

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

Typescript ESM examplesディレクトリに移動します。

cd examples/typescript-esm

依存関係をインストールします。

pnpm install

Typescriptのsimple_digital_assetサンプルを実行します。

pnpm run simple_digital_asset

ステップ 3 : 出力を理解する

simple_digital_assetサンプルの実行後に次の出力が表示されますが、一部の値は異なります。

=== Addresses ===

Alice's address is: 0x770dbeb6101056eac5a19de9a73ad72fac512e0de909e7bcb13a9d9241d1d162

=== Create the collection ===

Alice's collection: {
"collection_id": "0x23ece6c35415f5c5a720dc4de2820cabece0a6f1768095db479f657ad2c05753",
"collection_name": "Example Collection",
"creator_address": "0x770dbeb6101056eac5a19de9a73ad72fac512e0de909e7bcb13a9d9241d1d162",
"current_supply": 0,
"description": "Example description.",
"last_transaction_timestamp": "2023-11-29T21:26:03.204874",
"last_transaction_version": 8001101,
"max_supply": 18446744073709552000,
"mutable_description": true,
"mutable_uri": true,
"table_handle_v1": null,
"token_standard": "v2",
"total_minted_v2": 0,
"uri": "aptos.dev"
}

=== Alice Mints the digital asset ===

Alice's digital assets balance: 1
Alice's digital asset: {
"token_standard": "v2",
"token_properties_mutated_v1": null,
"token_data_id": "0x9f4460e29a66b4e41cef1671767dc8a5e8c52a2291e36f84b8596e0d1205fd8c",
"table_type_v1": null,
"storage_id": "0x9f4460e29a66b4e41cef1671767dc8a5e8c52a2291e36f84b8596e0d1205fd8c",
"property_version_v1": 0,
"owner_address": "0x770dbeb6101056eac5a19de9a73ad72fac512e0de909e7bcb13a9d9241d1d162",
"last_transaction_version": 8001117,
"last_transaction_timestamp": "2023-11-29T21:26:04.521624",
"is_soulbound_v2": false,
"is_fungible_v2": false,
"amount": 1,
"current_token_data": {
"collection_id": "0x23ece6c35415f5c5a720dc4de2820cabece0a6f1768095db479f657ad2c05753",
"description": "Example asset description.",
"is_fungible_v2": false,
"largest_property_version_v1": null,
"last_transaction_timestamp": "2023-11-29T21:26:04.521624",
"last_transaction_version": 8001117,
"maximum": null,
"supply": 0,
"token_data_id": "0x9f4460e29a66b4e41cef1671767dc8a5e8c52a2291e36f84b8596e0d1205fd8c",
"token_name": "Example Asset",
"token_properties": {},
"token_standard": "v2",
"token_uri": "aptos.dev/asset",
"current_collection": {
"collection_id": "0x23ece6c35415f5c5a720dc4de2820cabece0a6f1768095db479f657ad2c05753",
"collection_name": "Example Collection",
"creator_address": "0x770dbeb6101056eac5a19de9a73ad72fac512e0de909e7bcb13a9d9241d1d162",
"current_supply": 1,
"description": "Example description.",
"last_transaction_timestamp": "2023-11-29T21:26:04.521624",
"last_transaction_version": 8001117,
"max_supply": 18446744073709552000,
"mutable_description": true,
"mutable_uri": true,
"table_handle_v1": null,
"token_standard": "v2",
"total_minted_v2": 1,
"uri": "aptos.dev"
}
}
}

=== Transfer the digital asset to Bob ===

Alice's digital assets balance: 0
Bob's digital assets balance: 1

このサンプルでは、次のことを実演します。

Details
  • Aptos クライアントを初期化。
  • アリスとボブの 2 つのアカウントを作成。
  • 資金投入し、アリスとボブのアカウントを作成。
  • アリスのアカウントを使用してコレクションとトークンを作成。
  • アリスがボブへトークンを送金します。

ステップ 4 : SDK 詳細

コード全体を見る

完全なコードはsimple_digital_assetで確認出来ます。参照の上、以下の手順に従ってコードを完成させてください。


ステップ 4.1 : クライアントを初期化する

最初のステップではこのsimple_digital_assetサンプルでAptos クライアントを初期化します。

const APTOS_NETWORK: Network =
NetworkToNetworkName[process.env.APTOS_NETWORK] || Network.DEVNET;
const config = new AptosConfig({ network: APTOS_NETWORK });
const aptos = new Aptos(config);
ヒント

デフォルトでは、Aptos クライアントは Aptos devnet サービスを指します。ただしnetwork入力引数を使用して構成できます。


ステップ 4.2 : ローカルアカウントを作る

このステップでは、ローカルで 2 つのアカウントを作成します。Accountsはパブリック アドレスと、アカウントの所有権を認証するために使用される公開鍵/秘密鍵ペアで構成されます。このステップでは、アカウントを生成し、そのキーペアとアドレスを変数に保存する方法を実演します。

const alice = Account.generate();
const bob = Account.generate();
備考

注)これはローカルの鍵ペアのみを生成します。キーペアとパブリック アドレスを生成した後も、オンチェーンにアカウントは存在しません。


ステップ 4.3 : ブロックチェーンアカウントを作る

オンチェーンでアカウントをインスタンス化するには、何らかの方法で分かりやすく作成する必要があります。devnet ネットワーク上では、 Faucet API を使用して無料のテスト用のコインをリクエストできます。この例では、フォーセットを利用して資金を調達し、誤ってアリスとボブのアカウントを作成します。

await aptos.fundAccount({
accountAddress: alice.accountAddress,
amount: 100_000_000,
});
await aptos.faucet.fundAccount({
accountAddress: bob.accountAddress,
amount: 100_000_000,
});

ステップ 4.4 : コレクションを作る

ここから、代替不可能なデジタル資産を作成するプロセスが始まります。まず、アセットをグループ化するコレクションを作成する必要があります。コレクションには、0、1、または多数の別個の代替可能アセットまたは代替不可能なアセットを含めることができます。コレクションは単なるコンテナであり、作成者がアセットをグループ化することのみを目的としています。

アプリケーションはcreateCollectionTransactionを呼び出して、チェーンへsignAndSubmitTransactionします。

const createCollectionTransaction = await aptos.createCollectionTransaction({
creator: alice,
description: collectionDescription,
name: collectionName,
uri: collectionURI,
});

const committedTxn = await aptos.signAndSubmitTransaction({
signer: alice,
transaction: createCollectionTransaction,
});

これはcreateCollectionTransactionの関数シグネチャです。シミュレートまたはチェーンに送信できる SingleSignerTransactionを返します。

export async function createCollectionTransaction(
args: {
creator: Account;
description: string;
name: string;
uri: string;
options?: InputGenerateTransactionOptions;
} & CreateCollectionOptions,
): Promise<SingleSignerTransaction>;

ステップ 4.5 : トークンを作る

トークンを作成するには、作成者は関連するコレクションを指定する必要があります。トークンはコレクションに関連付けられている必要があり、そのコレクションにはミントできるトークンが含まれている必要があります。トークンには多くの属性が関連付けられていますが、ヘルパー API が静的コンテンツを作成する場合、必要最小限の属性のみを公開します。 amount required to create static content.

アプリケーションはmintTokenTransactionを呼び出します:

const mintTokenTransaction = await aptos.mintTokenTransaction({
creator: alice,
collection: collectionName,
description: tokenDescription,
name: tokenName,
uri: tokenURI,
});

const committedTxn = await aptos.signAndSubmitTransaction({
signer: alice,
transaction: mintTokenTransaction,
});

これはmintTokenTransactionの関数シグネチャです。シミュレートもしくは、チェーンへ提出ができるSingleSignerTransactionを返します。

async mintTokenTransaction(args: {
creator: Account;
collection: string;
description: string;
name: string;
uri: string;
options?: InputGenerateTransactionOptions;
}): Promise<SingleSignerTransaction>

ステップ 4.6: トークンとコレクションのメタデータを読み取る

コレクション資産とトークン資産は両方とも、一意のアドレスを持つオンチェーンのObjectsです。それらのメタデータはオブジェクト アドレスに保存されます。SDK は、このデータのクエリに関する便利なラッパーを提供します。

コレクションのメタデータを読み取るには:

const alicesCollection = await aptos.getCollectionData({
creatorAddress: alice.accountAddress,
collectionName,
minimumLedgerVersion: BigInt(pendingTxn.version),
});
console.log(`Alice's collection: ${JSON.stringify(alicesCollection, null, 4)}`);

所有しているトークンのメタデータを読み取るには:

const alicesDigitalAsset = await aptos.getOwnedTokens({
ownerAddress: alice.accountAddress,
minimumLedgerVersion: BigInt(pendingTxn.version),
});

console.log(
`Alice's digital asset: ${JSON.stringify(alicesDigitalAsset[0], null, 4)}`,
);

ステップ 4.7 : オブジェクトのオーナーを読み取る

aptos_token.moveコントラクトから作成された各オブジェクトは個別の資産です。ユーザーが所有する資産は、ユーザーのアカウントとは別に保管されます。ユーザーがオブジェクトを所有しているかどうかを確認するには、オブジェクトの所有者を確認します。

const alicesDigitalAsset = await aptos.getOwnedTokens({
ownerAddress: alice.accountAddress,
minimumLedgerVersion: BigInt(pendingTxn.version),
});

console.log(
`Alice's digital asset: ${JSON.stringify(alicesDigitalAsset[0], null, 4)}`,
);
クエリを作成してデータを取得する。
export async function getOwnedTokens(args: {
aptosConfig: AptosConfig;
ownerAddress: AccountAddressInput;
options?: PaginationArgs & OrderByArg<GetTokenActivityResponse[0]>;
}): Promise<GetOwnedTokensResponse> {
const { aptosConfig, ownerAddress, options } = args;

const whereCondition: CurrentTokenOwnershipsV2BoolExp = {
owner_address: { _eq: AccountAddress.from(ownerAddress).toStringLong() },
amount: { _gt: 0 },
};

const graphqlQuery = {
query: GetCurrentTokenOwnership,
variables: {
where_condition: whereCondition,
offset: options?.offset,
limit: options?.limit,
order_by: options?.orderBy,
},
};

const data = await queryIndexer<GetCurrentTokenOwnershipQuery>({
aptosConfig,
query: graphqlQuery,
originMethod: "getOwnedTokens",
});

return data.current_token_ownerships_v2;
}

ステップ 4.8 : オブジェクトを送信、返信する

aptos_token.moveコントラクトから作成された各オブジェクトは個別の資産です。ユーザーが所有する資産は、ユーザーのアカウントとは別に保管されます。ユーザーがオブジェクトを所有しているかどうかを確認するには、オブジェクトの所有者を確認します。

const alicesDigitalAsset = await aptos.getOwnedTokens({
ownerAddress: alice.accountAddress,
minimumLedgerVersion: BigInt(pendingTxn.version),
});

console.log(
`Alice's digital asset: ${JSON.stringify(alicesDigitalAsset[0], null, 4)}`,
);
アリスからボブへトークンを送金します
const transferTransaction = await aptos.transferDigitalAsset({
sender: alice,
digitalAssetAddress: alicesDigitalAsset[0].token_data_id,
recipient: bob.accountAddress,
});
const committedTxn = await aptos.signAndSubmitTransaction({
signer: alice,
transaction: transferTransaction,
});
const pendingTxn = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});
各ユーザーのクエリされたトークン量を出力します
const alicesDigitalAssetsAfter = await aptos.getOwnedTokens({
ownerAddress: alice.accountAddress,
minimumLedgerVersion: BigInt(pendingTxn.version),
});
console.log(
`Alices's digital assets balance: ${alicesDigitalAssetsAfter.length}`,
);

const bobDigitalAssetsAfter = await aptos.getOwnedTokens({
ownerAddress: bob.accountAddress,
minimumLedgerVersion: BigInt(pendingTxn.version),
});
console.log(`Bob's digital assets balance: ${bobDigitalAssetsAfter.length}`);

サポート資料