Λογαριασμοί
Όλα τα δεδομένα στο δίκτυο Solana αποθηκεύονται σε λογαριασμούς. Μπορείτε να σκεφτείτε το δίκτυο Solana ως μια δημόσια βάση δεδομένων με έναν μοναδικό πίνακα Λογαριασμών. Η σχέση μεταξύ ενός λογαριασμού και της διεύθυνσής του είναι παρόμοια με αυτή ενός ζεύγους κλειδιού-τιμής, όπου το κλειδί είναι η διεύθυνση και η τιμή είναι ο λογαριασμός.
Κάθε λογαριασμός έχει την ίδια βασική δομή και μπορεί να εντοπιστεί χρησιμοποιώντας τη διεύθυνσή του.
Διάγραμμα 3 λογαριασμών και των διευθύνσεών τους. Περιλαμβάνει τον ορισμό της δομής λογαριασμού.
Διεύθυνση λογαριασμού
Η διεύθυνση του λογαριασμού είναι ένα μοναδικό αναγνωριστικό 32 byte που χρησιμοποιείται για τον εντοπισμό του λογαριασμού στο blockchain της Solana. Οι διευθύνσεις λογαριασμών συχνά εμφανίζονται ως συμβολοσειρές κωδικοποιημένες σε base58. Οι περισσότεροι λογαριασμοί χρησιμοποιούν ένα δημόσιο κλειδί Ed25519 ως διεύθυνσή τους, αλλά αυτό δεν είναι απαραίτητο, καθώς η Solana υποστηρίζει επίσης διευθύνσεις παραγόμενες από προγράμματα.
Ένας λογαριασμός με τη διεύθυνση δημόσιου κλειδιού του κωδικοποιημένη σε base58
Δημόσιο κλειδί
Το παρακάτω παράδειγμα δείχνει πώς να χρησιμοποιήσετε το SDK της Solana για να δημιουργήσετε ένα keypair.
import { generateKeyPairSigner } from "@solana/kit";// Kit does not enable extractable private keysconst keypairSigner = await generateKeyPairSigner();console.log(keypairSigner);
Console
Click to execute the code.
Program Derived Address
Ένα Program Derived Address (PDA) είναι μια διεύθυνση που προσδιορίζεται ντετερμινιστικά χρησιμοποιώντας ένα αναγνωριστικό προγράμματος και μία ή περισσότερες προαιρετικές εισόδους (seeds). Το παρακάτω παράδειγμα δείχνει πώς να χρησιμοποιήσετε το SDK της Solana για να δημιουργήσετε ένα Program Derived Address.
import { Address, getProgramDerivedAddress } from "@solana/kit";const programAddress = "11111111111111111111111111111111" as Address;const seeds = ["helloWorld"];const [pda, bump] = await getProgramDerivedAddress({programAddress,seeds});console.log(`PDA: ${pda}`);console.log(`Bump: ${bump}`);
Console
Click to execute the code.
Δομή λογαριασμού
Κάθε
Account
έχει μέγιστο μέγεθος
10MiB
και περιέχει τις ακόλουθες πληροφορίες:
lamports: Ο αριθμός των lamports στον λογαριασμόdata: Τα δεδομένα του λογαριασμούowner: Το αναγνωριστικό του προγράμματος που κατέχει τον λογαριασμόexecutable: Υποδεικνύει εάν ο λογαριασμός περιέχει εκτελέσιμο δυαδικό αρχείοrent_epoch: Το παρωχημένο πεδίο epoch ενοικίου
Account
pub struct Account {/// lamports in the accountpub lamports: u64,/// data held in this account#[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]pub data: Vec<u8>,/// the program that owns this account. If executable, the program that loads this account.pub owner: Pubkey,/// this account's data contains a loaded program (and is now read-only)pub executable: bool,/// the epoch at which this account will next owe rentpub rent_epoch: Epoch,}
Lamports
Το υπόλοιπο του λογαριασμού σε lamports.
Κάθε λογαριασμός πρέπει να έχει ένα ελάχιστο υπόλοιπο lamport, που ονομάζεται rent, το οποίο επιτρέπει την αποθήκευση των δεδομένων του στην αλυσίδα. Το rent είναι ανάλογο με το μέγεθος του λογαριασμού.
Παρόλο που αυτό το υπόλοιπο ονομάζεται rent, λειτουργεί περισσότερο σαν κατάθεση, καθώς το πλήρες υπόλοιπο μπορεί να ανακτηθεί όταν ο λογαριασμός κλείσει. (Το όνομα "rent" προέρχεται από το πλέον παρωχημένο πεδίο rent epoch.)
(Δείτε τον τύπο ελάχιστου υπολοίπου και τις εφαρμοστέες σταθερές.)
Δεδομένα
Αυτό το πεδίο αναφέρεται συνήθως ως "δεδομένα λογαριασμού". Τα data σε αυτό το
πεδίο θεωρούνται αυθαίρετα καθώς μπορούν να περιέχουν οποιαδήποτε ακολουθία
bytes. Κάθε πρόγραμμα καθορίζει τη δομή των δεδομένων που αποθηκεύονται σε αυτό
το πεδίο.
- Program accounts: Αυτό το πεδίο περιέχει είτε εκτελέσιμο κώδικα προγράμματος είτε τη διεύθυνση ενός λογαριασμού δεδομένων προγράμματος που αποθηκεύει τον εκτελέσιμο κώδικα προγράμματος.
- Λογαριασμοί δεδομένων: Αυτό το πεδίο γενικά αποθηκεύει δεδομένα κατάστασης, που προορίζονται για ανάγνωση.
Η ανάγνωση δεδομένων από έναν λογαριασμό Solana περιλαμβάνει δύο βήματα:
- Ανάκτηση του λογαριασμού χρησιμοποιώντας τη διεύθυνσή του
- Αποσειριοποίηση του πεδίου
dataτου λογαριασμού από ακατέργαστα bytes στην κατάλληλη δομή δεδομένων, όπως ορίζεται από το πρόγραμμα που κατέχει τον λογαριασμό.
Ιδιοκτήτης
Αυτό το πεδίο περιέχει το αναγνωριστικό προγράμματος του ιδιοκτήτη του λογαριασμού.
Κάθε λογαριασμός Solana έχει ένα πρόγραμμα που ορίζεται
ως ιδιοκτήτης του. Ο ιδιοκτήτης του λογαριασμού είναι το μόνο πρόγραμμα που
μπορεί να αλλάξει τα data του λογαριασμού ή να αφαιρέσει lamports, όπως
υποδεικνύεται από τις οδηγίες του προγράμματος.
(Στην περίπτωση ενός program account, ο ιδιοκτήτης είναι το πρόγραμμα φορτωτή.)
Εκτελέσιμο
Αυτό το πεδίο υποδεικνύει εάν ένας λογαριασμός είναι ένας program account ή ένας λογαριασμός δεδομένων
- Αν
true: Ο λογαριασμός είναι program account - Αν
false: Ο λογαριασμός είναι λογαριασμός δεδομένων
Εποχή rent
Το πεδίο rent_epoch είναι παρωχημένο.
Στο παρελθόν, αυτό το πεδίο παρακολουθούσε πότε ένας λογαριασμός θα χρειαζόταν να πληρώσει rent. Ωστόσο, αυτός ο μηχανισμός συλλογής rent έχει πλέον καταργηθεί.
Τύποι λογαριασμών
Υπάρχουν δύο βασικές κατηγορίες στις οποίες εμπίπτουν οι λογαριασμοί:
- Program accounts: Λογαριασμοί που περιέχουν εκτελέσιμο κώδικα
- Λογαριασμοί δεδομένων: Λογαριασμοί που δεν περιέχουν εκτελέσιμο κώδικα
Αυτός ο διαχωρισμός σημαίνει ότι ο εκτελέσιμος κώδικας ενός προγράμματος και η κατάστασή του αποθηκεύονται σε ξεχωριστούς λογαριασμούς. (Παρόμοια με τα λειτουργικά συστήματα, τα οποία συνήθως έχουν ξεχωριστά αρχεία για τα προγράμματα και τα δεδομένα τους.)
Program accounts
Κάθε πρόγραμμα ανήκει σε ένα πρόγραμμα φορτωτή, το οποίο χρησιμοποιείται για την ανάπτυξη και διαχείριση του λογαριασμού. Όταν αναπτύσσεται ένα νέο πρόγραμμα, δημιουργείται ένας λογαριασμός για την αποθήκευση του εκτελέσιμου κώδικά του. Αυτός ονομάζεται program account. (Για απλότητα, μπορείτε να θεωρήσετε τον program account ως το ίδιο το πρόγραμμα.)
Στο παρακάτω διάγραμμα, μπορείτε να δείτε ότι ένα πρόγραμμα φορτωτή
χρησιμοποιείται για την ανάπτυξη ενός program account. Το πεδίο data του
program account περιέχει τον εκτελέσιμο κώδικα του προγράμματος.
Διάγραμμα ενός program account, των 4 συστατικών του και του προγράμματος φορτωτή του.
Λογαριασμοί δεδομένων προγράμματος
Τα προγράμματα που αναπτύσσονται με τη χρήση του loader-v3 δεν περιέχουν κώδικα
προγράμματος στο πεδίο data τους. Αντίθετα, το πεδίο data τους δείχνει σε
έναν ξεχωριστό λογαριασμό δεδομένων προγράμματος, ο οποίος περιέχει τον
κώδικα του προγράμματος. (Δείτε το παρακάτω διάγραμμα.)
Ένας λογαριασμός προγράμματος με δεδομένα. Τα δεδομένα δείχνουν σε έναν ξεχωριστό λογαριασμό δεδομένων προγράμματος
Κατά την ανάπτυξη ή αναβάθμιση προγραμμάτων, οι λογαριασμοί buffer χρησιμοποιούνται για την προσωρινή σταδιακή μεταφόρτωση.
Το παρακάτω παράδειγμα ανακτά τον λογαριασμό του Token Program. Παρατηρήστε ότι
το πεδίο executable έχει οριστεί σε true, υποδεικνύοντας ότι ο λογαριασμός
είναι πρόγραμμα.
import { Address, createSolanaRpc } from "@solana/kit";const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");const programId = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address;const accountInfo = await rpc.getAccountInfo(programId, { encoding: "base64" }).send();console.log(accountInfo);
Console
Click to execute the code.
Λογαριασμοί δεδομένων
Οι λογαριασμοί δεδομένων δεν περιέχουν εκτελέσιμο κώδικα. Αντίθετα, αποθηκεύουν πληροφορίες.
Λογαριασμός κατάστασης προγράμματος
Τα προγράμματα χρησιμοποιούν λογαριασμούς δεδομένων για να διατηρούν την κατάστασή τους. Για να το κάνουν αυτό, πρέπει πρώτα να δημιουργήσουν έναν νέο λογαριασμό δεδομένων. Η διαδικασία δημιουργίας ενός λογαριασμού κατάστασης προγράμματος συχνά αφαιρείται, αλλά είναι χρήσιμο να κατανοήσουμε την υποκείμενη διαδικασία.
Για να διαχειριστεί την κατάστασή του, ένα νέο πρόγραμμα πρέπει:
- Να επικαλεστεί το System Program για να δημιουργήσει έναν λογαριασμό. (Το System Program στη συνέχεια μεταφέρει την ιδιοκτησία στο νέο πρόγραμμα.)
- Να αρχικοποιήσει τα δεδομένα του λογαριασμού, όπως ορίζεται από τις οδηγίες του.
Διάγραμμα ενός λογαριασμού δεδομένων που ανήκει σε έναν λογαριασμό προγράμματος
Το παρακάτω παράδειγμα δημιουργεί και ανακτά έναν λογαριασμό Token Mint που ανήκει στο πρόγραμμα 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);
Console
Click to execute the code.
Λογαριασμοί συστήματος
Δεν ανατίθενται όλοι οι λογαριασμοί σε νέο ιδιοκτήτη μετά τη δημιουργία τους από το System Program. Οι λογαριασμοί που ανήκουν στο System Program ονομάζονται λογαριασμοί συστήματος. Όλοι οι λογαριασμοί πορτοφολιού είναι λογαριασμοί συστήματος, γεγονός που τους επιτρέπει να πληρώνουν χρεώσεις συναλλαγών.
Ένα πορτοφόλι που ανήκει στο System Program και περιέχει 1.000.000 lamports
Όταν αποστέλλεται SOL σε μια νέα διεύθυνση για πρώτη φορά, δημιουργείται ένας λογαριασμός σε αυτή τη διεύθυνση που ανήκει στο System Program.
Στο παρακάτω παράδειγμα, δημιουργείται ένα νέο 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);
Console
Click to execute the code.
Λογαριασμοί Sysvar
Οι λογαριασμοί Sysvar υπάρχουν σε προκαθορισμένες διευθύνσεις και παρέχουν πρόσβαση σε δεδομένα κατάστασης του συμπλέγματος. Ενημερώνονται δυναμικά με δεδομένα σχετικά με το δίκτυο του συμπλέγματος. Δείτε την πλήρη λίστα των Λογαριασμών Sysvar.
Το παρακάτω παράδειγμα ανακτά και αποσειριοποιεί δεδομένα από τον λογαριασμό Sysvar Clock.
import { createSolanaRpc } from "@solana/kit";import { fetchSysvarClock, SYSVAR_CLOCK_ADDRESS } from "@solana/sysvars";const rpc = createSolanaRpc("https://api.mainnet-beta.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);
Console
Click to execute the code.
Is this page helpful?