В предыдущей статье мы рассмотрели, как создать учетную запись, производную от программы, с помощью Solana Web3. В этой статье мы рассмотрим, как использовать web3 для взаимодействия с программой onchain. В качестве примера мы возьмем, как создать токен SPL через программу токенов.

Если вы еще не являетесь участником Medium и хотите получить полный доступ к моим историям, воспользуйтесь этой ссылкой, чтобы подписаться на членство в Medium. Ваш членский взнос напрямую поддерживает меня и побуждает меня предоставлять больше полезных ресурсов в будущем. Здоровья!

Напомним, что для создания токена SPL необходимо выполнить несколько шагов, как показано ниже:

  1. Создайте учетную запись КПК с владельцем, установленным в качестве программы Token;
  2. ИнициализироватьMint

Для получения более подробной информации, пожалуйста, обратитесь к моему предыдущему отрывку о том, как модель учетной записи Solana обрабатывает токен SPL.

Для первого шага мы уже прошли в этом посте. Итак, этот отрывок будет посвящен второму шагу. На втором этапе просто вызовите функцию initializeMint из программы Token. Если вы хотите узнать больше о том, как модель учетной записи взаимодействует с программой токенов, пожалуйста, обратитесь к моему предыдущему отрывку здесь.

Установка других зависимостей

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

$ npm install @solana/buffer-layout
$ npm install @solana/buffer-layout-utils

Эти зависимости используются для взаимодействия со структурой данных инструкции. Например, тип данных открытого ключа определен в buffer-layout-utils. Беззнаковое целое число 8 и структура, используемые в Solana, определены в buffer-layout.

Инструкция по построению

Итак, как построить свою инструкцию для взаимодействия с функцией initializeMint программы Token? Во-первых, давайте проверим их GitHub. Если у вас есть время, я рекомендую вам пройтись по каждому биту программы. Но если вы не хотите проходить по частям, я покажу вам ключевую часть, необходимую для создания вашей первой инструкции в этом отрывке. Я разобью этот раздел на несколько частей:

  1. Создать структуру для инструкции

Формат инструкции для initializeMint можно найти здесь. Вы можете найти ниже на странице:

Итак, в принципе, вы можете просто добавить это в свою программу, как показано ниже:

const lo = require('@solana/buffer-layout');
const loutil = require('@solana/buffer-layout-utils');
let initializeMintInstructionData = lo.struct([
    lo.u8('instruction'),
    lo.u8('decimals'),
    loutil.publicKey('mintAuthority'),
    lo.u8('freezeAuthorityOption'),
    loutil.publicKey('freezeAuthority'),
  ])
};

2. Заполнение параметров

Итак, после построения структуры вам нужно заполнить значение этой пустой структуры. Теперь давайте рассмотрим, о чем все это:

  1. Инструкция: В программе Солана, чтобы вызвать функцию из программы, вы должны вызвать индекс этой функции. Для программы Token вы можете найти индекс каждой функции здесь. Итак, функция initializeMint равна 0;
  2. Decimals: сколько знаков после запятой имеет ваш токен SPL;
  3. MintAuthority: какая учетная запись имеет право выпускать токен;
  4. freezeAuthorityOption: Можно ли еще отчеканить токен?
  5. freezeAuthority: кто имеет право заморозить выпуск токена?

Теперь вам нужно выделить память для структуры и закодировать параметры в структуру, как показано ниже:

const data = Buffer.alloc(initializeMintInstructionData.span);
initializeMintInstructionData.encode(
   {
   instruction: 0,
   decimals: 8,
   mintAuthority: keypair.publicKey,
   freezeAuthorityOption: 0,
   freezeAuthority: keypair.publicKey,
   },
   data
);

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

3. Предоставление учетных записей для программы токенов

Если вы проверите в Solana Explorer любую инструкцию, вызывающую initializeMint, вы увидите что-то вроде этого:

Это означает, что программа принимает на вход 2 аккаунта. Это учетная запись PDA для хранения данных токена и учетной записи System Rent. Вы можете поместить их в список, как показано ниже:

