Istruzioni
Le istruzioni sono il blocco fondamentale per interagire con la blockchain Solana. Un'istruzione è essenzialmente una funzione pubblica che chiunque utilizzi la rete Solana può chiamare. Ogni istruzione viene utilizzata per eseguire un'azione specifica. La logica di esecuzione per le istruzioni è memorizzata nei programmi, dove ogni programma definisce il proprio set di istruzioni. Per interagire con la rete Solana, una o più istruzioni vengono aggiunte a una transazione e inviate alla rete per essere elaborate.
Esempio di trasferimento di SOL
Il diagramma seguente mostra come le transazioni e le istruzioni lavorano insieme per consentire agli utenti di interagire con la rete. In questo esempio, SOL viene trasferito da un account a un altro.
I metadati dell'account del mittente indicano che deve firmare per la transazione. (Questo consente al System Program di detrarre lamport.) Sia l'account del mittente che quello del destinatario devono essere scrivibili, per consentire la modifica del loro saldo in lamport. Per eseguire questa istruzione, il wallet del mittente invia la transazione contenente la sua firma e il messaggio contenente l'istruzione di trasferimento SOL.
Diagramma di trasferimento SOL
Dopo l'invio della transazione, il System Program elabora l'istruzione di trasferimento e aggiorna il saldo in lamport di entrambi gli account.
Diagramma del processo di trasferimento SOL
L'esempio seguente mostra il codice relativo ai diagrammi sopra. (Vedi l'istruzione di trasferimento del System Program instruction.)
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);
Console
Click to execute the code.
Istruzioni
Diagramma che rappresenta una transazione con un'istruzione, suddivisa nei suoi 3 componenti
Un
Instruction
consiste nelle seguenti informazioni:
program_id
: L'ID del programma che viene invocato.accounts
: Un array di metadati dell'accountdata
: Un array di byte con [dati] aggiuntivi da utilizzare dall'istruzione.
Instruction struct
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>,}
Program ID
L'program_id
dell'istruzione è
l'indirizzo della chiave pubblica del programma che contiene la logica di
business dell'istruzione.
Metadati dell'account
L'array accounts
dell'istruzione è un array di strutture
AccountMeta
.
Devono essere forniti metadati per ogni account con cui l'istruzione
interagisce. (Questo permette alla transazione di eseguire istruzioni in
parallelo, a condizione che non modifichino lo stesso account.)
Il diagramma seguente rappresenta una transazione che contiene una singola
istruzione. L'array accounts
dell'istruzione contiene metadati per due
account.
Una transazione con un'istruzione. L'istruzione contiene due strutture AccountMeta nel suo array accounts.
I metadati dell'account includono le seguenti informazioni:
- pubkey: L'indirizzo della chiave pubblica dell'account
- is_signer: Impostato su
true
se l'account deve firmare la transazione - is_writable: Impostato su
true
se l'istruzione modifica i dati dell'account
Per sapere quali account richiede un'istruzione, inclusi quelli che devono essere scrivibili, di sola lettura o firmare la transazione, devi fare riferimento all'implementazione dell'istruzione, come definita dal programma.
AccountMeta
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,}
Dati
Il data
dell'istruzione è un array di byte che specifica quale istruzione del
programma invocare. Include anche eventuali argomenti richiesti dall'istruzione.
Esempio di creazione di un'istruzione
L'esempio seguente mostra la struttura di un'istruzione di trasferimento di SOL.
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));
Console
Click to execute the code.
Il codice seguente mostra l'output degli snippet di codice precedenti. Il
formato sarà diverso tra i vari SDK, ma nota che ogni istruzione contiene gli
stessi tre elementi di informazione richiesti:
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}}
Gli esempi seguenti mostrano come costruire manualmente l'istruzione di
trasferimento. (La scheda Expanded Instruction
è funzionalmente equivalente
alla scheda Instruction
.)
In pratica, di solito non è necessario costruire manualmente un Instruction
.
La maggior parte dei programmi fornisce librerie client con funzioni di
supporto che creano le istruzioni per te. Se una libreria non è disponibile,
puoi costruire manualmente l'istruzione.
const transferAmount = 0.01; // 0.01 SOLconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount * LAMPORTS_PER_SOL});
Is this page helpful?