Typescript
Token2022 з Web3.js

Token2022 з Web3.js

Розширення Memo Transfer

Розширення MemoTranfer є розширенням облікового запису Token, яке забезпечує, щоб усі вхідні перекази на токен-рахунок включали пам'ятку (memo), сприяючи покращеному відстеженню транзакцій та ідентифікації користувачів.

Initializing the Token Account

Щоб ініціалізувати розширення MemoTransfer на обліковому записі Token, нам знадобиться функція enableRequiredMemoTransfers().

Ось як створити токен з розширенням Memo Transfer:

ts
import {
    Keypair,
    SystemProgram,
    Transaction,
    sendAndConfirmTransaction,
} from '@solana/web3.js';
import {
    createInitializeAccountInstruction,
    createEnableRequiredMemoTransfersInstruction,
    getAccountLen,
    ExtensionType,
    TOKEN_2022_PROGRAM_ID,
} from '@solana/spl-token';
 
const tokenAccount = Keypair.generate();
 
// Calculate the size needed for a Token account with Memo Transfer extension
const accountLen = getAccountLen([ExtensionType.MemoTransfer]);
 
// Calculate minimum lamports required for rent exemption
const lamports = await connection.getMinimumBalanceForRentExemption(accountLen);
 
// Create the account with the correct size and owner
const createAccountInstruction = SystemProgram.createAccount({
    fromPubkey: keypair.publicKey,
    newAccountPubkey: tokenAccount.publicKey,
    space: accountLen,
    lamports,
    programId: TOKEN_2022_PROGRAM_ID,
});
 
// Initialize the Memo Transfer extension
const enableMemoTransferInstruction = createEnableRequiredMemoTransfersInstruction(
    destinationTokenAccount.publicKey,
    destinationKeypair.publicKey,
    undefined,
    TOKEN_2022_PROGRAM_ID,
);
 
// Initialize the Token account itself
const initializeAccountInstruction = createInitializeAccountInstruction(
    tokenAccount.publicKey,
    mint.publicKey,
    keypair.publicKey,
    TOKEN_2022_PROGRAM_ID,
);
 
const transaction = new Transaction().add(
    createAccountInstruction,
    initializeAccountInstruction,
    enableMemoTransferInstruction,
);
 
const signature = await sendAndConfirmTransaction(connection, transaction, [keypair, tokenAccount], {skipPreflight: false});
 
console.log(`Token accounts created! Check out your TX here: https://explorer.solana.com/tx/${signature}?cluster=devnet`);

Transferring Token with a Memo

Для використання програми Memo на Solana у нас є два можливі шляхи.

Створення власної "сирої" інструкції memo таким чином:

ts
const message = "Hello, Solana";
 
new TransactionInstruction({
    keys: [{ pubkey: keypair.publicKey, isSigner: true, isWritable: true }],
    data: Buffer.from(message, "utf-8"), // Memo message. In this case it is "Hello, Solana"
    programId: new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"), // Memo program that validates keys and memo message
}),

Або ми можемо використовувати SDK програми Memo після завантаження пакета таким чином:

 
npm i @solana/spl-memo

У нашому прикладі ми використаємо другий варіант, і це виглядатиме так:

ts
const memoInstruction = createMemoInstruction(
    "Hello, world!",
    [keypair.publicKey],
);
 
const transferInstruction = createTransferCheckedInstruction(
    tokenAccount,
    mint.publicKey,
    destinationTokenAccount.publicKey,
    keypair.publicKey,
    BigInt(100e6),
    6,
    undefined,
    TOKEN_2022_PROGRAM_ID,
);
 
const transferTransaction = new Transaction().add(
    memoInstruction,
    transferInstruction,
);
 
const transferSignature = await sendAndConfirmTransaction(connection, transferTransaction, [keypair]);
 
console.log(`Tokens transferred with memo! Check out your TX here: https://explorer.solana.com/tx/${transferSignature}?cluster=devnet`);

Disabling and Enabling the Memo

Якщо ми не хочемо вимагати, щоб переказ супроводжувався пам'яткою, ми можемо зробити це за допомогою функції disableRequiredMemoTransfer, і це виглядатиме так:

ts
const disableRequiredMemoTransfersInstruction = createDisableRequiredMemoTransfersInstruction(
    destinationTokenAccount,
    destinationKeypair.publicKey,
    undefined,
    TOKEN_2022_PROGRAM_ID,
);
 
const transferInstruction = createTransferCheckedInstruction(
    tokenAccount,
    mint.publicKey,
    destinationTokenAccount,
    keypair.publicKey,
    BigInt(100e6),
    6,
    undefined,
    TOKEN_2022_PROGRAM_ID,
);
 
const transaction = new Transaction().add(
    disableRequiredMemoTransfersInstruction,
    transferInstruction,
);
 
const signature = await sendAndConfirmTransaction(connection, transaction, [keypair, destinationKeypair]);
 
console.log(`Tokens transferred and account state changed! Check out your TX here: https://explorer.solana.com/tx/${signature}?cluster=devnet`);

А якщо ми хочемо знову увімкнути цю функцію, ми можемо просто використати функцію enableRequiredMemoTransfers() таким чином:

ts
const enableRequiredMemoTransfersInstruction = createEnableRequiredMemoTransfersInstruction(
    destinationTokenAccount,
    destinationKeypair.publicKey,
    undefined,
    TOKEN_2022_PROGRAM_ID,
);
 
const transferInstruction = createTransferCheckedInstruction(
    tokenAccount,
    mint.publicKey,
    destinationTokenAccount,
    keypair.publicKey,
    BigInt(100e6),
    6,
    undefined,
    TOKEN_2022_PROGRAM_ID,
);
 
const transaction = new Transaction().add(
    enableRequiredMemoTransfersInstruction,
    transferInstruction,
);
 
const signature = await sendAndConfirmTransaction(connection, transaction, [keypair, destinationKeypair]);
 
console.log(`Tokens transferred and account state changed! Check out your TX here: https://explorer.solana.com/tx/${signature}?cluster=devnet`);
Blueshift © 2025Commit: 6d01265