Акаунти

Усі дані в мережі Solana зберігаються в акаунтах. Мережу Solana можна уявити як публічну базу даних з єдиною таблицею Акаунтів. Зв'язок між акаунтом та його адресою подібний до пари ключ-значення, де ключем є адреса, а значенням — акаунт.

Кожен акаунт має однакову базову структуру і може бути знайдений за його адресою.

Діаграма 3 акаунтів та їхніх адрес. Включає визначення структури акаунта.Діаграма 3 акаунтів та їхніх адрес. Включає визначення структури акаунта.

Адреса акаунта

Адреса акаунта — це унікальний 32-байтовий ідентифікатор, який використовується для пошуку акаунта в блокчейні Solana. Адреси акаунтів часто відображаються як рядки, закодовані в base58. Більшість акаунтів використовують відкритий ключ Ed25519 як свою адресу, але це не обов'язково, оскільки Solana також підтримує програмно похідні адреси.

Акаунт з його адресою відкритого ключа, закодованою в base58Акаунт з його адресою відкритого ключа, закодованою в base58

Відкритий ключ

Приклад нижче демонструє, як використовувати SDK Solana для створення keypair.

import { generateKeyPairSigner } from "@solana/kit";
// Kit does not enable extractable private keys
const keypairSigner = await generateKeyPairSigner();
console.log(keypairSigner);
Console
Click to execute the code.

Program derived address

Program derived address (PDA) — це адреса, яка детерміновано виводиться з використанням ідентифікатора програми та одного чи кількох необов'язкових вхідних даних (seeds). Приклад нижче демонструє, як використовувати SDK Solana для створення program derived address.

import { Address, getProgramDerivedAddress } from "@solana/kit";
const programAddress = "11111111111111111111111111111111" as Address;
const seeds = ["helloWorld"];
const [pda, bump] = await getProgramDerivedAddress({
programAddress,
seeds
});
console.log(`PDA: ${pda}`);
console.log(`Bump: ${bump}`);
Console
Click to execute the code.

Структура акаунта

Кожен Account має максимальний розмір 10MiB і містить таку інформацію:

Account
pub struct Account {
/// lamports in the account
pub lamports: u64,
/// data held in this account
#[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
pub data: Vec<u8>,
/// the program that owns this account. If executable, the program that loads this account.
pub owner: Pubkey,
/// this account's data contains a loaded program (and is now read-only)
pub executable: bool,
/// the epoch at which this account will next owe rent
pub rent_epoch: Epoch,
}

Lamports

Баланс облікового запису в lamports.

Кожен обліковий запис повинен мати мінімальний баланс lamport, який називається rent, що дозволяє зберігати його дані в блокчейні. Rent пропорційний розміру облікового запису.

Хоча цей баланс називається rent, він працює більше як депозит, оскільки повний баланс можна повернути при закритті облікового запису. (Назва "rent" походить від тепер застарілого поля rent epoch.)

(Дивіться формулу мінімального балансу та відповідні константи.)

Дані

Це поле зазвичай називають "даними облікового запису". data у цьому полі вважаються довільними, оскільки можуть містити будь-яку послідовність байтів. Кожна програма визначає структуру даних, що зберігаються в цьому полі.

  • Program accounts: Це поле містить або виконуваний код програми, або адресу program data account, який зберігає виконуваний код програми.
  • Data accounts: Це поле зазвичай зберігає дані стану, призначені для читання.

Читання даних з облікового запису Solana включає два кроки:

  1. Отримання облікового запису за його адресою
  2. Десеріалізація поля data облікового запису з необроблених байтів у відповідну структуру даних, як визначено програмою, яка володіє обліковим записом.

Власник

Це поле містить ідентифікатор програми власника облікового запису.

Кожен обліковий запис Solana має програму, призначену як його власника. Власник облікового запису — це єдина програма, яка може змінювати data облікового запису або знімати lamports, як зазначено в інструкціях програми.

(У випадку program account, власником є його програма-завантажувач.)

Виконуваність

Це поле вказує, чи є акаунт program account або акаунтом даних

  • Якщо true: Акаунт є program account
  • Якщо false: Акаунт є акаунтом даних

Епоха оренди

Поле rent_epoch застаріле.

Раніше це поле відстежувало, коли акаунт повинен був сплачувати rent. Однак цей механізм збору rent з того часу застарів.

Lamports

Баланс облікового запису в lamports.

Кожен обліковий запис повинен мати мінімальний баланс lamport, який називається rent, що дозволяє зберігати його дані в блокчейні. Rent пропорційний розміру облікового запису.

Хоча цей баланс називається rent, він працює більше як депозит, оскільки повний баланс можна повернути при закритті облікового запису. (Назва "rent" походить від тепер застарілого поля rent epoch.)

(Дивіться формулу мінімального балансу та відповідні константи.)

