Transaktiot
Vuorovaikuttaaksesi Solana-verkon kanssa sinun täytyy lähettää transaktio. Voit ajatella transaktiota kirjekuorena, joka sisältää useita lomakkeita. Jokainen lomake on ohje, joka kertoo verkolle mitä tehdä. Transaktion lähettäminen on kuin kirjekuoren postittaminen, jotta lomakkeet voidaan käsitellä.
Alla oleva esimerkki näyttää yksinkertaistetun version kahdesta transaktiosta. Kun ensimmäinen transaktio käsitellään, se suorittaa yhden ohjeen. Kun toinen transaktio käsitellään, se suorittaa kolme ohjetta peräkkäisessä järjestyksessä: ensin ohje 1, sitten ohje 2 ja lopuksi ohje 3.
Transaktiot ovat atomisia: Jos yksikin ohje epäonnistuu, koko transaktio epäonnistuu eikä muutoksia tapahdu.
Yksinkertaistettu kaavio, joka näyttää kaksi transaktiota
Transaction
koostuu seuraavista tiedoista:
signatures: Taulukko allekirjoituksiamessage: Transaktion tiedot, mukaan lukien luettelo käsiteltävistä ohjeista
pub struct Transaction {#[wasm_bindgen(skip)]#[serde(with = "short_vec")]pub signatures: Vec<Signature>,#[wasm_bindgen(skip)]pub message: Message,}
Kaavio, joka näyttää transaktion kaksi osaa
Transaktioilla on kokonaiskoon rajoitus
1232
tavua. Tämä rajoitus sisältää sekä signatures -taulukon että
message -rakenteen.
Tämä rajoitus tulee IPv6:n Maximum Transmission Unit (MTU) -koosta, joka on 1280 tavua, miinus 48 tavua verkko-otsikoille (40 tavua IPv6 + 8 tavua otsikko).
Kaavio, joka näyttää transaktion muodon ja kokorajoitukset
Allekirjoitukset
Transaktion signatures -taulukko sisältää Signature -rakenteita. Jokainen
Signature
on 64 tavua ja se luodaan allekirjoittamalla transaktion Message tilin
yksityisellä avaimella. Allekirjoitus on annettava jokaiselle
allekirjoittajatilille, joka sisältyy mihinkään
transaktion ohjeista.
Ensimmäinen allekirjoitus kuuluu tilille, joka maksaa tapahtuman perusmaksun ja on tapahtuman allekirjoitus. Tapahtuman allekirjoitusta voidaan käyttää tapahtuman tietojen hakemiseen verkosta.
Viesti
Tapahtuman message on
Message
-rakenne, joka sisältää seuraavat tiedot:
header: Viestin otsikkoaccount_keys: Taulukko tilien osoitteista, joita tapahtuman ohjeet vaativatrecent_blockhash: Lohkohash, joka toimii tapahtuman aikaleimanainstructions: Taulukko ohjeista
Tilan säästämiseksi tapahtuma ei tallenna käyttöoikeuksia jokaiselle tilille
erikseen. Sen sijaan tilien käyttöoikeudet määritetään käyttämällä header ja
account_keys -tietoja.
pub struct Message {/// The message header, identifying signed and read-only `account_keys`.pub header: MessageHeader,/// All the account keys used by this transaction.#[serde(with = "short_vec")]pub account_keys: Vec<Pubkey>,/// The id of a recent ledger entry.pub recent_blockhash: Hash,/// Programs that will be executed in sequence and committed in/// one atomic transaction if all succeed.#[serde(with = "short_vec")]pub instructions: Vec<CompiledInstruction>,}
Otsikko
Viestin header on
MessageHeader
-rakenne. Se sisältää seuraavat tiedot:
num_required_signatures: Tapahtuman vaatimien allekirjoitusten kokonaismääränum_readonly_signed_accounts: Vain luku -tilien kokonaismäärä, jotka vaativat allekirjoituksianum_readonly_unsigned_accounts: Vain luku -tilien kokonaismäärä, jotka eivät vaadi allekirjoituksia
pub struct MessageHeader {/// The number of signatures required for this message to be considered/// valid. The signers of those signatures must match the first/// `num_required_signatures` of [`Message::account_keys`].pub num_required_signatures: u8,/// The last `num_readonly_signed_accounts` of the signed keys are read-only/// accounts.pub num_readonly_signed_accounts: u8,/// The last `num_readonly_unsigned_accounts` of the unsigned keys are/// read-only accounts.pub num_readonly_unsigned_accounts: u8,}
Kaavio, joka näyttää viestin otsikon kolme osaa
Tilien osoitteet
Viestin
account_keys
on taulukko tilien osoitteista, jotka lähetetään
kompaktissa taulukkomuodossa.
Taulukon etuliite ilmaisee sen pituuden. Jokainen taulukon kohde on julkinen
avain, joka osoittaa ohjeiden käyttämään tiliin. accounts_keys -taulukon on
oltava täydellinen ja tiukasti järjestetty seuraavasti:
- Allekirjoittaja + Kirjoitettava
- Allekirjoittaja + Vain luku
- Ei allekirjoittaja + Kirjoitettava
- Ei allekirjoittaja + Vain luku
Tiukka järjestys mahdollistaa account_keys -taulukon yhdistämisen viestin
header -tietoihin kunkin tilin käyttöoikeuksien määrittämiseksi.
Kaavio, joka näyttää tilitietojen järjestyksen
Viimeisin lohkohash
Viestin recent_blockhash on hash-arvo, joka toimii tapahtuman aikaleimana ja
estää tapahtumien kahdentumisen. Lohkohash vanhenee
150 lohkon
jälkeen. (Vastaa noin yhtä minuuttia – olettaen että jokainen lohko on 400ms.)
Lohkon vanhentumisen jälkeen tapahtuma on vanhentunut eikä sitä voida käsitellä.
getLatestBlockhash RPC-metodi
mahdollistaa nykyisen lohkohashin ja viimeisen lohkon korkeuden hakemisen,
jossa lohkohash on vielä voimassa.
Ohjeet
Viestin
instructions
on taulukko kaikista käsiteltävistä ohjeista, jotka lähetetään
kompaktissa taulukkomuodossa.
Taulukon etuliite ilmaisee sen pituuden. Jokainen taulukon kohde on
CompiledInstruction
-rakenne ja sisältää seuraavat tiedot:
program_id_index: Indeksi, joka osoittaa osoitteeseenaccount_keys-taulukossa. Tämä arvo osoittaa ohjelman osoitteen, joka käsittelee ohjeen.accounts: Taulukko indeksejä, jotka osoittavat osoitteisiinaccount_keys-taulukossa. Jokainen indeksi osoittaa tämän ohjeen vaatiman tilin osoitteeseen.data: Tavutaulukko, joka määrittää mikä ohje kutsutaan ohjelmassa. Se sisältää myös kaikki ohjeen vaatimat lisätiedot. (Esimerkiksi funktion argumentit)
pub struct CompiledInstruction {/// Index into the transaction keys array indicating the program account that executes this instruction.pub program_id_index: u8,/// Ordered indices into the transaction keys array indicating which accounts to pass to the program.#[serde(with = "short_vec")]pub accounts: Vec<u8>,/// The program input data.#[serde(with = "short_vec")]pub data: Vec<u8>,}
Ohjeiden kompakti taulukko
Esimerkki tapahtuman rakenteesta
Seuraava esimerkki näyttää tapahtuman rakenteen, joka sisältää yhden SOL-siirto-ohjeen.
import {createSolanaRpc,generateKeyPairSigner,lamports,createTransactionMessage,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,appendTransactionMessageInstructions,pipe,signTransactionMessageWithSigners,getCompiledTransactionMessageDecoder} from "@solana/kit";import { getTransferSolInstruction } from "@solana-program/system";const rpc = createSolanaRpc("http://localhost:8899");const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();// Generate sender and recipient keypairsconst sender = await generateKeyPairSigner();const recipient = await generateKeyPairSigner();// Define the amount to transferconst LAMPORTS_PER_SOL = 1_000_000_000n;const transferAmount = lamports(LAMPORTS_PER_SOL / 100n); // 0.01 SOL// Create a transfer instruction for transferring SOL from sender to recipientconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount});// Create transaction messageconst transactionMessage = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(sender, tx),(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),(tx) => appendTransactionMessageInstructions([transferInstruction], tx));const signedTransaction =await signTransactionMessageWithSigners(transactionMessage);// Decode the messageBytesconst compiledTransactionMessage =getCompiledTransactionMessageDecoder().decode(signedTransaction.messageBytes);console.log(JSON.stringify(compiledTransactionMessage, null, 2));
Alla oleva koodi näyttää tuloksen edellisistä koodiesimerkeistä. Formaatti vaihtelee SDK:iden välillä, mutta huomaa, että jokainen ohje sisältää samat vaaditut tiedot.
{"version": 0,"header": {"numSignerAccounts": 1,"numReadonlySignerAccounts": 0,"numReadonlyNonSignerAccounts": 1},"staticAccounts": ["HoCy8p5xxDDYTYWEbQZasEjVNM5rxvidx8AfyqA4ywBa","5T388jBjovy7d8mQ3emHxMDTbUF8b7nWvAnSiP3EAdFL","11111111111111111111111111111111"],"lifetimeToken": "EGCWPUEXhqHJWYBfDirq3mHZb4qDpATmYqBZMBy9TBC1","instructions": [{"programAddressIndex": 2,"accountIndices": [0, 1],"data": {"0": 2,"1": 0,"2": 0,"3": 0,"4": 128,"5": 150,"6": 152,"7": 0,"8": 0,"9": 0,"10": 0,"11": 0}}]}
Kun transaktio on lähetetty, voit hakea sen tiedot käyttämällä transaktion allekirjoitusta ja getTransaction RPC-metodia. Vastaus tulee olemaan rakenteeltaan samankaltainen kuin seuraava katkelma.
Voit myös löytää transaktion käyttämällä Solana Exploreria.
{"blockTime": 1745196488,"meta": {"computeUnitsConsumed": 150,"err": null,"fee": 5000,"innerInstructions": [],"loadedAddresses": {"readonly": [],"writable": []},"logMessages": ["Program 11111111111111111111111111111111 invoke [1]","Program 11111111111111111111111111111111 success"],"postBalances": [989995000, 10000000, 1],"postTokenBalances": [],"preBalances": [1000000000, 0, 1],"preTokenBalances": [],"rewards": [],"status": {"Ok": null}},"slot": 13049,"transaction": {"message": {"header": {"numReadonlySignedAccounts": 0,"numReadonlyUnsignedAccounts": 1,"numRequiredSignatures": 1},"accountKeys": ["8PLdpLxkuv9Nt8w3XcGXvNa663LXDjSrSNon4EK7QSjQ","7GLg7bqgLBv1HVWXKgWAm6YoPf1LoWnyWGABbgk487Ma","11111111111111111111111111111111"],"recentBlockhash": "7ZCxc2SDhzV2bYgEQqdxTpweYJkpwshVSDtXuY7uPtjf","instructions": [{"accounts": [0, 1],"data": "3Bxs4NN8M2Yn4TLb","programIdIndex": 2,"stackHeight": null}],"indexToProgramIds": {}},"signatures": ["3jUKrQp1UGq5ih6FTDUUt2kkqUfoG2o4kY5T1DoVHK2tXXDLdxJSXzuJGY4JPoRivgbi45U2bc7LZfMa6C4R3szX"]},"version": "legacy"}
Is this page helpful?