Ohjeet ovat perustavanlaatuinen rakennuspalikka Solana-lohkoketjun kanssa vuorovaikuttamiseen. Ohje on käytännössä julkinen funktio, jota kuka tahansa Solana-verkon käyttäjä voi kutsua. Jokaista ohjetta käytetään tietyn toiminnon suorittamiseen. Ohjeiden suorituslogiikka on tallennettu ohjelmiin, joissa jokainen ohjelma määrittelee omat ohjeensa. Solana-verkon kanssa vuorovaikuttamiseksi yksi tai useampi ohje lisätään transaktioon ja lähetetään verkkoon käsiteltäväksi.
SOL-siirtoesimerkki
Alla oleva kaavio näyttää, miten transaktiot ja ohjeet toimivat yhdessä mahdollistaen käyttäjien vuorovaikutuksen verkon kanssa. Tässä esimerkissä SOL siirretään yhdeltä tililtä toiselle.
Lähettäjän tilin metatiedot osoittavat, että sen on allekirjoitettava transaktio. (Tämä mahdollistaa System Programin vähentää lamporteja.) Sekä lähettäjän että vastaanottajan tilien on oltava kirjoitettavissa, jotta niiden lamport-saldo voi muuttua. Suorittaakseen tämän ohjeen, lähettäjän lompakko lähettää transaktion, joka sisältää sen allekirjoituksen ja viestin, joka sisältää SOL-siirto-ohjeen.
SOL-siirtokaavio
Kun transaktio on lähetetty, System Program käsittelee siirto-ohjeen ja päivittää molempien tilien lamport-saldon.
SOL-siirtoprosessikaavio
Alla oleva esimerkki näyttää koodin, joka liittyy yllä oleviin kaavioihin. (Katso System Programin siirto-ohje.)
import {airdropFactory,appendTransactionMessageInstructions,createSolanaRpc,createSolanaRpcSubscriptions,createTransactionMessage,generateKeyPairSigner,getSignatureFromTransaction,lamports,pipe,sendAndConfirmTransactionFactory,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,signTransactionMessageWithSigners} from "@solana/kit";import { getTransferSolInstruction } from "@solana-program/system";// Create a connection to clusterconst rpc = createSolanaRpc("http://localhost:8899");const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");// Generate sender and recipient keypairsconst sender = await generateKeyPairSigner();const recipient = await generateKeyPairSigner();const LAMPORTS_PER_SOL = 1_000_000_000n;const transferAmount = lamports(LAMPORTS_PER_SOL / 100n); // 0.01 SOL// Fund sender with airdropawait airdropFactory({ rpc, rpcSubscriptions })({recipientAddress: sender.address,lamports: lamports(LAMPORTS_PER_SOL), // 1 SOLcommitment: "confirmed"});// Check balance before transferconst { value: preBalance1 } = await rpc.getBalance(sender.address).send();const { value: preBalance2 } = await rpc.getBalance(recipient.address).send();// Create a transfer instruction for transferring SOL from sender to recipientconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount // 0.01 SOL in lamports});// Add the transfer instruction to a new transactionconst { value: latestBlockhash } = await rpc.getLatestBlockhash().send();const transactionMessage = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(sender, tx),(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),(tx) => appendTransactionMessageInstructions([transferInstruction], tx));// Send the transaction to the networkconst signedTransaction =await signTransactionMessageWithSigners(transactionMessage);await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction,{ commitment: "confirmed" });const transactionSignature = getSignatureFromTransaction(signedTransaction);// Check balance after transferconst { value: postBalance1 } = await rpc.getBalance(sender.address).send();const { value: postBalance2 } = await rpc.getBalance(recipient.address).send();console.log("Sender prebalance:",Number(preBalance1) / Number(LAMPORTS_PER_SOL));console.log("Recipient prebalance:",Number(preBalance2) / Number(LAMPORTS_PER_SOL));console.log("Sender postbalance:",Number(postBalance1) / Number(LAMPORTS_PER_SOL));console.log("Recipient postbalance:",Number(postBalance2) / Number(LAMPORTS_PER_SOL));console.log("Transaction Signature:", transactionSignature);
Ohjeet
Kaavio, joka kuvaa transaktiota ohjeineen, jaettuna kolmeen komponenttiin
Instruction
koostuu seuraavista tiedoista:
program_id: Kutsuttavan ohjelman ID.accounts: Taulukko tilin metadatastadata: Tavutaulukko, joka sisältää lisä[dataa] käskyn käyttöön.
pub struct Instruction {/// Pubkey of the program that executes this instruction.pub program_id: Pubkey,/// Metadata describing accounts that should be passed to the program.pub accounts: Vec<AccountMeta>,/// Opaque data passed to the program for its own interpretation.pub data: Vec<u8>,}
Ohjelmatunnus
Käskyn program_id on sen ohjelman
julkinen avainosoite, joka sisältää käskyn liiketoimintalogiikan.
Tilitiedot
Käskyn accounts -taulukko on taulukko
AccountMeta
-rakenteita. Metadata on annettava jokaiselle tilille, jonka kanssa käsky on
vuorovaikutuksessa. (Tämä mahdollistaa transaktioiden suorittamisen rinnakkain,
kunhan ne eivät muokkaa samaa tiliä.)
Alla oleva kaavio kuvaa transaktiota, joka sisältää yhden käskyn. Käskyn
accounts -taulukko sisältää metadatan kahdelle tilille.
Transaktio, jossa on yksi käsky. Käsky sisältää kaksi AccountMeta -rakennetta accounts -taulukossaan.
Tilin metatiedot sisältävät seuraavat tiedot:
- pubkey: Tilin julkinen avainosoite
- is_signer: Asetetaan arvoon
true, jos tilin on allekirjoitettava transaktio - is_writable: Asetetaan arvoon
true, jos käsky muokkaa tilin dataa
Tietääksesi, mitä tilejä ohje vaatii, mukaan lukien mitkä on oltava kirjoitettavissa, vain luettavissa tai allekirjoitettava transaktio, sinun on tutustuttava ohjeen toteutukseen, jonka ohjelma määrittelee.
pub struct AccountMeta {/// An account's public key.pub pubkey: Pubkey,/// True if an `Instruction` requires a `Transaction` signature matching `pubkey`.pub is_signer: bool,/// True if the account data or metadata may be mutated during program execution.pub is_writable: bool,}
Tiedot
Käskyn data on tavutaulukko, joka määrittää, mikä ohjelman käskyistä
kutsutaan. Se sisältää myös kaikki käskyn vaatimat argumentit.
Ohjeen luomisen esimerkki
Alla oleva esimerkki näyttää SOL-siirto-ohjeen rakenteen.
import { generateKeyPairSigner, lamports } from "@solana/kit";import { getTransferSolInstruction } from "@solana-program/system";// 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});console.log(JSON.stringify(transferInstruction, null, 2));
Alla oleva koodi näyttää edellisten koodiesimerkkien tulosteen. Muoto vaihtelee
SDK:iden välillä, mutta huomaa, että jokainen käsky sisältää samat kolme
vaadittua tietoa: program_id,
accounts, data.
{"accounts": [{"address": "Hu28vRMGWpQXN56eaE7jRiDDRRz3vCXEs7EKHRfL6bC","role": 3,"signer": {"address": "Hu28vRMGWpQXN56eaE7jRiDDRRz3vCXEs7EKHRfL6bC","keyPair": {"privateKey": {},"publicKey": {}}}},{"address": "2mBY6CTgeyJNJDzo6d2Umipw2aGUquUA7hLdFttNEj7p","role": 1}],"programAddress": "11111111111111111111111111111111","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}}
Alla olevat esimerkit näyttävät, kuinka siirto-ohje rakennetaan manuaalisesti.
(Expanded Instruction -välilehti on toiminnallisesti vastaava kuin
Instruction -välilehti.)
Käytännössä sinun ei yleensä tarvitse rakentaa Instruction -ohjetta
manuaalisesti. Useimmat ohjelmat tarjoavat asiakaskirjastoja, joissa on
apufunktioita, jotka luovat ohjeet puolestasi. Jos kirjastoa ei ole
saatavilla, voit rakentaa ohjeen manuaalisesti.
const transferAmount = 0.01; // 0.01 SOLconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount * LAMPORTS_PER_SOL});
Is this page helpful?