Instructions

Les instructions sont l'élément fondamental pour interagir avec la blockchain Solana. Une instruction est essentiellement une fonction publique que tout utilisateur du réseau Solana peut appeler. Chaque instruction est utilisée pour effectuer une action spécifique. La logique d'exécution des instructions est stockée dans les programmes, où chaque programme définit son propre ensemble d'instructions. Pour interagir avec le réseau Solana, une ou plusieurs instructions sont ajoutées à une transaction et envoyées au réseau pour être traitées.

Exemple de transfert de SOL

Le diagramme ci-dessous montre comment les transactions et les instructions fonctionnent ensemble pour permettre aux utilisateurs d'interagir avec le réseau. Dans cet exemple, des SOL sont transférés d'un compte à un autre.

Les métadonnées du compte émetteur indiquent qu'il doit signer la transaction. (Cela permet au System Program de déduire des lamports.) Les comptes émetteur et destinataire doivent être modifiables, afin que leur solde en lamports puisse changer. Pour exécuter cette instruction, le portefeuille de l'émetteur envoie la transaction contenant sa signature et le message contenant l'instruction de transfert de SOL.

Diagramme de transfert SOLDiagramme de transfert SOL

Après l'envoi de la transaction, le System Program traite l'instruction de transfert et met à jour le solde en lamports des deux comptes.

Diagramme du processus de transfert SOLDiagramme du processus de transfert SOL

L'exemple ci-dessous montre le code pertinent pour les diagrammes ci-dessus. (Voir l'instruction de transfert du System Program.)

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 cluster
const rpc = createSolanaRpc("http://localhost:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");
// Generate sender and recipient keypairs
const 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 airdrop
await airdropFactory({ rpc, rpcSubscriptions })({
recipientAddress: sender.address,
lamports: lamports(LAMPORTS_PER_SOL), // 1 SOL
commitment: "confirmed"
});
// Check balance before transfer
const { 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 recipient
const transferInstruction = getTransferSolInstruction({
source: sender,
destination: recipient.address,
amount: transferAmount // 0.01 SOL in lamports
});
// Add the transfer instruction to a new transaction
const { 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 network
const signedTransaction =
await signTransactionMessageWithSigners(transactionMessage);
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(
signedTransaction,
{ commitment: "confirmed" }
);
const transactionSignature = getSignatureFromTransaction(signedTransaction);
// Check balance after transfer
const { 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.

Instructions

Diagramme représentant une transaction avec une instruction, décomposée en ses 3 composantsDiagramme représentant une transaction avec une instruction, décomposée en ses 3 composants

Une Instruction contient les informations suivantes :

  • program_id : L'ID du programme invoqué.
  • accounts : Un tableau de métadonnées de compte
  • data : Un tableau d'octets avec des [données] supplémentaires à utiliser par l'instruction.
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

Le program_id de l'instruction est l'adresse de clé publique du programme qui contient la logique métier de l'instruction.

Métadonnées de compte

Le tableau accounts de l'instruction est un tableau de structures AccountMeta. Des métadonnées doivent être fournies pour chaque compte avec lequel l'instruction interagit. (Cela permet aux transactions d'exécuter des instructions en parallèle, tant qu'elles ne modifient pas le même compte.)

Le diagramme ci-dessous représente une transaction qui contient une seule instruction. Le tableau accounts de l'instruction contient des métadonnées pour deux comptes.

Une transaction avec une instruction. L'instruction contient deux structures AccountMeta dans son tableau accounts.Une transaction avec une instruction. L'instruction contient deux structures AccountMeta dans son tableau accounts.

Les métadonnées du compte comprennent les informations suivantes :

  • pubkey : L'adresse de clé publique du compte
  • is_signer : Défini sur true si le compte doit signer la transaction
  • is_writable : Défini sur true si l'instruction modifie les données du compte

Pour savoir quels comptes une instruction requiert, y compris lesquels doivent être modifiables, en lecture seule, ou signer la transaction, vous devez vous référer à l'implémentation de l'instruction, telle que définie par le programme.

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,
}

Données

Le data de l'instruction est un tableau d'octets qui spécifie laquelle des instructions du programme invoquer. Il inclut également tous les arguments requis par l'instruction.

Exemple de création d'instruction

L'exemple ci-dessous montre la structure d'une instruction de transfert de SOL.

import { generateKeyPairSigner, lamports } from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";
// Generate sender and recipient keypairs
const sender = await generateKeyPairSigner();
const recipient = await generateKeyPairSigner();
// Define the amount to transfer
const 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 recipient
const transferInstruction = getTransferSolInstruction({
source: sender,
destination: recipient.address,
amount: transferAmount
});
console.log(JSON.stringify(transferInstruction, null, 2));
Console
Click to execute the code.

Le code ci-dessous montre la sortie des extraits de code précédents. Le format diffère selon les SDK, mais remarquez que chaque instruction contient les trois mêmes éléments d'information requis : 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
}
}

Les exemples ci-dessous montrent comment construire manuellement l'instruction de transfert. (L'onglet Expanded Instruction est fonctionnellement équivalent à l'onglet Instruction)

En pratique, vous n'avez généralement pas besoin de construire une Instruction manuellement. La plupart des programmes fournissent des bibliothèques client avec des fonctions d'aide qui créent les instructions pour vous. Si une bibliothèque n'est pas disponible, vous pouvez construire manuellement l'instruction.

const transferAmount = 0.01; // 0.01 SOL
const transferInstruction = getTransferSolInstruction({
source: sender,
destination: recipient.address,
amount: transferAmount * LAMPORTS_PER_SOL
});

Is this page helpful?

Table des matières

Modifier la page

Géré par

© 2025 Fondation Solana.
Tous droits réservés.
Restez connecté