Підсумок
Програмні облікові записи містять виконуваний sBPF-код. Облікові записи даних зберігають стан, що належить програмам. Системні облікові записи належать System Program. Sysvars надають стан кластера, доступний за попередньо визначеними адресами.
Поле executable визначає категорію
облікового запису:
- Програмні облікові записи:
executable=true. Містить виконуваний код. - Облікові записи даних:
executable=false. Зберігає стан або дані користувача.
Це розділення коду від змінюваного стану означає, що програма розгортається один раз і може керувати будь-якою кількістю облікових записів даних.
Програмні облікові записи
Програмний обліковий запис зберігає виконуваний код. Кожен програмний обліковий запис належить програмі-завантажувачу. Коли програма розгортається, середовище виконання створює програмний обліковий запис для зберігання її байт-коду.
Diagram of a program account, its 4 components and its loader program.
Облікові записи даних програми
Програми, розгорнуті за допомогою loader-v3 (див.
Програми-завантажувачі),
не зберігають виконуваний байт-код у власному полі data. Натомість їхнє поле
data вказує на окремий обліковий запис даних програми, що містить код
програми. (Див. діаграму нижче.)
A program account with data. The data points to a separate program data account
Під час розгортання або оновлення програми буферні облікові записи використовуються для тимчасового етапного завантаження.
Наступний приклад отримує обліковий запис Token Program. Поле executable
дорівнює true, що підтверджує, що це програмний обліковий запис.
import { Address, generateKeyPairSigner } from "@solana/kit";import { createClient } from "@solana/kit-client-rpc";const feePayer = await generateKeyPairSigner();const client = createClient({url: "https://api.mainnet.solana.com",payer: feePayer});const programId = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address;const accountInfo = await client.rpc.getAccountInfo(programId, { encoding: "base64" }).send();console.log(accountInfo);
Акаунти даних
Акаунти даних не містять виконуваного коду. Вони зберігають стан, визначений програмою.
Акаунт стану програми
Програми зберігають свій стан в акаунтах даних. Створення акаунта стану програми включає два кроки:
- Викликати системну програму, щоб створити акаунт. Системна програма передає право власності вказаній програмі.
- Програма-власник ініціалізує поле
dataакаунта відповідно до своїх інструкцій.
Діаграма акаунта даних, що належить program account
Наступний приклад створює та отримує mint account токена, що належить програмі Token 2022.
import { generateKeyPairSigner } from "@solana/kit";import { createLocalClient } from "@solana/kit-client-rpc";import { systemProgram } from "@solana-program/system";import {getInitializeMintInstruction,getMintSize,TOKEN_2022_PROGRAM_ADDRESS,fetchMint} from "@solana-program/token-2022";const client = await createLocalClient().use(systemProgram());// Generate keypair to use as address of mintconst mint = await generateKeyPairSigner();// Get default mint account size (in bytes), no extensions enabledconst space = BigInt(getMintSize());// Get minimum balance for rent exemptionconst rent = await client.rpc.getMinimumBalanceForRentExemption(space).send();const transactionSignature = await client.sendTransaction([client.system.instructions.createAccount({newAccount: mint,lamports: rent,space,programAddress: TOKEN_2022_PROGRAM_ADDRESS}),getInitializeMintInstruction({mint: mint.address,decimals: 9,mintAuthority: client.payer.address})]);console.log("Mint Address:", mint.address);console.log("Transaction Signature:", transactionSignature.context.signature);const accountInfo = await client.rpc.getAccountInfo(mint.address).send();console.log(accountInfo);const mintAccount = await fetchMint(client.rpc, mint.address);console.log(mintAccount);
Системні акаунти
Акаунти, які залишаються у власності системної програми після створення, називаються системними акаунтами. Надсилання SOL на нову адресу вперше створює новий акаунт за цією адресою, що належить системній програмі.
Усі акаунти гаманців є системними акаунтами. Платник комісії в транзакції має бути системним акаунтом, оскільки лише акаунти, що належать системній програмі, можуть сплачувати комісії за транзакції.
Гаманець, що належить системній програмі, містить 1 000 000 lamports
Наступний приклад генерує нову keypair, поповнює її SOL і отримує акаунт. Поле
owner має значення 11111111111111111111111111111111
(системна програма).
import { generateKeyPairSigner, lamports } from "@solana/kit";import { createLocalClient } from "@solana/kit-client-rpc";const client = await createLocalClient();// Generate a new keypairconst keypair = await generateKeyPairSigner();console.log(`Public Key: ${keypair.address}`);// Funding an address with SOL automatically creates an accountconst signature = await client.airdrop(keypair.address,lamports(1_000_000_000n));const accountInfo = await client.rpc.getAccountInfo(keypair.address).send();console.log(accountInfo);
Облікові записи Sysvar
Облікові записи Sysvar є спеціальними обліковими записами за заздалегідь визначеними адресами, які надають доступ лише для читання до даних стану кластера. Вони динамічно оновлюються кожен slot.
| Sysvar | Адреса | Призначення |
|---|---|---|
| Clock | SysvarC1ock11111111111111111111111111111111 | Поточний slot, epoch та мітка часу Unix |
| EpochSchedule | SysvarEpochSchedu1e111111111111111111111111 | Константи планування epoch, встановлені в genesis |
| EpochRewards | SysvarEpochRewards1111111111111111111111111 | Статус та прогрес розподілу винагород epoch |
| Rent | SysvarRent111111111111111111111111111111111 | Ставка rent та поріг звільнення |
| SlotHashes | SysvarS1otHashes111111111111111111111111111 | Найновіші хеші батьківських банків slot'а |
| StakeHistory | SysvarStakeHistory1111111111111111111111111 | Активації та деактивації стейкінгу за epoch |
| LastRestartSlot | SysvarLastRestartS1ot1111111111111111111111 | Останній slot перезапуску кластера |
| Instructions | Sysvar1nstructions1111111111111111111111111 | Серіалізовані інструкції поточної транзакції |
| SlotHistory | SysvarS1otHistory11111111111111111111111111 | Запис про те, які slot'и були створені протягом останнього epoch |
Наступний приклад отримує та десеріалізує обліковий запис Sysvar Clock.
import { generateKeyPairSigner } from "@solana/kit";import { createClient } from "@solana/kit-client-rpc";import { fetchSysvarClock, SYSVAR_CLOCK_ADDRESS } from "@solana/sysvars";const feePayer = await generateKeyPairSigner();const client = createClient({url: "https://api.mainnet.solana.com",payer: feePayer});const accountInfo = await client.rpc.getAccountInfo(SYSVAR_CLOCK_ADDRESS, { encoding: "base64" }).send();console.log(accountInfo);// Automatically fetch and deserialize the account dataconst clock = await fetchSysvarClock(client.rpc);console.log(clock);
Is this page helpful?