Типы аккаунтов

Кратко

Аккаунты программ содержат исполняемый sBPF-код. Аккаунты данных хранят состояние и принадлежат программам. Системные аккаунты принадлежат System Program. Sysvars предоставляют состояние кластера, доступное по предопределённым адресам.

Поле executable определяет категорию аккаунта:

Такое разделение кода и изменяемого состояния позволяет развернуть программу один раз и управлять любым количеством аккаунтов данных.

Аккаунты программ

Аккаунт программы хранит исполняемый код. Каждый аккаунт программы принадлежит загрузчику программ. Когда программа развёртывается, среда выполнения создаёт аккаунт программы для хранения её байткода.

Диаграмма аккаунта программы, его 4 компонентов и загрузчика.Диаграмма аккаунта программы, его 4 компонентов и загрузчика.

Аккаунты данных программ

Программы, развёрнутые с помощью loader-v3 (см. Загрузчики программ), не хранят исполняемый байткод в собственном поле data. Вместо этого их data указывает на отдельный аккаунт данных программы, который содержит код программы. (См. диаграмму ниже.)

Аккаунт программы с данными. Данные указывают на отдельный аккаунт данных программыАккаунт программы с данными. Данные указывают на отдельный аккаунт данных программы

Во время развёртывания или обновления программы используются буферные аккаунты для временной загрузки данных.

В следующем примере происходит получение аккаунта Token Program. Поле executable имеет значение true, что подтверждает: это аккаунт программы.

import { Address, createSolanaRpc } from "@solana/kit";
const rpc = createSolanaRpc("https://api.mainnet.solana.com");
const programId = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address;
const accountInfo = await rpc
.getAccountInfo(programId, { encoding: "base64" })
.send();
console.log(accountInfo);
Console
Click to execute the code.

Аккаунты данных

Аккаунты данных не содержат исполняемого кода. Они хранят состояние, определяемое программой.

Аккаунт состояния программы

Программы хранят своё состояние в аккаунтах данных. Создание аккаунта состояния программы включает два шага:

  1. Вызвать System Program, чтобы создать аккаунт. System Program передаёт право собственности указанной программе.
  2. Владеющая программа инициализирует поле аккаунта data согласно своим инструкциям.

Диаграмма аккаунта данных, принадлежащего program accountДиаграмма аккаунта данных, принадлежащего program account

В следующем примере создаётся и запрашивается mint account токена, принадлежащий программе Token 2022.

import {
airdropFactory,
appendTransactionMessageInstructions,
createSolanaRpc,
createSolanaRpcSubscriptions,
createTransactionMessage,
generateKeyPairSigner,
getSignatureFromTransaction,
lamports,
pipe,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
signTransactionMessageWithSigners
} from "@solana/kit";
import { getCreateAccountInstruction } from "@solana-program/system";
import {
getInitializeMintInstruction,
getMintSize,
TOKEN_2022_PROGRAM_ADDRESS,
fetchMint
} from "@solana-program/token-2022";
// Create Connection, local validator in this example
const rpc = createSolanaRpc("http://localhost:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");
// Generate keypairs for fee payer
const feePayer = await generateKeyPairSigner();
// Fund fee payer
await airdropFactory({ rpc, rpcSubscriptions })({
recipientAddress: feePayer.address,
lamports: lamports(1_000_000_000n),
commitment: "confirmed"
});
// Generate keypair to use as address of mint
const mint = await generateKeyPairSigner();
// Get default mint account size (in bytes), no extensions enabled
const space = BigInt(getMintSize());
// Get minimum balance for rent exemption
const rent = await rpc.getMinimumBalanceForRentExemption(space).send();
// Instruction to create new account for mint (token 2022 program)
// Invokes the system program
const createAccountInstruction = getCreateAccountInstruction({
payer: feePayer,
newAccount: mint,
lamports: rent,
space,
programAddress: TOKEN_2022_PROGRAM_ADDRESS
});
// Instruction to initialize mint account data
// Invokes the token 2022 program
const initializeMintInstruction = getInitializeMintInstruction({
mint: mint.address,
decimals: 9,
mintAuthority: feePayer.address
});
const instructions = [createAccountInstruction, initializeMintInstruction];
// Get latest blockhash to include in transaction
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
// Create transaction message
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }), // Create transaction message
(tx) => setTransactionMessageFeePayerSigner(feePayer, tx), // Set fee payer
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), // Set transaction blockhash
(tx) => appendTransactionMessageInstructions(instructions, tx) // Append instructions
);
// Sign transaction message with required signers (fee payer and mint keypair)
const signedTransaction =
await signTransactionMessageWithSigners(transactionMessage);
// Send and confirm transaction
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(
signedTransaction,
{ commitment: "confirmed" }
);
// Get transaction signature
const transactionSignature = getSignatureFromTransaction(signedTransaction);
console.log("Mint Address:", mint.address);
console.log("Transaction Signature:", transactionSignature);
const accountInfo = await rpc.getAccountInfo(mint.address).send();
console.log(accountInfo);
const mintAccount = await fetchMint(rpc, mint.address);
console.log(mintAccount);
Console
Click to execute the code.