Дані

Це поле зазвичай називають "даними облікового запису". data у цьому полі вважаються довільними, оскільки можуть містити будь-яку послідовність байтів. Кожна програма визначає структуру даних, що зберігаються в цьому полі.

  • Program accounts: Це поле містить або виконуваний код програми, або адресу program data account, який зберігає виконуваний код програми.
  • Data accounts: Це поле зазвичай зберігає дані стану, призначені для читання.

Читання даних з облікового запису Solana включає два кроки:

  1. Отримання облікового запису за його адресою
  2. Десеріалізація поля data облікового запису з необроблених байтів у відповідну структуру даних, як визначено програмою, яка володіє обліковим записом.

Власник

Це поле містить ідентифікатор програми власника облікового запису.

Кожен обліковий запис Solana має програму, призначену як його власника. Власник облікового запису — це єдина програма, яка може змінювати data облікового запису або знімати lamports, як зазначено в інструкціях програми.

(У випадку program account, власником є його програма-завантажувач.)

Виконуваність

Це поле вказує, чи є акаунт program account або акаунтом даних

  • Якщо true: Акаунт є program account
  • Якщо false: Акаунт є акаунтом даних

Епоха оренди

Поле rent_epoch застаріле.

Раніше це поле відстежувало, коли акаунт повинен був сплачувати rent. Однак цей механізм збору rent з того часу застарів.

Account Examples
// Example Token Mint Account
Account {
lamports: 1461600,
data.len: 82,
owner: TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb,
executable: false,
rent_epoch: 0,
data: 010000001e213c90625a7e643d9555bb01b6c3fe6416d7afd523ce8c7ddd9b923ceafb9d00000000000000000901010000001e213c90625a7e643d9555bb01b6,
}
// Example Token Program Account
Account {
lamports: 4513200894,
data.len: 134080,
owner: BPFLoader2111111111111111111111111111111111,
executable: true,
rent_epoch: 18446744073709551615,
data: 7f454c460201010000000000000000000300f70001000000d8f90000000000004000000000000000800902000000000000000000400038000400400009000800,
}

Типи акаунтів

Існує дві основні категорії акаунтів:

Це розділення означає, що виконуваний код програми та її стан зберігаються в окремих акаунтах. (Подібно до операційних систем, які зазвичай мають окремі файли для програм та їхніх даних.)

Program accounts

Кожна програма належить програмі-завантажувачу, яка використовується для розгортання та управління акаунтом. Коли нова програма розгортається, створюється акаунт для зберігання її виконуваного коду. Це називається program account. (Для простоти можна вважати program account самою програмою.)

На діаграмі нижче ви можете побачити, як програма-завантажувач використовується для розгортання program account. Поле data program account містить виконуваний код програми.

Діаграма program account, його 4 компонентів та програми-завантажувача.Діаграма program account, його 4 компонентів та програми-завантажувача.

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

Програми, розгорнуті за допомогою loader-v3, не містять програмного коду в своєму полі data. Натомість, їхнє поле data вказує на окремий акаунт даних програми, який містить програмний код. (Дивіться діаграму нижче.)

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

Під час розгортання або оновлення програми буферні акаунти використовуються для тимчасового розміщення завантаження.

Приклад нижче отримує акаунт Token Program. Зверніть увагу, що поле executable встановлено як true, що вказує на те, що акаунт є програмою.

import { Address, createSolanaRpc } from "@solana/kit";
const rpc = createSolanaRpc("https://api.mainnet-beta.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. Ініціалізувати дані акаунта, як визначено її інструкціями.

Діаграма акаунта даних, яким володіє акаунт програмиДіаграма акаунта даних, яким володіє акаунт програми

Приклад нижче створює та отримує акаунт Token Mint, яким володіє програма 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. Акаунти, якими володіє System Program, називаються системними акаунтами. Усі гаманці є системними акаунтами, що дозволяє їм оплачувати комісії за транзакції.

Гаманець, яким володіє System Program, що містить 1 000 000 лампортівГаманець, яким володіє System Program, що містить 1 000 000 лампортів

Коли SOL вперше надсилається на нову адресу, на цій адресі створюється акаунт, яким володіє System Program.

У прикладі нижче створюється новий 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 існують за попередньо визначеними адресами і надають доступ до даних про стан кластера. Вони динамічно оновлюються даними про мережевий кластер. Перегляньте повний список облікових записів Sysvar.

У прикладі нижче отримуються та десеріалізуються дані з облікового запису Sysvar Clock.

import { createSolanaRpc } from "@solana/kit";
import { fetchSysvarClock, SYSVAR_CLOCK_ADDRESS } from "@solana/sysvars";
const rpc = createSolanaRpc("https://api.mainnet-beta.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?

Керується

© 2025 Фонд Solana.
Всі права захищені.
Залишайтеся на зв'язку