Акаунти

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

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

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

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

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

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

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

Приклад нижче демонструє, як використовувати Solana SDK для створення keypair. 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) - це адреса, яка детерміновано виводиться з використанням ID програми та одного чи кількох необов'язкових вхідних даних (seeds). Приклад нижче демонструє, як використовувати Solana SDK для створення 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 і містить наступну інформацію:

  • lamports: Кількість lamports на акаунті
  • data: Дані акаунта
  • owner: ID програми, якій належить акаунт
  • executable: Вказує, чи містить акаунт виконуваний бінарний код
  • rent_epoch: Застаріле поле epoch оренди
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.

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

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

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

Дані

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

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

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

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

Власник

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

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

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

Виконуваний

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

  • Якщо true: акаунт є program account
  • Якщо false: акаунт є data account

Епоха оренди

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

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

Lamports

Баланс акаунта в lamports.

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

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

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

Дані

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

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

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

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

Власник

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

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

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

Виконуваний

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

  • Якщо true: акаунт є program account
  • Якщо false: акаунт є data account

Епоха оренди

Поле 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,
}

Типи облікових записів

Існує дві основні категорії облікових записів:

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

Програмні облікові записи

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

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

Діаграма програмного облікового запису, його 4 компонентів та програми-завантажувача.Діаграма програмного облікового запису, його 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.

У наведеному нижче прикладі генерується нова пара ключів і фінансується 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.
Всі права захищені.
Залишайтеся на зв'язку
Акаунти | Solana