Invocation inter-programmes

Dans cette section, le programme CRUD de la section PDA précédente est mis à jour en ajoutant des invocations inter-programmes (CPI), une fonctionnalité qui permet aux programmes Solana de s'invoquer mutuellement.

Ce tutoriel montre également comment les programmes peuvent "signer" pour les adresses dérivées de programme (PDA) lors de l'exécution d'invocations inter-programmes.

Les instructions update et delete nécessitent des modifications pour gérer les transferts de SOL entre les comptes en invoquant le System Program.

L'objectif de cette section comprend l'explication du processus d'implémentation des CPI dans un programme Solana en utilisant le framework Anchor, en s'appuyant sur les concepts de PDA explorés dans la section précédente. Pour plus de détails, consultez la page Invocation inter-programmes.

Pour référence, ce lien inclut le code final après avoir complété les sections PDA et CPI.

Le code de départ pour cette section inclut uniquement la section PDA complétée.

Mettre à jour l'instruction de mise à jour

Tout d'abord, le programme nécessite un mécanisme simple de "paiement pour mise à jour" en modifiant la structure Update et la fonction update.

Commencez par mettre à jour le fichier lib.rs pour importer les éléments du module system_program.

lib.rs
use anchor_lang::system_program::{transfer, Transfer};

Ensuite, mettez à jour la structure Update pour inclure un nouveau compte appelé vault_account. Ce compte, contrôlé par le programme, reçoit du SOL de la part d'un utilisateur lorsqu'il met à jour son compte de message.

lib.rs
#[account(
mut,
seeds = [b"vault", user.key().as_ref()],
bump,
)]
pub vault_account: SystemAccount<'info>,

Ensuite, ajoutez la logique CPI dans l'instruction update pour transférer 0,001 SOL du compte de l'utilisateur vers le compte coffre-fort.

lib.rs
let transfer_accounts = Transfer {
from: ctx.accounts.user.to_account_info(),
to: ctx.accounts.vault_account.to_account_info(),
};
let cpi_context = CpiContext::new(
ctx.accounts.system_program.to_account_info(),
transfer_accounts,
);
transfer(cpi_context, 1_000_000)?;

Reconstruisez le programme.

Terminal
$
build

Mettre à jour l'instruction de suppression

Ajoutez maintenant un mécanisme de "remboursement lors de la suppression" en modifiant la structure Delete et la fonction delete.

Tout d'abord, mettez à jour la structure Delete pour inclure le vault_account. Cela permet le transfert de tout SOL dans le vault vers l'utilisateur lorsqu'ils ferment leur compte de message.

lib.rs
#[account(
mut,
seeds = [b"vault", user.key().as_ref()],
bump,
)]
pub vault_account: SystemAccount<'info>,

Ajoutez également le system_program car le CPI pour le transfert nécessite d'invoquer le System Program.

lib.rs
pub system_program: Program<'info, System>,

Ensuite, ajoutez la logique CPI dans l'instruction delete pour transférer le SOL du compte coffre-fort vers le compte de l'utilisateur.

lib.rs
let user_key = ctx.accounts.user.key();
let signer_seeds: &[&[&[u8]]] =
&[&[b"vault", user_key.as_ref(), &[ctx.bumps.vault_account]]];
let transfer_accounts = Transfer {
from: ctx.accounts.vault_account.to_account_info(),
to: ctx.accounts.user.to_account_info(),
};
let cpi_context = CpiContext::new(
ctx.accounts.system_program.to_account_info(),
transfer_accounts,
).with_signer(signer_seeds);
transfer(cpi_context, ctx.accounts.vault_account.lamports())?;

Notez que _ctx: Context<Delete> devient ctx: Context<Delete> pour utiliser le contexte dans le corps de la fonction.

Reconstruisez le programme.

Terminal
$
build

Redéployer le programme

Après avoir effectué ces modifications, redéployez le programme mis à jour. Cela garantit que le programme modifié devient disponible pour les tests. Sur Solana, la mise à jour d'un programme nécessite simplement de déployer le programme avec le même ID de programme.

Assurez-vous que votre portefeuille Playground dispose de SOL sur le devnet. Obtenez du SOL devnet depuis le Faucet Solana.

Terminal
$
deploy

Mettre à jour le fichier de test

Ensuite, mettez à jour le fichier anchor.test.ts pour inclure le nouveau compte vault dans les instructions. Cela nécessite de dériver le PDA du vault et de l'inclure dans les appels d'instruction de mise à jour et de suppression.

Dériver le PDA du coffre-fort

Tout d'abord, ajoutez la dérivation du PDA du coffre-fort :

anchor.test.ts
const [vaultPda, vaultBump] = PublicKey.findProgramAddressSync(
[Buffer.from("vault"), wallet.publicKey.toBuffer()],
program.programId
);

Modifier le test de mise à jour

Ensuite, mettez à jour l'instruction de mise à jour pour inclure le vaultAccount

anchor.test.ts
const transactionSignature = await program.methods
.update(message)
.accounts({
messageAccount: messagePda,
vaultAccount: vaultPda
})
.rpc({ commitment: "confirmed" });

Modifier le test de suppression

Ensuite, mettez à jour l'instruction de suppression pour inclure le vaultAccount

anchor.test.ts
const transactionSignature = await program.methods
.delete()
.accounts({
messageAccount: messagePda,
vaultAccount: vaultPda
})
.rpc({ commitment: "confirmed" });

Relancer le test

Après avoir effectué ces modifications, exécutez les tests pour vous assurer que tout fonctionne comme prévu :

Terminal
$
test

Vous pouvez ensuite examiner les liens SolanaFM pour visualiser les détails de la transaction, où vous trouverez les CPI pour les instructions de transfert au sein des instructions de mise à jour et de suppression.

CPI de mise à jourCPI de mise à jour

CPI de suppressionCPI de suppression

Si vous rencontrez des erreurs, vous pouvez consulter le code final.

Prochaines étapes

Félicitations pour avoir terminé le guide de démarrage rapide Solana. Vous avez acquis une expérience pratique avec les concepts clés de Solana, notamment :

  • Récupération et lecture de données à partir des comptes
  • Construction et envoi de transactions
  • Déploiement et mise à jour des programmes Solana
  • Travail avec les adresses dérivées de programme (PDA)
  • Réalisation d'invocations inter-programmes (CPI)

Pour approfondir votre compréhension de ces concepts, consultez la documentation Concepts fondamentaux qui fournit des explications détaillées sur les sujets abordés dans ce guide.

Explorer plus d'exemples

Si vous préférez apprendre par l'exemple, consultez le Dépôt d'exemples de programmes pour une variété de programmes d'exemple.

Solana Playground offre une fonctionnalité pratique permettant d'importer ou de visualiser des projets en utilisant leurs liens GitHub. Par exemple, ouvrez ce lien Solana Playground pour voir le projet Anchor de ce dépôt Github.

Cliquez sur le bouton Import et entrez un nom de projet pour l'ajouter à votre liste de projets dans Solana Playground. Une fois qu'un projet est importé, toutes les modifications sont automatiquement sauvegardées et persistantes.

Is this page helpful?