Le Registre de Faits
0x568B
June 21st, 2022

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.

Compression in the wild | Photo par Niklas Hamann sur Unsplash
Compression in the wild | Photo par Niklas Hamann sur Unsplash

Introduction

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 :

  1. isComposite(x, witness) renvoie True si et seulement si x est un nombre composite. Witness (témoin) est un diviseur de x.
  2. merkleLeaf((leaf, root), witness) renvoie True si et seulement si leaf est une feuille (leaf) dans un arbre de Merkle avec une racine root. Le witness est le chemin d'authentification pertinent dans l'arbre.
  3. signedText((text, public_key), witness) renvoie True si et seulement si text apparaît dans un document signé par public_key. Witness est un document contenant le texte ainsi que sa signature.

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).

Figure 1 : Le flux de données, divisé en phases. Dans la phase (1), le fait et le witness correspondant sont transmis au contrat de registre, qui vérifie la validité et ajoute le fait à l'ensemble. Dans la phase (2), lorsque le contrat d'application est invoqué, il appelle le contrat de registre pour vérifier la validité du fait.
Figure 1 : Le flux de données, divisé en phases. Dans la phase (1), le fait et le witness correspondant sont transmis au contrat de registre, qui vérifie la validité et ajoute le fait à l'ensemble. Dans la phase (2), lorsque le contrat d'application est invoqué, il appelle le contrat de registre pour vérifier la validité du fait.

Quand Utiliser les Contrats de Registre ?

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 :

  1. Une opération de stockage pour chaque fait validé, résultant de l'ajout du fait à l'ensemble on-chain.
  2. Transmettre les faits plusieurs fois : une fois pour le contrat de registre, et une fois pour chaque contrat d'application l'utilisant.
  3. Communication inter-contrat lors de l'interrogation du contrat de registre pour la validité des faits.

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 :

  1. Séparation nette entre le contrat d'application et le contrat de registre, y compris la possibilité de mettre à niveau l'un sans modifier l'autre.
  2. Répartir le coût du gas sur plusieurs transactions. Cette option est utile lorsque le coût du gas requis pour l'ensemble de l'opération est supérieur à la limite du block.
  3. Répartir le coût du gas entre différentes parties. Cela est utile lorsqu'une partie doit payer pour la vérification de la déclaration et qu'une autre partie doit payer pour le contrat d'application faisant référence au fait validé.
  4. Réutilisation d'un fait plusieurs fois (c'est-à-dire mise en cache), par différentes transactions dans un même contrat, ou par différents contrats.
  5. Economy of Scale : en utilisant un système de preuve succinct, tel que STARK, SNARK ou BulletProofs, il est possible de vérifier un lot de faits en utilisant beaucoup moins de gas que la quantité totale de gas nécessaire pour vérifier chaque fait séparément. Ainsi, différents contrats reposant sur la même déclaration (voire les mêmes données !) peuvent bénéficier d'économies de scale massives.

Développons plus en détail ce tout dernier avantage, que nous considérons comme ayant un énorme potentiel.

Batching with Succinct Proofs of Knowledge

(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.

Arweave TX
BYN0-OflxMfkRiXSzRmThcf_1WmNqGT7iXqp-Qfdw9s
Ethereum Address
0x568B12eBBE85521D2cd8a2C9B7a8EF3f48aa2d66
Content Digest
Pnm3zzQEoexc5pRqQxkCHv5kQmaXuAjB2b-XNvvN34c