Initialement publié en anglais par StarkWare le 3 juillet, 2019
Il s'agit d'une version légèrement modifiée de ce que nous avons publié sur ethresearch.
Dans ce post, nous présentons un pattern de conception pour les smart-contracts, que nous appelons le pattern Fact Registry Contract, ou, simplement, Registry Contract. Ce pattern permet de séparer la vérification d'une déclaration de l'application qui repose sur sa validité.
L'idée est d'écrire un contrat séparé dont le seul but est de valider et d'enregistrer les éléments qui satisfont cette déclaration. Une déclaration est définie par un prédicat P(x, witness) qui reçoit un élément x et une information auxiliaire witness et renvoie soit True soit False. Nous appellerons x un fact, si un witness est connu de quelqu'un de telle sorte que P renvoie True.
Voici quelques exemples de déclarations :
La vérification des déclarations ci-dessus peut être requise dans le cadre d'un contrat d'application. La façon courante de traiter ces prédicats est d'écrire une fonction dans le contrat d'application et de passer witness dans calldata (les données d'appel) de la transaction.
Cependant, dans certains cas, une meilleure approche serait d'écrire un registry contract (contrat de registre) dédié. Un contrat de registre est un contrat qui maintient un ensemble de faits précédemment attestés (conservés sur le stockage d'Ethereum) et possède deux méthodes : add() et isValid(). La méthode add(fact, witness) ajoute le fait à l'ensemble, à condition que la déclaration soit valable. La méthode isValid(fact) renvoie simplement True si le fait est dans l'ensemble.
Dans de nombreux cas, la taille d'un fait (sans witness) est supérieure à 32 octets. Dans de tels cas, il est préférable de maintenir l'ensemble des hachages des faits précédemment témoignés, plutôt que les faits eux-mêmes.
Notez que si isValid(fact) renvoie True, cela implique que non seulement il existe un witness satisfaisant le prédicat, mais aussi qu'un tel witness a été présenté précédemment au contrat. En tant que telle, la méthode isValid() sert de preuve de connaissance (proof of knowledge).
L'utilisation d'un contrat de registre introduit plusieurs frais généraux par rapport à la solution monolithique consistant à utiliser une fonction dans le contrat d'application :
Lorsque le coût total (calcul et données d'appel) de la vérification de la déclaration est faible, l'utilisation de contrats de registre peut ajouter une surcharge non négligeable au coût du gas et, dans ce cas, la solution monolithique est préférable.
Cependant, lorsque le coût de la vérification est élevé, ces frais généraux deviennent négligeables et l'utilisation du pattern de conception proposé présente de nombreux avantages :
Développons plus en détail ce tout dernier avantage, que nous considérons comme ayant un énorme potentiel.
(Mise en lots avec les Preuves de connaissances Succintes)
Dans les exemples ci-dessus, le coût en gas de la validation des faits était additif, en ce sens que le coût en gas requis pour valider plusieurs faits était (approximativement) égal à la somme des coûts requis pour valider les faits séparément. Cependant, il existe des techniques qui réduisent la quantité de gas nécessaire pour valider (ou "vérifier", dans le jargon des systèmes de preuve) un lot de faits. Par exemple, les preuves succinctes de connaissance (comme les STARKs) permettent de prouver qu'un certain calcul a un résultat donné, avec un coût sous-linéaire dans la taille du calcul. En particulier, prouver de nombreux faits ensemble est moins cher que le coût total de la preuve de chaque fait séparément.
Considérons un contrat de registre pour merkleLeaf() mentionné ci-dessus. Si nous étendons la fonction add() pour obtenir un lot de nouveaux faits (c'est-à-dire une liste de paires (leaf, root)), nous pouvons vérifier leur validité en vérifiant une preuve succincte attestant du lot entier, au lieu de vérifier le chemin d'authentification pour chaque fait. Notez que les chemins d'authentification ne sont pas du tout transmis dans ce cas. Au fur et à mesure que le nombre de faits ajoutés à un lot augmente, le coût en gas amorti par fait diminue (dans les systèmes modernes de preuve succincte, le coût en gas nécessaire pour vérifier une preuve, à l'exclusion d'un petit coût linéaire nécessaire pour gérer l'entrée du public, augmente (poly-)logarithmiquement avec la taille du lot).
Les systèmes de preuve succincte ont un seuil d'efficacité : il y a un coût de calcul minimal associé à la vérification d'une preuve, et il n'est donc pas économiquement rationnel de générer des preuves pour des lots qui tombent en dessous d'une taille minimale. Ainsi, les contrats à faible bande passante ne peuvent pas utiliser ces mécanismes de mise en lots et bénéficier de leurs avantages. Les contrats de registre abaissent ce seuil d'efficacité en nous permettant de rassembler des faits provenant de différentes applications et de les placer dans un seul lot. De cette façon, les contrats à faible bande passante peuvent bénéficier de la participation à de tels lots, en économisant le gas nécessaire à la vérification des faits et en permettant ainsi des économies de scale.
Lior Goldberg & Michael Riabzev
StarkWare
Traduction faite par HoVa.