У попередньому розділі ви дізналися, як читати дані з мережі Solana шляхом отримання акаунтів. Запис даних у мережу Solana потребує транзакції. Транзакція містить одну або кілька інструкцій, і кожна інструкція викликає програму.
Програми визначають бізнес-логіку для кожної інструкції. Коли ви надсилаєте транзакцію, середовище виконання Solana виконує інструкції транзакції по порядку. Транзакції є атомарними. Або кожна інструкція в транзакції виконується успішно, або вся транзакція завершується невдачею.
Приклади в цьому розділі показують, як:
- Переказати SOL між акаунтами
- Створити нове карбування токенів
Переказ SOL
Наведений нижче приклад переказує SOL з одного акаунта на інший. Лише програма, призначена власником акаунта, може змінювати дані акаунта або списувати lamport з його балансу. Акаунти гаманців належать System Program, тому переказ SOL між акаунтами гаманців вимагає інструкції, яка викликає інструкцію transfer System Program. Акаунт-відправник також повинен підписати транзакцію.
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";import { getTransferSolInstruction } from "@solana-program/system";const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));const receiver = await generateKeyPairSigner();const transferInstruction = getTransferSolInstruction({source: client.payer,destination: receiver.address,amount: lamports(10_000_000n)});const result = await client.sendTransaction([transferInstruction]);console.log("Transaction Signature:", result.context.signature);const { value: senderBalance } = await client.rpc.getBalance(client.payer.address).send();const { value: receiverBalance } = await client.rpc.getBalance(receiver.address).send();console.log("Sender Balance:", senderBalance);console.log("Receiver Balance:", receiverBalance);
Створіть клієнт Kit для локального тестового validator. Цей фрагмент додає підписанта-платника, підключається до локального RPC-ендпоінту, вмикає airdrop та поповнює платника тестовим SOL для переказу.
const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));
Згенеруйте підписанта для отримувача. Відправником є client.payer, якого було
створено за допомогою generatedPayer() та поповнено через airdropPayer().
const receiver = await generateKeyPairSigner();
Допоміжна функція getTransferSolInstruction() створює інструкцію System
Program. Інструкція переказує SOL від підписанта source на
адресу destination на вказану
amount кількість lamports.
const transferInstruction = getTransferSolInstruction({source: client.payer,destination: receiver.address,amount: lamports(10_000_000n)});
Викличте client.sendTransaction() з масивом інструкцій. Клієнт Kit перетворює
інструкції на одну транзакцію, підписує підписантами, прикріпленими до
інструкцій, надсилає транзакцію та очікує підтвердження.
const result = await client.sendTransaction([transferInstruction]);console.log("Transaction Signature:", result.context.signature);
Після підтвердження транзакції отримайте обидва баланси за допомогою
client.rpc.
const { value: senderBalance } = await client.rpc.getBalance(client.payer.address).send();const { value: receiverBalance } = await client.rpc.getBalance(receiver.address).send();
Створення токена
Наведений нижче приклад створює новий mint account за допомогою Token Extensions Program. mint account — це обліковий запис, який визначає глобальні параметри токена, такі як кількість десяткових знаків, обсяг емісії, повноваження на випуск та повноваження на заморожування.
Для створення mint account потрібні дві інструкції:
- Викликати System Program, щоб створити новий обліковий запис, яким володіє Token Extensions Program.
- Викликати Token Extensions Program, щоб ініціалізувати цей обліковий запис як mint.
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";import { getCreateAccountInstruction } from "@solana-program/system";import {fetchMint,getInitializeMintInstruction,getMintSize,TOKEN_2022_PROGRAM_ADDRESS} from "@solana-program/token-2022";const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));const mint = await generateKeyPairSigner();const space = BigInt(getMintSize());const rent = await client.rpc.getMinimumBalanceForRentExemption(space).send();const createAccountInstruction = getCreateAccountInstruction({payer: client.payer,newAccount: mint,space,lamports: rent,programAddress: TOKEN_2022_PROGRAM_ADDRESS});const initializeMintInstruction = getInitializeMintInstruction({mint: mint.address,decimals: 2,mintAuthority: client.payer.address,freezeAuthority: client.payer.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const result = await client.sendTransaction([createAccountInstruction,initializeMintInstruction]);console.log("Mint Address:", mint.address);console.log("Transaction Signature:", result.context.signature);const mintAccount = await fetchMint(client.rpc, mint.address);console.log("Mint Account:", mintAccount);
Створіть та поповніть клієнт Kit, а потім згенеруйте підписанта для використання як адреси нового mint account. Платник клієнта фінансує створення акаунту та сплачує комісію за транзакцію.
const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));const mint = await generateKeyPairSigner();
Обчисліть розмір mint account у байтах, а потім виконайте RPC-запит для розрахунку lamport, необхідних для зберігання цих даних в акаунті. Цей необхідний баланс називається rent.
const space = BigInt(getMintSize());const rent = await client.rpc.getMinimumBalanceForRentExemption(space).send();
Перша інструкція викликає System Program. Інструкція використовує
payer для фінансування newAccount,
виділяє mint account space, передає rent-exempt
lamports і призначає право власності Token Extensions
Program programAddress.
const createAccountInstruction = getCreateAccountInstruction({payer: client.payer,newAccount: mint,space,lamports: rent,programAddress: TOKEN_2022_PROGRAM_ADDRESS});
Друга інструкція викликає Token Extensions Program. Інструкція ініціалізує
адресу mint зі значенням
decimals, mintAuthority,
freezeAuthority і вказує Token Program
tokenProgram, якому належить mint account.
const initializeMintInstruction = getInitializeMintInstruction({mint: mint.address,decimals: 2,mintAuthority: client.payer.address,freezeAuthority: client.payer.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});
Надішліть обидві інструкції в одній транзакції. Інструкція створення акаунту має йти перед інструкцією ініціалізації mint account, оскільки mint account повинен існувати до того, як Token Extensions Program зможе записати дані mint до акаунту.
const result = await client.sendTransaction([createAccountInstruction,initializeMintInstruction]);
Після підтвердження транзакції отримайте mint account.
const mintAccount = await fetchMint(client.rpc, mint.address);console.log("Mint Account:", mintAccount);
Is this page helpful?