Системные аккаунты

Аккаунты, которые после создания остаются во владении System Program, называются системными аккаунтами. Отправка SOL на новый адрес впервые создаёт новый аккаунт по этому адресу, принадлежащий System Program.

Все кошельки являются системными аккаунтами. Плательщик комиссии в транзакции должен быть системным аккаунтом, так как только аккаунты, принадлежащие System Program, могут оплачивать комиссии за транзакции.

Кошелёк, принадлежащий System Program, содержащий 1 000 000 лампортовКошелёк, принадлежащий System Program, содержащий 1 000 000 лампортов

В следующем примере создаётся новая keypair, пополняется SOL и запрашивается аккаунт. Поле owner равно 11111111111111111111111111111111 (System Program).

import {
airdropFactory,
createSolanaRpc,
createSolanaRpcSubscriptions,
generateKeyPairSigner,
lamports
} from "@solana/kit";
// Create a connection to Solana cluster
const rpc = createSolanaRpc("http://localhost:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");
// Generate a new keypair
const keypair = await generateKeyPairSigner();
console.log(`Public Key: ${keypair.address}`);
// Funding an address with SOL automatically creates an account
const signature = await airdropFactory({ rpc, rpcSubscriptions })({
recipientAddress: keypair.address,
lamports: lamports(1_000_000_000n),
commitment: "confirmed"
});
const accountInfo = await rpc.getAccountInfo(keypair.address).send();
console.log(accountInfo);
Console
Click to execute the code.

Системные аккаунты (Sysvar)

Системные аккаунты (Sysvar) — это специальные аккаунты по предопределённым адресам, которые предоставляют только для чтения доступ к данным состояния кластера. Они обновляются динамически каждый slot.

SysvarАдресНазначение
ClockSysvarC1ock11111111111111111111111111111111Текущий slot, epoch и Unix-временная метка
EpochScheduleSysvarEpochSchedu1e111111111111111111111111Константы расписания epoch, заданные в genesis
EpochRewardsSysvarEpochRewards1111111111111111111111111Статус и прогресс распределения наград за epoch
RentSysvarRent111111111111111111111111111111111Ставка rent и порог освобождения
SlotHashesSysvarS1otHashes111111111111111111111111111Последние хэши родительских банков slot
StakeHistorySysvarStakeHistory1111111111111111111111111Активация и деактивация стейка по epoch
LastRestartSlotSysvarLastRestartS1ot1111111111111111111111Последний slot перезапуска кластера
InstructionsSysvar1nstructions1111111111111111111111111Сериализованные инструкции текущей транзакции
SlotHistorySysvarS1otHistory11111111111111111111111111Запись о том, какие slot были произведены за последний epoch

В следующем примере выполняется получение и десериализация системного аккаунта Clock.

import { createSolanaRpc } from "@solana/kit";
import { fetchSysvarClock, SYSVAR_CLOCK_ADDRESS } from "@solana/sysvars";
const rpc = createSolanaRpc("https://api.mainnet.solana.com");
const accountInfo = await rpc
.getAccountInfo(SYSVAR_CLOCK_ADDRESS, { encoding: "base64" })
.send();
console.log(accountInfo);
// Automatically fetch and deserialize the account data
const clock = await fetchSysvarClock(rpc);
console.log(clock);
Console
Click to execute the code.

Is this page helpful?

Содержание

Редактировать страницу

Управляется

© 2026 Solana Foundation.
Все права защищены.
Связаться с нами