Zusammenfassung
Program Accounts enthalten ausführbaren sBPF-Code. Data Accounts speichern Zustand, der von Programmen verwaltet wird. System Accounts gehören dem System Program. Sysvars bieten clusterweiten Zustand, der über vordefinierte Adressen zugänglich ist.
Das Feld executable bestimmt die
Kategorie eines Konten:
- Program Accounts:
executable=true. Enthält ausführbaren Code. - Data Accounts:
executable=false. Speichert Zustand oder Benutzerdaten.
Diese Trennung von Code und veränderbarem Zustand bedeutet, dass ein Programm einmal deployed wird und beliebig viele Data Accounts verwalten kann.
Program Accounts
Ein Program Account speichert ausführbaren Code. Jeder Program Account gehört einem Loader-Programm. Wenn ein Programm deployed wird, erstellt die Runtime einen Program Account, um dessen Bytecode zu speichern.
Diagramm eines Program Account, seiner 4 Komponenten und seines Loader-Programms.
Program Data Accounts
Programme, die mit loader-v3 deployed wurden (siehe
Loader-Programme),
speichern ausführbaren Bytecode nicht in ihrem eigenen data-Feld. Stattdessen
verweist ihr data auf einen separaten Program Data Account, der den
Programmcode enthält. (Siehe Diagramm unten.)
Ein Program Account mit Daten. Die Daten verweisen auf einen separaten Program Data Account
Während des Programm-Deployments oder bei Upgrades werden Buffer-Accounts verwendet, um den Upload temporär bereitzustellen.
Das folgende Beispiel ruft den Token Program Account ab. Das Feld executable
ist true, was bestätigt, dass es sich um einen Program Account handelt.
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);
Datenkonten
Datenkonten enthalten keinen ausführbaren Code. Sie speichern programmdefinierte Zustände.
Programmzustandskonto
Programme speichern ihren Zustand in Datenkonten. Das Erstellen eines Programmzustandskontos umfasst zwei Schritte:
- Rufen Sie das System Program auf, um das Konto zu erstellen. Das System Program überträgt die Eigentümerschaft an das angegebene Programm.
- Das besitzende Programm initialisiert das
data-Feld des Kontos gemäß seinen Anweisungen.
Diagramm eines Datenkontos, das einem Programmkonto gehört
Das folgende Beispiel erstellt und ruft ein Token-Mint-Konto ab, das dem Token 2022-Programm gehört.
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);
Systemkonten
Konten, die nach der Erstellung im Besitz des System Program bleiben, werden als Systemkonten bezeichnet. Das erstmalige Senden von SOL an eine neue Adresse erstellt ein neues Konto unter dieser Adresse, das dem System Program gehört.
Alle Wallet-Konten sind Systemkonten. Der Fee-Zahler einer Transaktion muss ein Systemkonto sein, da nur Konten im Besitz des System Program Transaktionsgebühren zahlen können.
Ein Wallet im Besitz des System Program mit 1.000.000 Lamports
Das folgende Beispiel generiert ein neues Keypair, finanziert es mit SOL und
ruft das Konto ab. Das owner-Feld ist 11111111111111111111111111111111 (das
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);
Sysvar-Konten
Sysvar-Konten sind spezielle Konten mit vordefinierten Adressen, die schreibgeschützten Zugriff auf Cluster-Zustandsdaten ermöglichen. Sie werden dynamisch in jedem Slot aktualisiert.
| Sysvar | Adresse | Zweck |
|---|---|---|
| Clock | SysvarC1ock11111111111111111111111111111111 | Aktueller Slot, Epoch und Unix-Zeitstempel |
| EpochSchedule | SysvarEpochSchedu1e111111111111111111111111 | Epoch-Planungskonstanten, die in Genesis festgelegt wurden |
| EpochRewards | SysvarEpochRewards1111111111111111111111111 | Status und Fortschritt der Epoch-Belohnungsverteilung |
| Rent | SysvarRent111111111111111111111111111111111 | Mietsatz und Befreiungsschwelle |
| SlotHashes | SysvarS1otHashes111111111111111111111111111 | Neueste Hashes der übergeordneten Banken des Slots |
| StakeHistory | SysvarStakeHistory1111111111111111111111111 | Stake-Aktivierungen und -Deaktivierungen pro Epoch |
| LastRestartSlot | SysvarLastRestartS1ot1111111111111111111111 | Letzter Cluster-Neustart-Slot |
| Instructions | Sysvar1nstructions1111111111111111111111111 | Serialisierte Anweisungen der aktuellen Transaktion |
| SlotHistory | SysvarS1otHistory11111111111111111111111111 | Aufzeichnung darüber, welche Slots in der letzten Epoch produziert wurden |
Das folgende Beispiel ruft das Sysvar-Clock-Konto ab und deserialisiert es.
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?