Passer au contenu principal

Comment créer et déployer un programme Leo sur Aleo

Mis à jour le
21 mai 2026

9 minutes de lecture

Aperçu

Dans le guide d'introduction, nous avons abordé l'architecture d'Aleo : exécution hors chaîne, vérification sur la chaîne et enregistrements en tant qu'état privé. Ce guide vous permettra de mettre ces concepts en pratique. Vous allez créer un jeton privé dans Leo, le tester, puis le déployer sur le Testnet d'Aleo via un point de terminaison Quicknode.

Le token que nous développons est volontairement simple : deux fonctions, aucun état public. Vous créez des tokens sous forme d'enregistrements chiffrés et les transférez de manière privée. Le réseau vérifie chaque transaction à l'aide d'une preuve à divulgation nulle de connaissance, mais ne voit jamais qui a envoyé les tokens, qui les a reçus, ni combien ont été transférés. C'est là l'argument de vente principal d'Aleo, et c'est ce vers quoi nous tendons ici.


En bref
  • Nous créons un jeton privé doté de deux fonctions : mint_private et transfert_privé
  • Toutes les données d'état sont stockées dans des enregistrements chiffrés ; ainsi, rien n'est visible sur la blockchain.
  • Tout le code utilise la syntaxe de Leo 4.0 : fn pour les fonctions, enregistrement pour les types d'état privés
  • Déployer sur le testnet Aleo via un point de terminaison Quicknode avec leo deploy --broadcast

Ce que vous allez apprendre

  • Comment écrire un programme Leo utilisant des enregistrements pour garantir un état entièrement privé
  • Comment effectuer un test avec @test annotations et test du Lion
  • Comment effectuer un déploiement sur le Testnet d'Aleo via déploiement Leo
  • Comment effectuer des transactions privées et comprendre ce qui est visible sur la blockchain (rien)

