Ваше первое NFT

В этом руководстве описывается, как создавать и передавать NFT на блокчейне Aptos. Реализацию Aptos для основных NFT можно найти в модуле token.move Move.

Шаг 1: Выберите SDK

Установите предпочтительный SDK из приведенного ниже списка:

Шаг 2: Запустите пример

Каждый SDK содержит каталог examples. В этом руководстве рассматривается пример simple-nft.

Клонируйте репозиторий aptos-core:

git clone git@github.com:aptos-labs/aptos-core.git ~/aptos-core

Перейдите в каталог примеров Typescript SDK:

cd ~/aptos-core/ecosystem/typescript/sdk/examples/typescript

Установите необходимые зависимости:

yarn install

Запустите пример Typescript simple_nft:

yarn run simple_nft

Шаг 3: Понимание вывода

После выполнения примера simple-nft должен появиться следующий вывод, хотя некоторые значения будут отличаться:

=== Addresses ===
Alice: 0x9df0f527f3a0b445e4d5c320cfa269cdefafc7cd1ed17ffce4b3fd485b17aafb
Bob: 0xfcc74af84dde26b0050dce35d6b3d11c60f5c8c58728ca3a0b11035942a0b1de

=== Initial Coin Balances ===
Alice: 20000
Bob: 20000

=== Creating Collection and Token ===
Alice's collection: {
    "description": "Alice's simple collection",
    "maximum": "18446744073709551615",
    "mutability_config": {
        "description": false,
        "maximum": false,
        "uri": false
    },
    "name": "Alice's",
    "supply": "1",
    "uri": "https://aptos.dev"
}
Alice's token balance: 1
Alice's token data: {
    "default_properties": {
        "map": {
            "data": []
        }
    },
    "description": "Alice's simple token",
    "largest_property_version": "0",
    "maximum": "1",
    "mutability_config": {
        "description": false,
        "maximum": false,
        "properties": false,
        "royalty": false,
        "uri": false
    },
    "name": "Alice's first token",
    "royalty": {
        "payee_address": "0x9df0f527f3a0b445e4d5c320cfa269cdefafc7cd1ed17ffce4b3fd485b17aafb",
        "royalty_points_denominator": "1000000",
        "royalty_points_numerator": "0"
    },
    "supply": "1",
    "uri": "https://aptos.dev/img/nyan.jpeg"
}

=== Transferring the token to Bob ===
Alice's token balance: 0
Bob's token balance: 1

=== Transferring the token back to Alice using MultiAgent ===
Alice's token balance: 1
Bob's token balance: 0

Этот пример демонстрирует:

  • Инициализацию клиентов REST и faucet.

  • Создание двух учетных записей: Alice и Bob.

  • Финансирование и создание учетных записей Alice и Bob.

  • Создание коллекции и токена с использованием учетной записи Alice.

  • Alice предлагает токен, а Bob его принимает.

  • Bob в одностороннем порядке отправляет токен Alice через мультиагентную транзакцию.

Шаг 4: SDK в подробностях

СМОТРИТЕ ПОЛНЫЙ КОД Смотрите simple_nft для получения полного кода при выполнении следующих шагов.

Шаг 4.1: Инициализация клиентов

На первом шаге примера инициализируются клиенты API и faucet.

  • Клиент API взаимодействует с REST API, и

  • Клиент faucet взаимодействует с сервисом devnet Faucet для создания и пополнения учетных записей.

const client = new AptosClient(NODE_URL);
const faucetClient = new FaucetClient(NODE_URL, FAUCET_URL); 

Используя клиент API, мы можем создать TokenClient, который мы используем для обычных операций с токенами, таких как создание коллекций и токенов, их передача, утверждение и так далее.

const tokenClient = new TokenClient(client); 

common.ts инициализирует значения URL таким образом:

export const NODE_URL = process.env.APTOS_NODE_URL || "https://fullnode.devnet.aptoslabs.com";
export const FAUCET_URL = process.env.APTOS_FAUCET_URL || "https://faucet.devnet.aptoslabs.com";

ПОДСКАЗКА По умолчанию URL-адреса обеих служб указывают на службы Aptos devnet. Однако их можно настроить с помощью следующих переменных среды:

  • APTOS_NODE_URL

  • APTOS_FAUCET_URL

Шаг 4.2: Создание локальных учетных записей

Следующим шагом будет создание двух учетных записей на локальном уровне. Учетные записи представляют собой состояние в сети и вне сети. Состояние вне сети состоит из адреса и пары открытого и закрытого ключей, используемых для аутентификации владельца. Этот шаг демонстрирует, как генерировать состояние вне сети.

const alice = new AptosAccount();
const bob = new AptosAccount(); 

Шаг 4.3: Создание учетных записей в блокчейне

В Aptos каждая учетная запись должна иметь представление в сети, чтобы поддерживать получение токенов и coins, а также взаимодействие с другими dApps. Учетная запись представляет собой носитель для хранения активов, поэтому она должна быть явно создана. В данном примере для создания учетных записей Alice и Bob используется Faucet:

await faucetClient.fundAccount(alice.address(), 100_000_000);
await faucetClient.fundAccount(bob.address(), 100_000_000); 

Шаг 4.4: Создание коллекции

Теперь начинается процесс создания токенов. Сначала создатель должен создать коллекцию для хранения токенов. Коллекция может содержать ноль, один или много отдельных токенов. Коллекция не ограничивает атрибуты токенов, поскольку она является лишь хранилищем.

