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, createSolanaRpc } from "@solana/kit";const rpc = createSolanaRpc("https://api.mainnet.solana.com");const programId = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address;const accountInfo = await 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 {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 exampleconst rpc = createSolanaRpc("http://localhost:8899");const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");// Generate keypairs for fee payerconst feePayer = await generateKeyPairSigner();// Fund fee payerawait airdropFactory({ rpc, rpcSubscriptions })({recipientAddress: feePayer.address,lamports: lamports(1_000_000_000n),commitment: "confirmed"});// 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 rpc.getMinimumBalanceForRentExemption(space).send();// Instruction to create new account for mint (token 2022 program)// Invokes the system programconst createAccountInstruction = getCreateAccountInstruction({payer: feePayer,newAccount: mint,lamports: rent,space,programAddress: TOKEN_2022_PROGRAM_ADDRESS});// Instruction to initialize mint account data// Invokes the token 2022 programconst initializeMintInstruction = getInitializeMintInstruction({mint: mint.address,decimals: 9,mintAuthority: feePayer.address});const instructions = [createAccountInstruction, initializeMintInstruction];// Get latest blockhash to include in transactionconst { value: latestBlockhash } = await rpc.getLatestBlockhash().send();// Create transaction messageconst 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 transactionawait sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction,{ commitment: "confirmed" });// Get transaction signatureconst 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);
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 {airdropFactory,createSolanaRpc,createSolanaRpcSubscriptions,generateKeyPairSigner,lamports} from "@solana/kit";// Create a connection to Solana clusterconst rpc = createSolanaRpc("http://localhost:8899");const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");// Generate a new keypairconst keypair = await generateKeyPairSigner();console.log(`Public Key: ${keypair.address}`);// Funding an address with SOL automatically creates an accountconst 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);
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 { createSolanaRpc } from "@solana/kit";import { fetchSysvarClock, SYSVAR_CLOCK_ADDRESS } from "@solana/sysvars";const rpc = createSolanaRpc("https://api.mainnet.solana.com");const accountInfo = await rpc.getAccountInfo(SYSVAR_CLOCK_ADDRESS, { encoding: "base64" }).send();console.log(accountInfo);// Automatically fetch and deserialize the account dataconst clock = await fetchSysvarClock(rpc);console.log(clock);
Is this page helpful?