Anchor
Escrow avec Anchor

Escrow avec Anchor

75 Graduates

Escrow avec Anchor

Anchor Escrow Challenge

L'Escrow

Un escrow est un outil financier puissant qui permet des échanges sécurisés de jetons entre deux parties.

Imaginez un coffre-fort numérique où un utilisateur peut bloquer un jeton A en attendant qu'un autre utilisateur dépose un jeton B avant que l'échange ne soit terminé.

Cela crée un environnement sans confiance où aucune des parties n'a à craindre que l'autre ne revienne sur sa décision.

Dans ce challenge, nous allons mettre en œuvre ce concept à travers trois instructions simples mais puissantes :

  • Créer (Make) : Le créateur (premier utilisateur) définit les conditions de l'échange et dépose le montant convenu du jeton A dans un coffre-fort sécurisé (vault). C'est comme si vous mettiez votre objet dans un coffre-fort et que vous fixiez les conditions de l'échange.

  • Accepter (Take) : Le preneur (deuxième utilisateur) accepte l'offre en transférant le montant promis du jeton B au créateur, et reçoit en retour le jeton A verrouillé. C'est le moment où les deux parties complètent leur part du marché.

  • Rembourser (Refund) : Si le créateur change d'avis ou si aucun preneur n'est trouvé, il peut annuler l'offre et récupérer son jeton A. C'est comme si vous récupériez votre objet dans le coffre-fort si l'échange n'aboutit pas.

Remarque : Si vous n'êtes pas familier avec Anchor, vous devriez commencer par lire l'Introduction à Anchor pour vous familiariser avec les concepts de base que nous allons utiliser dans ce programme.

Installation

Commençons par créer un nouvel espace de travail Anchor :

anchor init blueshift_anchor_escrow
cd blueshift_anchor_escrow

Nous continuons ensuite en activant init-if-needed sur la crate anchor-lang et en ajoutant la crate anchor-spl :

cargo add anchor-lang --features init-if-needed
cargo add anchor-spl

Puisque nous utilisons anchor-spl, nous devons aussi mettre à jour le fichier Cargo.toml pour inclure anchor-spl/idl-build dans la fonctionnalité idl-build.

Ouvrez Cargo.toml et vous verrez une ligne idl-build déjà existante qui ressemble à ceci :

toml
idl-build = ["anchor-lang/idl-build"]

Modifiez-la pour ajouter anchor-spl/idl-build :

toml
idl-build = ["anchor-lang/idl-build", "anchor-spl/idl-build"]

Vous pouvez maintenant ouvrir le dossier précédemment créé et commencer à coder !

Modèle

Cette fois, puisque le programme est assez complexe, nous allons le diviser en petits modules spécifiques au lieu de tout mettre dans le lib.rs.

L'arborescence des dossiers se présente sensiblement comme suit :

text
src
├── instructions
│       ├── make.rs
│       ├── mod.rs
│       ├── refund.rs
│       └── take.rs
├── errors.rs
├── lib.rs
└── state.rs

Le fichier lib.rs ressemblera donc à peu près à ceci :

rust
use anchor_lang::prelude::*;

mod state;
mod errors;
mod instructions;
use instructions::*;

declare_id!("22222222222222222222222222222222222222222222");

#[program]
pub mod blueshift_anchor_escrow {
    use super::*;

    #[instruction(discriminator = 0)]
    pub fn make(ctx: Context<Make>, seed: u64, receive: u64, amount: u64) -> Result<()> {
        //...
    }

    #[instruction(discriminator = 1)]
    pub fn take(ctx: Context<Take>) -> Result<()> {
        //...
    }

    #[instruction(discriminator = 2)]
    pub fn refund(ctx: Context<Refund>) -> Result<()> {
        //...
    }
}

Comme vous le voyez, nous avons implémenté un discriminateur personnalisé pour les instructions. Veillez donc à utiliser Anchor version 0.31.0 ou plus récente.

État (State)

Nous allons nous rendre dans le fichier state.rs où se trouvent toutes les données de notre Escrow. Pour ce faire, nous allons lui donner un discriminateur personnalisé et envelopper la structure dans la macro #[account] comme ceci :

rust
use anchor_lang::prelude::*;

#[derive(InitSpace)]
#[account(discriminator = 1)]
  pub struct Escrow {
    pub seed: u64,
    pub maker: Pubkey,
    pub mint_a: Pubkey,
    pub mint_b: Pubkey,
    pub receive: u64,
    pub bump: u8,
}

Rôle de chaque champ :

  • seed: Nombre aléatoire utilisé lors du processus de dérivation des seeds pour qu'un créateur puisse ouvrir plusieurs escrows avec la même paire de jetons. Il est stocké on-chain pour que nous puissions toujours retrouver le PDA.

  • maker: Le portefeuille qui a créé l'escrow. Nécessaire pour le remboursement et pour recevoir les paiements.

  • mint_a & mint_b: Les adresses de mint pour pour les deux côtés de l'échange, celui de l'"offre" et celui de la "demande".

  • receive: La quantité de jeton B souhaitée par le créateur. (Le solde du vault indique déjà le montant du dépôt du jeton A, nous ne le stockons donc pas).

  • bump: Octet de saut mis en cache. Le dériver à chaque fois coûte des ressources, c'est pourquoi nous le sauvegardons une fois pour toutes.

Nous pourrions ajouter plus d'informations, mais des octets supplémentaires signifient une rente plus importante. En ne stockant que l'essentiel, les dépôts restent peu coûteux tout en permettant au programme d'appliquer toutes les règles dont il a besoin.

Nous terminons en ajoutant la macro #[derive(InitSpace)] afin de ne pas avoir à calculer manuellement la rente de cette structure.

Erreurs

Nous pouvons maintenant passer au fichier errors.rs où nous allons ajouter quelques erreurs que nous utiliserons plus tard :

rust
use anchor_lang::prelude::*;

#[error_code]
pub enum EscrowError {
    #[msg("Invalid amount")]
    InvalidAmount,
    #[msg("Invalid maker")]
    InvalidMaker,
    #[msg("Invalid mint a")]
    InvalidMintA,
    #[msg("Invalid mint b")]
    InvalidMintB,
}

Chaque enum correspond à un message clair et lisible par l'homme qu'Anchor affichera chaque fois qu'une contrainte ou un require !() échouera.

Next PageCréer
OU PASSER AU CHALLENGE
Prêt à relever le challenge ?
Blueshift © 2025Commit: e573eab