const solanaWeb3 = require('@solana/web3.js');
const keys = [
{ pubkey: splaccount.publicKey, isSigner: false, isWritable: true },
{ pubkey: solanaWeb3.SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
];

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

4. Добавить их в инструкцию

Итак, после того, как все было подготовлено, теперь вы можете поместить эти данные в одну инструкцию. Вы можете использовать класс TransactionInstruction из библиотеки solana web3, как показано ниже:

const tokenProgramId=new solanaWeb3.PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
const instruction =  new solanaWeb3.TransactionInstruction({keys , programId: tokenProgramId, data});

5. Поместить все в функцию

Собираем все вместе. Вы можете создать функцию с именем initializeMint(), как показано ниже:

const solanaWeb3 = require('@solana/web3.js');
const tokenProgramId=new solanaWeb3.PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
const lo = require('@solana/buffer-layout');
const loutil = require('@solana/buffer-layout-utils');
function initializeMint(){
   let initializeMintInstructionData = lo.struct([
      lo.u8('instruction'),
      lo.u8('decimals'),
      loutil.publicKey('mintAuthority'),
      lo.u8('freezeAuthorityOption'),
      loutil.publicKey('freezeAuthority'),
   ]);
   let params = {
      instruction: 0,
      decimals: 8,
      mintAuthority: keypair.publicKey,
      freezeAuthorityOption: 0,
      freezeAuthority: keypair.publicKey,
   }
   const keys = 
   [
      { 
         pubkey: splaccount.publicKey, 
         isSigner: false, 
         isWritable: true 
      },
      { 
         pubkey: solanaWeb3.SYSVAR_RENT_PUBKEY, 
         isSigner: false, 
         isWritable: false 
      },
   ];
   const data = Buffer.alloc(initializeMintInstructionData.span);
   initializeMintInstructionData.encode(
      {
         instruction: 0,
         decimals: 8,
         mintAuthority: keypair.publicKey,
         freezeAuthorityOption: 0,
         freezeAuthority: keypair.publicKey,
      },
        data
    );
   const instruction =  new solanaWeb3.TransactionInstruction(
      {
         keys, 
         programId: tokenProgramId, 
         data
      }
   );
    
   return instruction;
}

Объединение этой функции с нашим кодом

Теперь, если вы посмотрите наш предыдущий пассаж, вы можете добавить эту функцию во весь код. Тем не менее, функция createPDAAccount нуждается в небольшой модификации:

const createPDAAccount = async () => {
    splaccount = solanaWeb3.Keypair.generate();
    let transaction = new solanaWeb3.Transaction({
      feePayer: keypair.publicKey
    });
   
    const instruction = solanaWeb3.SystemProgram.createAccount({
      fromPubkey: keypair.publicKey,
      newAccountPubkey: splaccount.publicKey,
      space: 82,
      lamports: 100000000,
      programId: tokenProgramId,
    });
    
    const instruction2 = initializeMint();
    transaction.add(instruction, instruction2);
    
    var signature = await    solanaWeb3.sendAndConfirmTransaction(
       connection, 
       transaction, 
       [keypair, splaccount]
    );
    
    console.log(signature);
 }

Здесь следует упомянуть несколько моментов.

  1. Размер создаваемой учетной записи КПК должен составлять 82 байта. Итак, как появились 82 байта? В исходном коде программы токенов здесь вы можете найти что-то вроде следующего:

Если вы подсчитаете MINT_SIZE, это будет 82 байта.

2. В Solana транзакция может содержать более одной инструкции. Итак, вам нужно использовать transaction.add для добавления разных инструкций вместе. Затем используйте solanaWeb3.sendAndConfirmTransaction, чтобы отправить его.

Если вы зайдете в проводник Solana, введете открытый ключ созданной учетной записи КПК в поле поиска, вы увидите что-то вроде этого:

Поздравляем! Вы успешно создали свой токен с помощью web3!

Заключение

Конечно, более простой способ создать SPL-токен — использовать SPL CLI или библиотеку spl-token. Но для того, чтобы понять, что такое инструкция, как все работает в Солане, рекомендуется запачкать руки и построить свою собственную инструкцию. В дальнейшем мы хотели бы больше поговорить о том, как обеспечить поставку токена и взаимодействовать с Metaplex для создания вашего NFT. Так что, пожалуйста, следите за обновлениями и до скорой встречи! Ваше здоровье!

Учебное пособие по Solana Web3 (1) — Установка и работа с учетной записью

Учебное пособие по Solana Web3 (2) — Подключите программу Web3 к кошельку

Учебное пособие по Solana Web3 (3) — Создание учетной записи, производной от программы (КПК)

Учебное пособие по Solana Web3 (4) — Взаимодействие с программой токенов