Podsumowanie
Konta programów przechowują wykonywalny kod sBPF. Konta danych przechowują stan, są własnością programów. Konta systemowe należą do System Program. Sysvars udostępniają stan klastra dostępny pod zdefiniowanymi adresami.
Pole executable określa kategorię
konta:
- Konta programów:
executable=true. Zawiera kod wykonywalny. - Konta danych:
executable=false. Przechowuje stan lub dane użytkownika.
Oddzielenie kodu od zmiennego stanu oznacza, że program jest wdrażany tylko raz i może zarządzać dowolną liczbą kont danych.
Konta programów
Konto programu przechowuje kod wykonywalny. Każde konto programu jest własnością loader programu. Gdy program jest wdrażany, środowisko uruchomieniowe tworzy konto programu do przechowywania jego bajtkodu.
Diagram konta programu, jego 4 komponentów i loader programu.
Konta danych programu
Programy wdrażane przy użyciu loader-v3 (zobacz
Loader programs) nie
przechowują wykonywalnego bajtkodu w swoim polu data. Zamiast tego ich data
wskazuje na osobne konto danych programu, które zawiera kod programu.
(Zobacz diagram poniżej.)
Konto programu z danymi. Dane wskazują na osobne konto danych programu
Podczas wdrażania lub aktualizacji programu używane są konta buforowe do tymczasowego przesyłania danych.
Poniższy przykład pobiera konto Token Program. Pole executable ma wartość
true, co potwierdza, że jest to konto programu.
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);
Konta danych
Konta danych nie zawierają kodu wykonywalnego. Przechowują stan zdefiniowany przez program.
Konto stanu programu
Programy przechowują swój stan w kontach danych. Utworzenie konta stanu programu obejmuje dwa kroki:
- Wywołaj System Program, aby utworzyć konto. System Program przekazuje własność wskazanemu programowi.
- Program będący właścicielem inicjalizuje pole
datakonta zgodnie ze swoimi instrukcjami.
Diagram konta danych należącego do program account
Poniższy przykład tworzy i pobiera konto Token Mint należące do programu 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);
Konta systemowe
Konta, które po utworzeniu pozostają własnością System Program, nazywane są kontami systemowymi. Wysłanie SOL na nowy adres po raz pierwszy tworzy nowe konto na tym adresie, którego właścicielem jest System Program.
Wszystkie konta portfeli to konta systemowe. Płatnik opłaty transakcyjnej musi być kontem systemowym, ponieważ tylko konta należące do System Program mogą płacić opłaty transakcyjne.
Portfel należący do System Program zawierający 1 000 000 lamportów
Poniższy przykład generuje nowy keypair, zasila go SOL i pobiera konto. Pole
owner to 11111111111111111111111111111111
(System Program).
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);
Konta Sysvar
Konta Sysvar to specjalne konta o predefiniowanych adresach, które zapewniają tylko do odczytu dostęp do danych o stanie klastra. Aktualizują się dynamicznie w każdym slot.
| Sysvar | Adres | Cel |
|---|---|---|
| Clock | SysvarC1ock11111111111111111111111111111111 | Bieżący slot, epoch i znacznik czasu Unix |
| EpochSchedule | SysvarEpochSchedu1e111111111111111111111111 | Stałe harmonogramu epoch ustalone w genesis |
| EpochRewards | SysvarEpochRewards1111111111111111111111111 | Status i postęp dystrybucji nagród za epoch |
| Rent | SysvarRent111111111111111111111111111111111 | Stawka rent i próg zwolnienia |
| SlotHashes | SysvarS1otHashes111111111111111111111111111 | Najnowsze hashe nadrzędnych banków slotu |
| StakeHistory | SysvarStakeHistory1111111111111111111111111 | Aktywacje i dezaktywacje stake'ów w każdej epoch |
| LastRestartSlot | SysvarLastRestartS1ot1111111111111111111111 | Ostatni slot restartu klastra |
| Instructions | Sysvar1nstructions1111111111111111111111111 | Zserializowane instrukcje bieżącej transakcji |
| SlotHistory | SysvarS1otHistory11111111111111111111111111 | Rejestr slotów wyprodukowanych w ostatniej epoch |
Poniższy przykład pobiera i deserializuje konto 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?