Ваша первая транзакция

В этом руководстве описывается, как генерировать и отправлять транзакции в блокчейн Aptos, а также проверять эти отправленные транзакции. Пример transfer-coin, используемый в этом руководстве, создан с помощью Aptos SDKs.

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

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

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

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

git clone https://github.com/aptos-labs/aptos-core.git

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

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

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

yarn install

Запустите пример transfer_coin:

yarn run transfer_coin

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

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

=== Addresses ===
Alice: 0x0baec07bfc42f8018ea304ddc307a359c1c6ab20fbce598065b6cb19acff7043
Bob: 0xc98ceafadaa32e50d06d181842406dbbf518b6586ab67cfa2b736aaddeb7c74f

=== Initial Balances ===
Alice: 20000
Bob: 0

=== Intermediate Balances ===
Alice: 18996
Bob: 1000

=== Final Balances ===
Alice: 17992
Bob: 2000

Приведенный выше вывод демонстрирует, что пример transfer-coin выполняет следующие шаги:

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

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

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

    • Создание учетной записи Bob из faucet.

  • Передача 1000 coins от Alice к Bob.

  • 4 coins газа, оплаченные Alice для осуществления этого перевода.

  • Еще один перевод 1000 coins от Alice к Bob.

  • Дополнительные 4 coins газа, заплаченные Alice за этот перевод.

Далее ниже приведено описание функций SDK, которые используются для выполнения описанных выше действий.

Шаг 4: SDK в деталях

Код примера transfer-coin использует вспомогательные функции для взаимодействия с REST API. В этом разделе рассматривается каждый из вызовов и дается представление о функциональности.

СМОТРИТЕ ПОЛНЫЙ КОД Полный код см. в Typescript transfer-coin, следуя приведенным ниже шагам.

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

На первом этапе пример transfer-coin инициализирует REST и faucet-клиенты.

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

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

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

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

const coinClient = new CoinClient(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, а также взаимодействие в других dApp. Учетная запись представляет собой носитель для хранения активов, поэтому она должна быть явно создана. В данном примере используется Faucet для создания и пополнения учетной записи Alice и только для создания учетной записи Bob:

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

Шаг 4.4: Чтение балансов

На этом этапе SDK преобразует один вызов в процесс запроса ресурса и чтения поля из этого ресурса.

console.log(`Alice: ${await coinClient.checkBalance(alice)}`);
console.log(`Bob: ${await coinClient.checkBalance(bob)}`); 

За кулисами функция checkBalance в CoinClient в SDK запрашивает ресурс CoinStore для AptosCoin и считывает текущее значение:

async checkBalance(
  account: AptosAccount,
  extraArgs?: {
    // The coin type to use, defaults to 0x1::aptos_coin::AptosCoin
    coinType?: string;
  },
): Promise<bigint> {
  const coinType = extraArgs?.coinType ?? APTOS_COIN;
  const typeTag = `0x1::coin::CoinStore<${coinType}>`;
  const resources = await this.aptosClient.getAccountResources(account.address());
  const accountResource = resources.find((r) => r.type === typeTag);
  return BigInt((accountResource!.data as any).coin.value);
} 

Шаг 4.5: Передача

Как и предыдущий шаг, это еще один вспомогательный шаг, который создает транзакцию, передающую coins от Alice к Bob. Для правильно созданных транзакций API возвращает хэш транзакции, который можно использовать в последующих шагах для проверки статуса транзакции. Блокчейн Aptos выполняет несколько проверок при отправке, и если какая-либо из них не проходит, пользователю выдается сообщение об ошибке. Эти проверки включают подпись транзакции, неиспользованный порядковый номер и отправку транзакции в соответствующую сеть.

let txnHash = await coinClient.transfer(alice, bob, 1_000, { gasUnitPrice: BigInt(100) }); 

За кулисами функция transfer генерирует рабочую нагрузку транзакции и поручает клиенту подписать, отправить и дождаться ее:

async transfer(
  from: AptosAccount,
  to: AptosAccount,
  amount: number | bigint,
  extraArgs?: OptionalTransactionArgs & {
    // The coin type to use, defaults to 0x1::aptos_coin::AptosCoin
    coinType?: string;
  },
): Promise<string> {
  const coinTypeToTransfer = extraArgs?.coinType ?? APTOS_COIN;
  const payload = this.transactionBuilder.buildTransactionPayload(
    "0x1::coin::transfer",
    [coinTypeToTransfer],
    [to.address(), amount],
  );
  return this.aptosClient.generateSignSubmitTransaction(from, payload, extraArgs);
} 

В клиенте это делает generateSignSubmitTransaction:

const rawTransaction = await this.generateRawTransaction(sender.address(), payload, extraArgs);
const bcsTxn = AptosClient.generateBCSTransaction(sender, rawTransaction);
const pendingTransaction = await this.submitSignedBCSTransaction(bcsTxn);
return pendingTransaction.hash;

Разбиваем вышесказанное на части:

  1. transfer внутренне является EntryFunction в модуле Coin Move, т.е. функцией входа в Move, которую можно вызвать напрямую.

  2. Функция Move хранится на модуле coin: 0x1::coin.

  3. Поскольку модуль Coin может использоваться другими coins, при передаче необходимо явно указать, какой тип coins передавать. Если coinType не указан, то по умолчанию используется 0x1::aptos_coin::AptosCoin.

Шаг 4.6: Ожидание разрешения транзакции

В Typescript достаточно просто вызвать coinClient.transfer, чтобы дождаться завершения транзакции. Функция вернет Transaction, возвращенную API, как только она будет обработана (успешно или неуспешно), или выдаст ошибку, если время обработки превысит таймаут.

Вы можете установить checkSuccess в true при вызове transfer, если хотите, чтобы он выбрасывал сообщение, если транзакция не была успешно зафиксирована:

await client.waitForTransaction(txnHash); 

Last updated