Транзакции с использованием Typescript SDK

egormajj

EgorMajj

Posted on September 8, 2022

Транзакции с использованием Typescript SDK

В этом руководстве показаны шаги по созданию, подписанию и отправке транзакции в формате BCS с использованием Aptos Typescript SDK.

Отправка транзакций в BCS в сравнении с JSON
BCS: Отправка транзакций в формате BCS более безопасна, чем отправка в формате JSON. В этом методе вы создадите BCS-сериализованное сообщение для подписи на стороне клиента. Подробное руководство по отправке в формате BCS см. в руководстве "Создание подписанной транзакции". Typescript SDK поддерживает подписание и отправку транзакций в формате BCS.

JSON: Если вы отправляете транзакции в формате JSON, вы будете использовать REST API и полагаться на сервер Aptos для создания подписывающего сообщения. Такой подход создает риск того, что пользователь подпишет непреднамеренную транзакцию, подделанную вредоносным сервером API. О том, как отправлять транзакции в формате JSON, читайте в руководстве "Ваша первая транзакция". Кроме того, Typescript SDK предоставляет оболочки, позволяющие значительно сократить объем ручной работы, необходимой для подготовки и отправки транзакций в формате JSON.

ПОДСКАЗКА
Мы настоятельно рекомендуем вам использовать формат BCS для отправки транзакций в блокчейн Aptos.

Прежде чем приступить к работе

Прежде чем продолжить, установите последнюю версию Aptos TS SDK. Перейдите в корень каталога вашего проекта и запустите:

npm install aptos или yarn add aptos

ПРИМЕЧАНИЕ
Смотрите исходный код этого руководства. Хотя в этом руководстве используется Typescript, Aptos TS SDK также работает в проектах Javascript.

Шаг 1: Создание учетных записей
Предположим, что пользователь Alice хочет отправить 717 пробных coins пользователю Bob. Сначала нам нужно создать две учетные записи пользователей.

import { AptosClient, AptosAccount, FaucetClient, BCS, TxnBuilderTypes } from "aptos";

// devnet is used here for testing
const NODE_URL = "https://fullnode.devnet.aptoslabs.com";
const FAUCET_URL = "https://faucet.devnet.aptoslabs.com";

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

// Generates key pair for Alice
const alice = new AptosAccount();
// Creates Alice's account and mint 5000 test coins
await faucetClient.fundAccount(alice.address(), 5000);

let resources = await client.getAccountResources(alice.address());
let accountResource = resources.find((r) => r.type === "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>");
console.log(`Alice coins: ${(accountResource?.data as any).coin.value}. Should be 5000!`);

// Generates key pair for Bob
const bob = new AptosAccount();
// Creates Bob's account and mint 0 test coins
await faucetClient.fundAccount(bob.address(), 0);

resources = await client.getAccountResources(bob.address());
accountResource = resources.find((r) => r.type === "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>");
console.log(`Bob coins: ${(accountResource?.data as any).coin.value}. Should be 0!`);
Enter fullscreen mode Exit fullscreen mode

С помощью приведенного выше кода мы создали две учетные записи на Aptos devnet и заминтили 5000 тестовых coins для учетной записи Alice и 0 тестовых coins для учетной записи Bob.

Шаг 2. Подготовьте полезную среду транзакции

Typescript SDK поддерживает три типа полезной среды транзакций:

  1. ScriptFunction
  2. Script и
  3. ModuleBundle.

Подробности см. на сайте https://aptos-labs.github.io/ts-sdk-doc/classes/TxnBuilderTypes.TransactionPayload.html.

Полезная среда ScriptFunction используется для вызова функции скрипта Move на цепочке. В полезной среде ScriptFunction вы можете указать имя функции и аргументы.

Полезная среда Script содержит байткод для выполнения Aptos MoveVM (Move Virtual Machine). В полезной среде Script можно указать код сценария в байтах и аргументы сценария.

Полезная нагрузка ModuleBundle используется для публикации нескольких модулей одновременно. В полезной нагрузке ModuleBundle вы можете предоставить байткод модуля.

Для перевода coins с учетной записи Alice на учетную запись Bob нам необходимо подготовить полезную среду ScriptFunction с функцией transfer.

// We need to pass a token type to the `transfer` function.
const token = new TxnBuilderTypes.TypeTagStruct(TxnBuilderTypes.StructTag.fromString("0x1::aptos_coin::AptosCoin"));

const entryFunctionPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction(
  TxnBuilderTypes.EntryFunction.natural(
    // Fully qualified module name, `AccountAddress::ModuleName`
    "0x1::coin",
    // Module function
    "transfer",
    // The coin type to transfer
    [token],
    // Arguments for function `transfer`: receiver account address and amount to transfer
    [BCS.bcsToBytes(TxnBuilderTypes.AccountAddress.fromHex(bob.address())), BCS.bcsSerializeUint64(717)],
  ),
);
Enter fullscreen mode Exit fullscreen mode

Функция Move transfer требует тип coin в качестве аргумента type. Функция transfer определена здесь https://github.com/aptos-labs/aptos-core/blob/faf4f94260d4716c8a774b3c17f579d203cc4013/aptos-move/framework/aptos-framework/sources/Coin.move#L311.

В приведенном выше фрагменте кода мы хотим передать AptosCoin, который определен под учетной записью 0x1 и модулем AptosCoin. Поэтому полное имя AptosCoin будет 0x1::aptos_coin::AptosCoin.

ПРИМЕЧАНИЕ
Все аргументы в полезной среде ScriptFunction должны быть сериализованы BCS. В приведенном выше коде мы сериализовали адрес учетной записи Bob'а и номер суммы для перевода.

Шаг 3. Подпишите и отправьте транзакцию

После сборки полезной нагрузки транзакции мы готовы создать экземпляр RawTransaction, который обертывает только что созданную полезную нагрузку. Затем RawTransaction можно подписать и отправить.

// Create a raw transaction out of the transaction payload
const rawTxn = await client.generateRawTransaction(alice.address(), entryFunctionPayload);

// Sign the raw transaction with Alice's private key
const bcsTxn = AptosClient.generateBCSTransaction(alice, rawTxn);
// Submit the transaction
const transactionRes = await client.submitSignedBCSTransaction(bcsTxn);

// Wait for the transaction to finish
await client.waitForTransaction(transactionRes.hash);

resources = await client.getAccountResources(bob.address());
accountResource = resources.find((r) => r.type === "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>");
console.log(`Bob coins: ${(accountResource?.data as any).coin.value}. Should be 717!`);
Enter fullscreen mode Exit fullscreen mode

Результат

Результат после выполнения:

Alice coins: 5000. Should be 5000!
Bob coins: 0. Should be 0!
Bob coins: 717. Should be 717!
Enter fullscreen mode Exit fullscreen mode

Создание необработанных транзакций с помощью конструктора транзакций ABI

Чтобы уменьшить бремя сериализации аргументов полезной нагрузки вручную, Typescript SDK также предоставляет конструктор транзакций на основе ABI (Application Binary Interface). ABI включает информацию о сигнатурах функций Move. С помощью ABI, Typescript SDK может сериализовать собственные значения JS/TS. Файлы ABI создаются при компиляции пакетов Move с помощью Aptos CLI. Для создания необработанных транзакций с помощью ABI transaction builder сначала необходимо преобразовать ABI-файлы в шестнадцатеричные строки. На linux/Mac это можно сделать с помощью следующей команды:

cat aptos-core/aptos-move/framework/aptos-token/build/AptosToken/abis/token_transfers/offer_script.abi | od -v -t x1 -A n | tr -d ' \n'
Enter fullscreen mode Exit fullscreen mode

А затем вы можете создавать необработанные транзакции:

import { TransactionBuilderABI, HexString } from "aptos";

// You can pass in multiple ABIs
const transactionBuilder = new TransactionBuilderABI([
  new HexString("ABI_HEX_STRING_1").toUint8Array(),
  new HexString("ABI_HEX_STRING_2").toUint8Array(),
]);

const rawTransaction = transactionBuilder.build(
  "0x3::token_transfers::offer_script",
  [],
  [receiver, creator, collectionName, name, property_version, amount],
);
Enter fullscreen mode Exit fullscreen mode

После создания необработанных транзакций вы можете выполнить описанный выше Шаг 3, чтобы подписать и отправить транзакцию.

💖 💪 🙅 🚩
egormajj
EgorMajj

Posted on September 8, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

What was your win this week?
weeklyretro What was your win this week?

November 29, 2024

Where GitOps Meets ClickOps
devops Where GitOps Meets ClickOps

November 29, 2024

How to Use KitOps with MLflow
beginners How to Use KitOps with MLflow

November 29, 2024

Modern C++ for LeetCode 🧑‍💻🚀
leetcode Modern C++ for LeetCode 🧑‍💻🚀

November 29, 2024