Kaikki data Solana-verkossa tallennetaan tileihin. Voit ajatella Solana-verkkoa julkisena tietokantana, jossa on yksi Tilit-taulu. Tilin ja sen osoitteen välinen suhde on samankaltainen kuin avain-arvo-parissa, jossa avain on osoite ja arvo on tili.
Jokaisella tilillä on sama perus rakenne ja se voidaan paikantaa sen osoitteen avulla.
Kaavio kolmesta tilistä ja niiden osoitteista. Sisältää tilin rakenteen määritelmän.
Tilin osoite
Tilin osoite on 32-tavuinen yksilöllinen tunniste, jota käytetään tilin paikantamiseen Solana-lohkoketjussa. Tilien osoitteet näytetään usein base58-koodattuina merkkijonoina. Useimmat tilit käyttävät Ed25519 julkista avainta osoitteenaan, mutta tämä ei ole pakollista, sillä Solana tukee myös ohjelmasta johdettuja osoitteita.
Tili ja sen base58-koodattu julkisen avaimen osoite
Julkinen avain
Alla oleva esimerkki havainnollistaa, miten Solana SDK:ta käytetään
keypair-parin luomiseen. Keypair sisältää:
- Julkisen avaimen, joka toimii tilin osoitteena
- Yksityisen avaimen, jota käytetään transaktioiden allekirjoittamiseen
import { generateKeyPairSigner } from "@solana/kit";// Kit does not enable extractable private keysconst keypairSigner = await generateKeyPairSigner();console.log(keypairSigner);
Program derived address
Program derived address (PDA) on osoite, joka on deterministisesti johdettu käyttäen ohjelmatunnusta ja yhtä tai useampaa valinnaista syötettä (siemeniä). Alla oleva esimerkki näyttää, miten Solana SDK:ta käytetään Program derived address -osoitteen luomiseen.
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}`);
Tilin rakenne
Jokaisen
Account
enimmäiskoko on
10MiB
ja se sisältää seuraavat tiedot:
lamports: Tilin lamport-määrädata: Tilin dataowner: Tilin omistavan ohjelman IDexecutable: Ilmaisee, sisältääkö tili suoritettavaa binääriärent_epoch: Vanhentunut rent epoch -kenttä
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
Tilin saldo lamport-yksiköissä.
Jokaisella tilillä on oltava vähimmäismäärä lamport-yksiköitä, jota kutsutaan nimellä rent, mikä mahdollistaa sen tietojen tallentamisen lohkoketjuun. Rent on verrannollinen tilin kokoon.
Vaikka tätä saldoa kutsutaan nimellä rent, se toimii enemmän talletuksen tavoin, sillä koko saldon voi saada takaisin, kun tili suljetaan. (Nimi "rent" tulee nyt vanhentuneesta rent epoch -kentästä.)
(Katso vähimmäissaldon kaava ja sovellettavat vakiot.)
Data
Tätä kenttää kutsutaan yleisesti "tilin dataksi". Tämän kentän data katsotaan
mielivaltaiseksi, koska se voi sisältää minkä tahansa tavujonon. Jokainen
ohjelma määrittelee tähän kenttään tallennetun datan rakenteen.
- Program account: Tämä kenttä sisältää joko suoritettavan ohjelmakoodin tai program data account -osoitteen, johon suoritettava ohjelmakoodi on tallennettu.
- Data account: Tämä kenttä yleensä tallentaa tilatietoja, jotka on tarkoitettu luettaviksi.
Datan lukeminen Solana-tililtä sisältää kaksi vaihetta:
- Tilin hakeminen sen osoitteella
- Tilin
data-kentän deserialisointi raakatavuista sopivaan datarakenteeseen, kuten tilin omistava ohjelma on määritellyt.
Owner
Tämä kenttä sisältää tilin omistajan ohjelmatunnuksen.
Jokaisella Solana-tilillä on ohjelma, joka on määritetty
sen omistajana. Tilin omistaja on ainoa ohjelma, joka voi muuttaa tilin data
-kenttää tai vähentää lamportteja, kuten ohjelman instruktiot osoittavat.
(Program account -tapauksessa omistaja on sen lataaja-ohjelma.)
Executable
Tämä kenttä ilmaisee, onko tili program account vai data account
- Jos
true: Tili on program account - Jos
false: Tili on datatili
Rent epoch
rent_epoch -kenttä on vanhentunut.
Aiemmin tämä kenttä seurasi, milloin tilin pitäisi maksaa rent-maksua. Tämä rent-keräysmekanismi on kuitenkin sittemmin poistettu käytöstä.
Tilityypit
Tilit jakautuvat kahteen peruskategoriaan:
- Ohjelma-tilit: Tilit, jotka sisältävät suoritettavaa koodia
- Data-tilit: Tilit, jotka eivät sisällä suoritettavaa koodia
Tämä ohjelman koodin ja sen tilan erottaminen on keskeinen ominaisuus Solanan tilimallissa. (Samankaltaisesti kuin käyttöjärjestelmissä, joissa tyypillisesti on erilliset tiedostot ohjelmille ja niiden datalle.)
Ohjelma-tilit
Jokaisen ohjelman omistaa lataaja-ohjelma, jota käytetään tilin käyttöönottoon ja hallintaan. Kun uusi ohjelma otetaan käyttöön, luodaan tili sen suoritettavan koodin tallentamiseen. Tätä kutsutaan ohjelma-tiliksi. (Yksinkertaisuuden vuoksi voit ajatella ohjelma-tilin olevan itse ohjelma.)
Alla olevassa kaaviossa näet, kuinka loader-ohjelmaa käytetään program accountin
käyttöönottoon. Program accountin data sisältää suoritettavan ohjelmakoodin.
Kaavio ohjelma-tilistä, sen 4 komponentista ja sen lataaja-ohjelmasta.
Ohjelma-datatilit
Loader-v3:lla käyttöönotetut ohjelmat eivät sisällä ohjelmakoodia
data-kentässään. Sen sijaan niiden data osoittaa erilliseen program data
accountiin, joka sisältää ohjelmakoodin. (Katso alla oleva kaavio.)
Ohjelma-tili datalla. Data osoittaa erilliseen ohjelma-datatiliin
Ohjelman käyttöönoton tai päivitysten aikana puskuritilejä käytetään väliaikaisesti latauksen valmisteluun.
Alla oleva esimerkki hakee Token Program -tilin. Huomaa, että
executable-kenttä on asetettu arvoon true, mikä osoittaa, että tili on
ohjelma.
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);
Data-tilit
Data-tilit eivät sisällä suoritettavaa koodia. Sen sijaan ne tallentavat tietoa.
Program state account -tilit
Ohjelmat käyttävät data-tilejä tilansa ylläpitämiseen. Tehdäkseen niin, niiden täytyy ensin luoda uusi data-tili. Ohjelman tilatilien luomisprosessi on usein abstrahoitu, mutta on hyödyllistä ymmärtää taustalla oleva prosessi.
Hallitakseen tilaansa, uuden ohjelman täytyy:
- Kutsua System Program luomaan tili. (System Program siirtää sitten omistajuuden uudelle ohjelmalle.)
- Alustaa tilin data, kuten sen ohjeet määrittelevät.
Kaavio data-tilistä, jonka omistaa program account
Alla oleva esimerkki luo ja hakee Token Mint -tilin, jonka omistaa Token 2022 -ohjelma.
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-tilit
Kaikkia tilejä ei määritetä uudelle omistajalle sen jälkeen, kun System Program on luonut ne. System Programin omistamia tilejä kutsutaan system-tileiksi. Kaikki lompakkotilit ovat system-tilejä, mikä mahdollistaa niiden maksaa transaktiomaksuja.
System Programin omistama lompakko, joka sisältää 1 000 000 lamportsia
Kun SOL lähetetään uuteen osoitteeseen ensimmäistä kertaa, tili luodaan kyseiseen osoitteeseen System Programin omistamana.
Alla olevassa esimerkissä luodaan uusi keypair ja rahoitetaan se SOL:lla. Koodin
suorittamisen jälkeen näet, että tilin owner-osoite on
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-tilit
Sysvar-tilit ovat ennalta määritetyissä osoitteissa ja tarjoavat pääsyn klusterin tilatietoihin. Ne päivittyvät dynaamisesti verkkoklusterin tiedoilla. Katso täydellinen luettelo Sysvar-tileistä.
Alla oleva esimerkki hakee ja purkaa tietoja Sysvar Clock -tililtä.
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?