Ce dont vous aurez besoin

  • Connaissance des concepts présentés dans le guide « Introduction à Aleo et Leo »
  • Rouille 1.94.1 ou une version plus récente (Leo nécessite cette version. Exécutez Mise à jour de Rustup (à mettre à jour si nécessaire)
  • Un compte Quicknode avec un point de terminaison Aleo Testnet
  • Crédits ALEO du réseau de test provenant du « faucet » Aleo
  • Accès au terminal

Créer un point de terminaison Quicknode

Pour déployer des programmes et interagir avec eux sur le réseau Aleo, vous devez avoir accès à un point de terminaison RPC Aleo. Vous pourriez faire tourner votre propre nœud, mais Quicknode se charge de l'infrastructure à votre place.

Créez un compte Quicknode si ce n'est pas déjà fait. Une fois connecté, cliquez sur « Créer un point de terminaison », puis sélectionnez la chaîne Aleo et le réseau Testnet.

Point de terminaison Quicknode Aleo

Une fois le point de terminaison créé, copiez l'URL du fournisseur HTTP. Vous l'ajouterez ultérieurement à la configuration de votre projet.

note

Ajouter /v2 à la fin de l'URL de votre point de terminaison Quicknode. Leo ajoute le chemin d'accès réseau (/testnet/...) automatiquement lors des appels API, et les points de terminaison Aleo de Quicknode nécessitent le /v2 préfixe.

Configuration de l'environnement de développement

Installez le compilateur Leo via cargo :

cargo install leo-lang

Vérifiez l'installation :

leo --version

Mettre en place un nouveau projet :

leo new private_token
cd private_token

Cela crée la structure de projet suivante :

Fichier/RépertoireObjectif
src/main.leoLe code source de votre programme
tests/Fichiers de test avec @test fonctions annotées
program.jsonMétadonnées du projet : nom du programme, version, dépendances

Il vous faudra également un .env fichier de configuration du déploiement. Créez-en un à la racine du projet :

avertissement

Ajoutez l' .env à votre .gitignore. Ne placez jamais votre clé privée dans un système de gestion de versions.

touch .env

Ajoutez ce qui suit :

NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp... # generate one with: leo account new
ENDPOINT=https://your-quicknode-aleo-endpoint.quiknode.pro/your-auth-token/v2

Si vous ne disposez pas encore d'une clé privée, générez-en une à l'aide de Nouveau compte Leo et collez-le. Pour le point de terminaison, utilisez l'URL Quicknode que vous avez copiée précédemment avec /v2 en annexe.

Écriture du programme « Token »

Nous développons un jeton privé. Il n'y a pas de registre public des soldes, ni de mappage sur la chaîne que tout le monde peut consulter. Chaque jeton existe sous la forme d'un enregistrement crypté que seul son propriétaire peut voir. Lorsqu'une personne transfère des jetons, l'ancien enregistrement est supprimé et de nouveaux enregistrements sont créés, le tout hors chaîne. Le réseau ne voit qu'une preuve attestant que les règles ont été respectées.

Deux fonctions gèrent tout :

  • mint_private crée de nouveaux jetons sous la forme d'un enregistrement chiffré
  • transfert_privé transfère des jetons d'une adresse à une autre, en toute confidentialité

Remplacer le contenu de src/main.leo avec :

program private_token.aleo {

record Token {
owner: address,
amount: u64,
}

fn mint_private(receiver: address, amount: u64) -> Token {
return Token {
owner: receiver,
amount: amount,
};
}

fn transfer_private(sender: Token, receiver: address, amount: u64) -> (Token, Token) {
let difference: u64 = sender.amount - amount;

let remaining: Token = Token {
owner: sender.owner,
amount: difference,
};

let transferred: Token = Token {
owner: receiver,
amount: amount,
};

return (remaining, transferred);
}

@noupgrade
constructor() {}
}

Voyons ensemble ce qu'il y a ici :

enregistrer le jeton définit l'état privé. Chaque jeton est un enregistrement chiffré dans le registre, comportant un propriétaire et un montant. Seule la clé de consultation du propriétaire permet de le déchiffrer. Il n'existe pas de tableau public des soldes.

mint_private crée un nouveau Jeton enregistrement. Le processus se déroule entièrement hors chaîne. Le réseau vérifie la preuve, mais n'a jamais connaissance du destinataire ni du montant.

transfert_privé part d'un Jeton enregistre l'opération, la traite, puis génère deux nouveaux enregistrements : l'un pour le destinataire, indiquant le montant transféré, et l'autre pour l'expéditeur, indiquant le solde restant. Ce fonctionnement est similaire à celui du modèle UTXO de Bitcoin, à la différence près que tout est chiffré. Il n'y a pas de vérification explicite du solde, car les entiers Leo ne subissent pas de débordement vers le bas. Si montant de l'expéditeur - montant devienne négative, la transaction échoue automatiquement.

@noupgrade Le @noupgrade L'annotation verrouille le programme afin qu'il ne puisse plus être modifié après son déploiement. Pour les programmes pouvant être mis à jour, il faudrait plutôt écrire un constructeur intégrant la logique d'autorisation et utiliser Mise à jour de Leo pour publier de nouvelles versions

constructor() {} - Un constructeur est obligatoire pour tous les programmes Aleo.

Test du programme

Leo dispose d'un framework de test intégré. Les fonctions de test se trouvent dans le tests/ répertoire et utilisez la commande @test Annotation. Les fichiers de test sont eux-mêmes des programmes Leo ; ils nécessitent donc un programme bloc et un import pour le programme qu'ils testent.

Ouvrez le fichier existant tests/test_private_token.leo et remplacez son contenu par :

import private_token.aleo;

program test_private_token.aleo {

@test
fn test_mint_private() {
let receiver: address = aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc;
let result: private_token.aleo::Token = private_token.aleo::mint_private(receiver, 100u64);
assert_eq(result.owner, receiver);
assert_eq(result.amount, 100u64);
}

@test
fn test_transfer_private() {
let alice: address = self.signer;
let bob: address = aleo1qgqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqanmpl0;

let minted: private_token.aleo::Token = private_token.aleo::mint_private(alice, 100u64);
let (remaining, transferred): (private_token.aleo::Token, private_token.aleo::Token) = private_token.aleo::transfer_private(minted, bob, 30u64);

assert_eq(transferred.owner, bob);
assert_eq(transferred.amount, 30u64);
assert_eq(remaining.owner, alice);
assert_eq(remaining.amount, 70u64);
}

@test
@should_fail
fn test_transfer_more_than_balance() {
let alice: address = aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc;
let bob: address = aleo1qgqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqanmpl0;

let minted: private_token.aleo::Token = private_token.aleo::mint_private(alice, 50u64);
// This should fail: transferring 100 from a record with only 50
let (remaining, transferred): (private_token.aleo::Token, private_token.aleo::Token) = private_token.aleo::transfer_private(minted, bob, 100u64);
}

@noupgrade
constructor() {}
}

Exécutez les tests :

test du Lion

Résultats des tests Leo indiquant que 3 tests ont été réussis

Quelques remarques concernant le fichier de test :

  • import private_token.aleo; met le programme principal dans la portée
  • Les types et les fonctions utilisent le chemin d'accès complet : private_token.aleo::Token, private_token.aleo::mint_private()
  • Dans test_transfert_privé, nous utilisons signataire autonome comme adresse de frappe, car la machine virtuelle exige que les enregistrements d'entrée appartiennent au signataire de la transaction
  • @should_fail indique à Leo que le test devrait échouer. Si la fonction s'exécute sans erreur, c'est le test lui-même qui échoue
  • Tout programme (y compris les programmes de test) doit disposer d'un constructeur. Nous utilisons @noupgrade ici, pour que ce soit simple

Vous pouvez filtrer les tests par nom :

leo test mint

Cela ne lance que les tests dont le nom contient « mint ».

Déploiement sur le réseau de test Aleo

Maintenant que le programme se compile et que les tests sont réussis, il est temps de le déployer.

Obtenir des crédits Testnet

Rendez-vous sur le site Aleo Faucet et demandez des crédits Testnet pour l'adresse de votre compte.

Comment trouver votre adresse Aleo

Courir Importation d'un compte Leo avec la clé privée issue de votre .env:

leo account import APrivateKey1zkp...

Cela affiche votre adresse, votre clé publique et votre clé privée. Copiez l'adresse.

Choisissez un nom de programme

Le nom de votre programme doit être unique sur l'ensemble du réseau. Si private_token.aleo est déjà pris, modifiez le nom dans les deux src/main.leo et program.json. Les noms comportant moins de 10 caractères sont soumis à des frais d'espace de noms qui augmentent à mesure que la longueur du nom diminue, à l'instar des noms de domaine courts qui coûtent plus cher. Les noms comportant 10 caractères ou plus ne sont soumis à aucun frais d'espace de noms.

Déployer

leo deploy --broadcast

Leo vous présentera le détail des frais avant de vous demander votre confirmation :

Composante « frais »Ce qu'il couvre
Stockage1 millicrédit par octet de données de programme
SynthèseProportionnelle à la complexité du circuit (nombre_de_variables + nombre_de_contraintes)
Espace de nomsSupplément pour les noms de programmes de moins de 10 caractères (0 pour les noms de 10 caractères ou plus)
PrioritéConseil facultatif pour une inclusion plus rapide (valeur par défaut : 0)

Une fois la confirmation obtenue, Leo diffuse la transaction de déploiement et surveille le réseau pendant un maximum de 12 blocs afin de vérifier qu'elle a bien été intégrée.

Sortie de la commande « Leo deploy » affichant le détail des frais et la confirmation

Vous pouvez vérifier le déploiement dans Aleo Explorer.

Exécution de transactions privées

Maintenant que le programme est déployé, mettons-le en pratique. Chaque étape décrite ci-dessous s'exécute hors chaîne sur votre ordinateur ; le réseau ne voit qu'une preuve.

Jetons Mint

leo execute mint_private <RECEIVER_ADDRESS> 1000u64 --broadcast

Remplacez <RECEIVER_ADDRESS> avec votre adresse Aleo. Cela crée un Jeton Enregistrement chiffré destiné au destinataire. La transaction est enregistrée sur la blockchain, mais le contenu de l'enregistrement (propriétaire, montant) est chiffré. Personne qui observe la blockchain ne peut savoir ce qui a été émis ni à qui.

Leo affiche l'enregistrement de sortie après l'exécution. Voici à quoi cela ressemble :

{
owner: aleo1abc...def.private,
amount: 1000u64.private,
_nonce: 6068899261705353026606683251009719039686976057706338283793929594435531277185group.public,
_version: 1u8.public
}

Le propriétaire et montant les champs sont marqués .privé, ce qui signifie qu'ils sont chiffrés dans le registre. Enregistrez l'enregistrement complet, car vous devrez le transmettre en tant que paramètre d'entrée à transfert_privé.

Jetons de transfert

leo execute transfer_private "{ owner: aleo1abc...def.private, amount: 1000u64.private, _nonce: 6068...185group.public, _version: 1u8.public }" <RECEIVER_ADDRESS> 300u64 --broadcast

Remplacez l'enregistrement par la sortie complète de votre étape « mint », placée entre guillemets. L'ensemble du { owner: ..., amount: ..., _nonce: ..., _version: ... } Le bloc prend un seul argument. Il utilise votre enregistrement existant et en crée deux nouveaux : 300 jetons pour le destinataire et 700 pour vous (le montant mis à jour).

Voici ce que voit le réseau : une preuve valide. C'est tout. Ni adresse d'expéditeur, ni adresse de destinataire, ni montant. Les validateurs confirment que les calculs sont corrects sans savoir en quoi consistent ces calculs.

Ce qui est visible sur la blockchain

C'est là tout l'intérêt de l'opération. Voici ce qui s'affiche localement dans votre terminal une fois le transfert terminé :

Sortie CLI affichant les deux enregistrements de sortie et l'ID de transaction

Votre terminal affiche à la fois les enregistrements de transaction (300 jetons vers le destinataire, 700 jetons en retour vers vous) et un identifiant de transaction. Vous savez exactement ce qui s'est passé.

Reprenez maintenant cet identifiant de transaction et recherchez-le dans Aleo Explorer. L'onglet « Aperçu » confirme que la transaction a bien été enregistrée sur la blockchain :

Onglet « Aperçu » d'Aleo Explorer affichant l'identifiant de transaction

Le même identifiant de transaction, confirmé sur le réseau. Mais cliquez sur l'onglet « Transactions » :

Onglet « Transactions » d'Aleo Explorer affichant les entrées et les sorties chiffrées

Les entrées et les sorties sont chiffrées. Ni l'expéditeur, ni le destinataire, ni les montants ne sont identifiés. Les validateurs ont confirmé la validité de la preuve sans savoir en quoi consistait le transfert.

Comparez cela à un transfert standard de jetons EVM, où l'expéditeur, le destinataire, le montant et l'historique complet de la transaction sont accessibles à tous.

Conclusion

Nous sommes passés d'un projet à l'état brut à un jeton privé déployé sur le testnet d'Aleo. Le programme comporte deux fonctions : mint_private crée des jetons, transfert_privé les déplace. Toutes les données d'état sont stockées dans des enregistrements chiffrés. Aucune information concernant les soldes des jetons ou l'historique des transferts n'est visible sur la blockchain.

Il s'agit d'un exemple simplifié, mais il illustre le principe de base. Un jeton de production permettrait d'ajouter les soldes publics (à l'aide de mappages et final blocs), des fonctions de conversion permettant de passer du domaine public au domaine privé, ainsi que des contrôles d'accès à la création de pièces. Le guide d'introduction explique le fonctionnement des mappages et des blocs finaux si vous souhaitez aller plus loin.

