ملخص
تحتوي حسابات البرامج على كود sBPF القابل للتنفيذ. تخزن حسابات البيانات الحالة، وتكون مملوكة للبرامج. حسابات النظام مملوكة لبرنامج النظام. توفر متغيرات النظام حالة الكتلة يمكن الوصول إليها على عناوين محددة مسبقًا.
يحدد حقل executable فئة الحساب:
- حسابات البرامج:
executable=true. يحتوي على كود قابل للتنفيذ. - حسابات البيانات:
executable=false. يخزن الحالة أو بيانات المستخدم.
هذا الفصل بين الكود والحالة القابلة للتغيير يعني أن البرنامج يتم نشره مرة واحدة ويمكنه إدارة أي عدد من حسابات البيانات.
حسابات البرامج
يخزن حساب البرنامج الكود القابل للتنفيذ. كل حساب برنامج مملوك لـبرنامج محمل. عندما يتم نشر برنامج، ينشئ وقت التشغيل حساب برنامج لحفظ الكود الثنائي الخاص به.
مخطط لحساب برنامج ومكوناته الأربعة وبرنامج المحمل الخاص به.
حسابات بيانات البرامج
البرامج المنشورة باستخدام loader-v3 (انظر
برامج المحمل) لا تخزن
الكود الثنائي القابل للتنفيذ في حقل data الخاص بها. بدلاً من ذلك، يشير حقل
data الخاص بها إلى حساب بيانات برنامج منفصل يحتوي على كود البرنامج. (انظر
المخطط أدناه.)
حساب برنامج مع بيانات. تشير البيانات إلى حساب بيانات برنامج منفصل
أثناء نشر البرنامج أو الترقيات، تُستخدم حسابات المخزن المؤقت لتجهيز التحميل مؤقتًا.
يسترجع المثال التالي حساب Token Program. حقل executable هو true، مما يؤكد
أنه حساب برنامج.
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);
حسابات البيانات
حسابات البيانات لا تحتوي على كود قابل للتنفيذ. إنها تخزن الحالة المحددة بواسطة البرنامج.
حساب حالة البرنامج
تخزن البرامج حالتها في حسابات البيانات. يتضمن إنشاء حساب حالة البرنامج خطوتين:
- استدعاء System Program لإنشاء الحساب. يقوم System Program بنقل الملكية إلى البرنامج المحدد.
- يقوم البرنامج المالك بتهيئة حقل
dataالخاص بالحساب وفقًا لـ التعليمات الخاصة به.
مخطط لحساب بيانات مملوك بواسطة program account
ينشئ المثال التالي ويجلب mint account مملوكًا بواسطة برنامج 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);
حسابات النظام
الحسابات التي تظل مملوكة لـ System Program بعد الإنشاء تسمى حسابات النظام. إرسال SOL إلى عنوان جديد لأول مرة ينشئ حسابًا جديدًا في ذلك العنوان مملوكًا لـ System Program.
جميع حسابات المحفظة هي حسابات نظام. يجب أن يكون دافع الرسوم في المعاملة حساب نظام، لأن الحسابات المملوكة لـ System Program فقط يمكنها دفع رسوم المعاملات.
محفظة مملوكة لـ System Program تحتوي على 1,000,000 lamport
ينشئ المثال التالي keypair جديدًا، ويموله بـ SOL، ويجلب الحساب. حقل owner هو
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);
حسابات Sysvar
حسابات Sysvar هي حسابات خاصة بعناوين محددة مسبقاً توفر وصولاً للقراءة فقط إلى بيانات حالة الشبكة. يتم تحديثها ديناميكياً كل slot.
| Sysvar | العنوان | الغرض |
|---|---|---|
| Clock | SysvarC1ock11111111111111111111111111111111 | الـ slot الحالي، الـ epoch، والطابع الزمني Unix |
| EpochSchedule | SysvarEpochSchedu1e111111111111111111111111 | ثوابت جدولة الـ epoch المحددة في genesis |
| EpochRewards | SysvarEpochRewards1111111111111111111111111 | حالة وتقدم توزيع مكافآت الـ epoch |
| Rent | SysvarRent111111111111111111111111111111111 | معدل الـ rent وحد الإعفاء |
| SlotHashes | SysvarS1otHashes111111111111111111111111111 | أحدث hashes لـ banks الأصلية للـ slot |
| StakeHistory | SysvarStakeHistory1111111111111111111111111 | تفعيلات وإلغاء تفعيلات الـ stake لكل epoch |
| LastRestartSlot | SysvarLastRestartS1ot1111111111111111111111 | آخر slot لإعادة تشغيل الشبكة |
| Instructions | Sysvar1nstructions1111111111111111111111111 | التعليمات المتسلسلة للمعاملة الحالية |
| SlotHistory | SysvarS1otHistory11111111111111111111111111 | سجل الـ slots التي تم إنتاجها خلال الـ epoch الأخير |
يوضح المثال التالي كيفية جلب وإلغاء تسلسل حساب 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?