Ваше приложение будет вызывать createCollection:

const txnHash1 = await tokenClient.createCollection(
  alice,
  collectionName,
  "Alice's simple collection",
  "https://alice.com",
); 

Подпись функции createCollection. Она возвращает хэш транзакции:

async createCollection(
  account: AptosAccount,
  name: string,
  description: string,
  uri: string,
  maxAmount: AnyNumber = MAX_U64_BIG_INT,
  extraArgs?: OptionalTransactionArgs,
): Promise<string> {

Шаг 4.5: Создание токена

Чтобы создать токен, создатель должен указать связанную с ним коллекцию. Токен должен быть связан с коллекцией, и в этой коллекции должны быть оставшиеся токены, которые можно минтить. Существует множество атрибутов, связанных с токеном, но API-помощник раскрывает только минимальное количество, необходимое для создания статического контента.

Ваше приложение будет вызывать createToken:

const txnHash2 = await tokenClient.createToken(
  alice,
  collectionName,
  tokenName,
  "Alice's simple token",
  1,
  "https://aptos.dev/img/nyan.jpeg",
); 

Подпись функции createToken. Возвращает хэш транзакции:

async createToken(
  account: AptosAccount,
  collectionName: string,
  name: string,
  description: string,
  supply: number,
  uri: string,
  max: AnyNumber = MAX_U64_BIG_INT,
  royalty_payee_address: MaybeHexString = account.address(),
  royalty_points_denominator: number = 0,
  royalty_points_numerator: number = 0,
  property_keys: Array<string> = [],
  property_values: Array<string> = [],
  property_types: Array<string> = [],
  extraArgs?: OptionalTransactionArgs,
): Promise<string> {
  

Шаг 4.6: Чтение метаданных токена и коллекции

Метаданные коллекции и токена хранятся на учетной записи создателя в таблице Collections. SDK предоставляют удобные оболочки для запросов к этим конкретным таблицам:

Чтобы прочитать метаданные коллекции:

const collectionData = await tokenClient.getCollectionData(alice.address(), collectionName);
console.log(`Alice's collection: ${JSON.stringify(collectionData, null, 4)}`); 

Чтобы прочитать метаданные токена:

const tokenData = await tokenClient.getTokenData(alice.address(), collectionName, tokenName); console.log(Alice's token data: ${JSON.stringify(tokenData, null, 4)});

Вот как getTokenData запрашивает метаданные токена:

async getTokenData(
  creator: MaybeHexString,
  collectionName: string,
  tokenName: string,
): Promise<TokenTypes.TokenData> {
  const creatorHex = creator instanceof HexString ? creator.hex() : creator;
  const collection: { type: Gen.MoveStructTag; data: any } = await this.aptosClient.getAccountResource(
    creatorHex,
    "0x3::token::Collections",
  );
  const { handle } = collection.data.token_data;
  const tokenDataId = {
    creator: creatorHex,
    collection: collectionName,
    name: tokenName,
  };

  const getTokenTableItemRequest: Gen.TableItemRequest = {
    key_type: "0x3::token::TokenDataId",
    value_type: "0x3::token::TokenData",
    key: tokenDataId,
  };

  // We know the response will be a struct containing TokenData, hence the
  // implicit cast.
  return this.aptosClient.getTableItem(handle, getTokenTableItemRequest);
} 

Шаг 4.7: Чтение баланса токена

Каждый токен в Aptos является отдельным активом, активы, принадлежащие пользователю, хранятся в его TokenStore. Чтобы получить баланс:

const aliceBalance1 = await tokenClient.getToken(
  alice.address(),
  collectionName,
  tokenName,
  `${tokenPropertyVersion}`,
);
console.log(`Alice's token balance: ${aliceBalance1["amount"]}`); 

Шаг 4.8: Предложение и требование токена

Многие пользователи получили нежелательные токены, которые могут вызвать как минимальный дискомфорт, так и серьезные последствия. Aptos предоставляет каждому владельцу аккаунта право решать, принимать или не принимать односторонние переводы. По умолчанию односторонние переводы не поддерживаются. Таким образом, Aptos обеспечивает основу для предложения и требования токенов.

Чтобы предложить токен:

const txnHash3 = await tokenClient.offerToken(
  alice,
  bob.address(),
  alice.address(),
  collectionName,
  tokenName,
  1,
  tokenPropertyVersion,
); 

Чтобы получить токен:

const txnHash4 = await tokenClient.claimToken(
  bob,
  alice.address(),
  alice.address(),
  collectionName,
  tokenName,
  tokenPropertyVersion,
); 

Шаг 4.9: Безопасная односторонняя передача токена

Для поддержки безопасной односторонней передачи токена отправитель может сначала попросить получателя подтвердить вне сети о предстоящей передаче. Это происходит в форме запроса мультиагентной транзакции. Мультиагентные транзакции содержат несколько подписей, по одной для каждой учетной записи на сети. Move затем может использовать это для предоставления разрешений на уровне signer всем подписантам. Для передачи токенов это гарантирует, что принимающая сторона действительно желает получить этот токен, не требуя использования описанной выше структуры передачи токенов.

let txnHash5 = await tokenClient.directTransferToken(
  bob,
  alice,
  alice.address(),
  collectionName,
  tokenName,
  1,
  tokenPropertyVersion,
); 

Шаг 4.10: Включение односторонней передачи токенов

В скором времени.

В скором времени.

Last updated