Pour les appels inter-programmes, les Futures composés et d'autres modèles plus avancés, consultez la documentation pour les développeurs d'Aleo et le dépôt leo-examples.

Foire aux questions

Combien coûte le déploiement d'un programme Leo sur Aleo ?

Les frais de déploiement se composent de trois éléments : un coût de stockage de 1 millicrédit par octet de données de programme, un coût de synthèse proportionnel à la complexité du circuit (calculé en fonction du nombre de variables et de contraintes), et des frais liés à l'espace de noms pour les noms de programme de moins de 10 caractères. Les frais de priorité sont facultatifs et leur valeur par défaut est 0. L'interface en ligne de commande Leo vous présente le détail complet des coûts avant que vous ne confirmiez le déploiement.

Quelle est la différence entre « leo run » et « leo execute » ?

La commande « leo run » compile et exécute une fonction localement sans générer de preuve. Elle est utile pour effectuer des tests rapides pendant le développement. La commande « leo execute » effectue la même exécution locale, mais synthétise également le circuit et génère une preuve zk-SNARK, ce qui est nécessaire pour le déploiement et l'exécution sur la blockchain.

Puis-je mettre à jour un programme Leo déjà déployé sur Aleo ?

Oui, si le programme a été déployé en tant que programme pouvant être mis à jour, vous pouvez utiliser la commande « leo upgrade » pour déployer une nouvelle version. La mise à jour remplace le bytecode du programme sur la blockchain tout en conservant le même nom et la même adresse.

Pourquoi ne puis-je pas consulter le solde de mes jetons sur un explorateur de blocs ?

Les jetons privés utilisent des enregistrements, et non des mappages publics. Les enregistrements sont chiffrés dans le registre et seul leur propriétaire peut les déchiffrer à l'aide de sa clé de consultation. Les explorateurs de blocs ne peuvent afficher que l'état public (les mappages) ; les soldes des jetons privés leur sont donc invisibles. Vous ne pouvez consulter vos propres enregistrements qu'en local, via l'interface CLI de Leo.

Nous ❤️ les commentaires !

Faites-nous savoir si vous avez des commentaires ou des suggestions de nouveaux sujets. Nous serions ravis de vous entendre.

Partager ce guide