Le paiement se fige pendant cinq secondes, puis, d’un geste un peu trop vif, je clique une deuxième fois. Pour les paiements classiques, on peut encore consulter deux opérations. Mais pour les transactions privées, où le montant et les participants sont dissimulés, sur quoi le réseau peut-il s’appuyer pour savoir que tu n’as pas dépensé deux fois le même argent ?
Je suis parti de cette question pour redécomposer le Phoenix de @Dusk . Il ne comptabilise pas les fonds comme un solde public : il les découpe en notes chiffrées, et inscrit l’engagement des notes dans un arbre de Merkle. Lors du spend, des preuves à divulgation nulle de connaissance prouvent que la note existe bien, qu’elle est contrôlée par l’utilisateur et que les entrées/sorties respectent la conservation, sans divulguer le montant précis ni les notes correspondantes.
Ce qui attrape le « double spend », c’est le nullifier. On peut le voir comme un marqueur d’invalidation unique laissé après l’utilisation d’une note. Le monde extérieur ne peut pas remonter à la note d’origine à partir de ce marqueur, mais le réseau peut vérifier si ce marqueur a déjà été observé. Si la même note est construite en deux transactions, elles entrent en conflit sur le même nullifier : les deux ne peuvent pas être valides simultanément.
La documentation actuelle de Dusk précise aussi : dans le mempool, lorsque des transactions Phoenix provoquent un conflit de nullifier, seule une nouvelle transaction dont le Gas est strictement plus élevé peut remplacer l’ancienne. Envoyer à nouveau en augmentant les frais, c’est donc peut-être remplacer un paiement, pas créer une nouvelle transaction. Mais une fois la transaction incluse dans un bloc accepté et exécutée, même si le contrat renvoie une erreur, les notes et le Gas associés sont consommés ; il faut encore attendre que le bloc soit « finalized » pour que ce soit vraiment une issue définitive.
Donc la cryptographie empêche que l’actif soit copié, mais le portefeuille doit quand même expliquer l’état des opérations : en attente, remplacée, exécution échouée et confirmation finale. Afficher simplement « échec » et laisser l’utilisateur réessayer encore et encore ne résout rien.
$DUSK, c’est le Gas et l’actif mis en garantie, mais ce n’est pas un argument pour garantir l’expérience produit. J’aimerais plutôt voir si le portefeuille peut afficher la relation de remplacement, la raison de la consommation des notes et l’état de finalité. La confidentialité peut masquer les détails, mais pas si la transaction a eu lieu.
#dusk $DUSK