Applications décentralisées (DApps)

Bannière Amazon du livre Maîtriser Ethereum

Dans ce chapitre, nous allons explorer le monde des applications décentralisées, ou DApps. Dès les premiers jours d’Ethereum, la vision des fondateurs était bien plus large que les "contrats intelligents" : rien de moins que de réinventer le web et de créer un nouveau monde de DApps, appelé à juste titre web3. Les contrats intelligents sont un moyen de décentraliser la logique de contrôle et les fonctions de paiement des applications. Les DApps Web3 consistent à décentraliser tous les autres aspects d’une application : stockage, messagerie, nommage, etc. (voir Web3 : Un web décentralisé utilisant des contrats intelligents et des technologies P2P).

Web3 : un Web décentralisé utilisant des contrats intelligents et les technologies P2P
Figure 1. Web3 : Un web décentralisé utilisant des contrats intelligents et des technologies P2P
Warning

Alors que les "applications décentralisées" sont une vision audacieuse de l’avenir, le terme "DApp" est souvent appliqué à tout contrat intelligent avec une interface Web. Certaines de ces soi-disant DApps sont des applications hautement centralisées (CApps ?). Méfiez-vous des faux DApps !

Dans ce chapitre, nous allons développer et déployer un exemple de DApp : une plateforme d’enchères. Vous pouvez trouver le code source dans le référentiel du livre sous code/auction_dapp. Nous examinerons chaque aspect d’une application d’enchères et verrons comment nous pouvons décentraliser l’application autant que possible. Cependant, examinons d’abord de plus près les caractéristiques et les avantages déterminants des DApps.

Qu’est-ce qu’un DApp ?

Une DApp est une application qui est principalement ou entièrement décentralisée.

Considérez tous les aspects possibles d’une application qui peut être décentralisée :

  • Logiciel dorsale (logique d’application)

  • Logiciel frontal

  • Stockage de données

  • Communications par messages

  • Résolution de nom

Chacun d’eux peut être quelque peu centralisé ou quelque peu décentralisé. Par exemple, une interface peut être développée comme une application Web qui s’exécute sur un serveur centralisé ou comme une application mobile qui s’exécute sur votre appareil. Le backend et le stockage peuvent être sur des serveurs privés et des bases de données propriétaires, ou vous pouvez utiliser un contrat intelligent et un stockage P2P.

La création d’une DApp présente de nombreux avantages qu’une architecture centralisée typique ne peut pas offrir :

Élasticité

Parce que la logique applicative est contrôlée par un contrat intelligent, une DApp dorsale sera entièrement distribué et géré sur une plateforme chaîne de blocs. Contrairement à une application déployée sur un serveur centralisé, une DApp n’aura pas de temps d’arrêt et restera disponible tant que la plateforme fonctionnera.

Transparence

La nature en chaîne d’une DApp permet à chacun d’inspecter le code et d’être plus sûr de sa fonction. Toute interaction avec la DApp sera stockée pour toujours dans la chaîne de blocs.

Résistance à la censure

Tant qu’un utilisateur a accès à un nœud Ethereum (en exécutant un si nécessaire), l’utilisateur pourra toujours interagir avec une DApp sans interférence de tout contrôle centralisé. Aucun fournisseur de services, ni même le propriétaire du contrat intelligent, ne peut modifier le code une fois qu’il est déployé sur le réseau.

Dans l’écosystème Ethereum tel qu’il se présente aujourd’hui, il existe très peu d’applications véritablement décentralisées, la plupart reposant encore sur des services et des serveurs centralisés pour une partie de leur fonctionnement. À l’avenir, nous prévoyons qu’il sera possible pour chaque partie de n’importe quelle DApp d’être exploitée de manière entièrement décentralisée.

Environnement dorsale (contrat intelligent)

Dans une DApp, les contrats intelligents sont utilisés pour stocker la logique applicative (code de programme) et l’état correspondant de votre application. Vous pouvez penser à un contrat intelligent remplaçant un composant côté serveur (alias "backend" ou "environnement dorsale") dans une application standard. C’est une simplification excessive, bien sûr. L’une des principales différences est que tout calcul exécuté dans un contrat intelligent est très coûteux et doit donc être réduit au minimum. Il est donc important d’identifier les aspects de l’application qui nécessitent une plateforme d’exécution fiable et décentralisée.

Les contrats intelligents Ethereum vous permettent de créer des architectures dans lesquelles un réseau de contrats intelligents appellent et transmettent des données entre eux, lisant et écrivant leurs propres variables d’état au fur et à mesure, leur complexité n’étant limitée que par la limite de gaz de bloc. Après avoir déployé votre contrat intelligent, votre logique applicative pourrait bien être utilisée par de nombreux autres développeurs à l’avenir.

L’une des principales considérations de la conception d’une architecture de contrat intelligent est l’impossibilité de modifier le code d’un contrat intelligent une fois qu’il est déployé. Il peut être supprimé s’il est programmé avec un opcode SELFDESTRUCT accessible, mais à part une suppression complète, le code ne peut en aucun cas être modifié.

La deuxième considération majeure de la conception de l’architecture des contrats intelligents est la taille du DApp. Un très gros contrat intelligent monolithique peut coûter beaucoup de gaz à déployer et à utiliser. Par conséquent, certaines applications peuvent choisir d’avoir un calcul hors chaîne et une source de données externe. Gardez à l’esprit, cependant, que le fait que la logique applicative de base de la DApp dépende de données externes (par exemple, à partir d’un serveur centralisé) signifie que vos utilisateurs devront faire confiance à ces ressources externes.

Environnement frontale (interface utilisateur Web)

Contrairement à la logique applicative de la DApp, qui nécessite qu’un développeur comprenne l’EVM et de nouveaux langages comme Solidity, l’interface côté client d’une DApp peut utiliser des technologies web standards (HTML, CSS, JavaScript, etc.). Cela permet à un développeur Web traditionnel d’utiliser des outils, des bibliothèques et des frameworks familiers. Les interactions avec Ethereum, telles que la signature de messages, l’envoi de transactions et la gestion de clés, sont souvent effectuées via le navigateur Web, via une extension telle que MetaMask (voir [intro_chapter]).

Bien qu’il soit également possible de créer un DApp mobile, il existe actuellement peu de ressources pour aider à créer des interfaces DApp mobiles, principalement en raison du manque de clients mobiles pouvant servir de client léger avec une fonctionnalité de gestion des clés.

L’interface est généralement liée à Ethereum via la bibliothèque JavaScript web3.js, qui est fournie avec les ressources de l’interface et servie à un navigateur par un serveur Web.

Stockage de données

En raison des coûts élevés du gaz et de la limite de gaz actuellement faible, les contrats intelligents ne sont pas bien adapté au stockage ou au traitement de grandes quantités de données. Par conséquent, la plupart des DApps utilisent des services de stockage de données hors chaîne, ce qui signifie qu’ils stockent les données volumineuses de la chaîne Ethereum, sur une plate-forme de stockage de données. Cette plate-forme de stockage de données peut être centralisée (par exemple, une base de données cloud typique), ou les données peuvent être décentralisées, stockées sur une plate-forme P2P telle que l’IPFS ou la propre plate-forme Swarm d’Ethereum.

Le stockage P2P décentralisé est idéal pour stocker et distribuer de gros actifs statiques tels que des images, des vidéos et les ressources de l’interface Web frontale de l’application (HTML, CSS, JavaScript, etc.). Nous examinerons ensuite quelques-unes des options.

IPFS

Le Inter-Planetary File System (IPFS) est un système de stockage décentralisé adressable par le contenu qui distribue les objets stockés entre pairs dans un réseau P2P. "Contenu adressable" signifie que chaque élément de contenu (fichier) est haché et que le hachage est utilisé pour identifier ce fichier. Vous pouvez ensuite récupérer n’importe quel fichier de n’importe quel nœud IPFS en le demandant par son hachage.

IPFS vise à remplacer HTTP comme protocole de choix pour la livraison d’applications Web. Au lieu de stocker une application Web sur un seul serveur, les fichiers sont stockés sur IPFS et peuvent être récupérés à partir de n’importe quel nœud IPFS.

Plus d’informations sur IPFS peuvent être trouvées sur https://ipfs.io.

Swarm

Swarm est un autre système de stockage P2P adressable par le contenu , similaire à IPFS. Swarm a été créé par la Fondation Ethereum, dans le cadre de la suite d’outils Go-Ethereum. Comme IPFS, il vous permet de stocker des fichiers qui sont diffusés et répliqués par les nœuds Swarm. Vous pouvez accéder à n’importe quel fichier Swarm en y faisant référence par un hachage. Swarm vous permet d’accéder à un site Web à partir d’un système P2P décentralisé, au lieu d’un serveur Web central.

La page d’accueil de Swarm est elle-même stockée sur Swarm et accessible sur votre nœud Swarm ou une passerelle : https://swarm-gateways.net/bzz:/theswarm.eth/.

Protocoles de communication de messages décentralisés

Un autre composant majeur de toute application est la communication inter-processus. Cela signifie pouvoir échanger des messages entre applications, entre différentes instances de l’application ou entre utilisateurs de l’application. Traditionnellement, cela est réalisé en s’appuyant sur un serveur centralisé. Cependant, il existe une variété d’alternatives décentralisées aux protocoles basés sur serveur, offrant une messagerie sur un réseau P2P. Le protocole de messagerie P2P le plus notable pour les DApps est Whisper, qui fait partie de la suite d’outils Go-Ethereum de la Fondation Ethereum.

Le dernier aspect d’une application qui peut être décentralisée est la résolution de noms. Nous examinerons de près le service de noms d’Ethereum plus loin dans ce chapitre ; maintenant, cependant, montrons un exemple.

Un exemple de DApp de base : DApp d’enchères

Dans cette section, nous allons commencer à construire un exemple de DApp, pour explorer les différents outils de décentralisation. Notre DApp mettra en place une enchère décentralisée.

La DApp d’enchères permet à un utilisateur d’enregistrer un jeton "acte", qui représente un actif unique, comme une maison, une voiture, une marque, etc. Une fois qu’un jeton a été enregistré, la propriété du jeton est transférée à la DApp d’enchères, ce qui lui permet d’être mis en vente. Le DApp d’enchères répertorie chacun des jetons enregistrés, permettant aux autres utilisateurs de placer des offres. Au cours de chaque enchère, les utilisateurs peuvent rejoindre une salle de discussion créée spécifiquement pour cette enchère. Une fois qu’une enchère est finalisée, la propriété du jeton d’acte est transférée au gagnant de l’enchère.

Le processus global d’enchères peut être vu dans Auction DApp : un exemple simple de DApp d’enchères.

Les principaux composants de notre DApp d’enchères sont :

  • Un contrat intelligent implémentant des jetons "acte" non fongibles ERC721 (DeedRepository)

  • Un contrat intelligent mettant en place une enchère (AuctionRepository)pour vendre les actes

  • Une interface web utilisant le cadre de développement JavaScript Vue/Vuetify

  • La bibliothèque web3.js pour se connecter aux chaînes Ethereum (via MetaMask ou d’autres clients)

  • Un client Swarm, pour stocker des ressources telles que des images

  • Un client Whisper, pour créer des salons de discussion par enchère pour tous les participants

DApp d’enchères : un exemple simple de DApp d’enchères
Figure 2. Auction DApp : un exemple simple de DApp d’enchères

Vous pouvez trouver le code source de la DApp d’enchères dans le référentiel du livre.

DApp d’enchères : contrats intelligents dorsaux

Notre exemple Auction DApp est pris en charge par deux contrats intelligents que nous devons déployer sur une chaîne de blocs Ethereum afin de prendre en charge l’application : AuctionRepository et DeedRepository.

Commençons par regarder DeedRepository, montré dans DeedRepository.sol : un jeton d’acte ERC721 à utiliser dans une vente aux enchères. Ce contrat est un jeton non fongible compatible ERC721 (voir [erc721]).

Example 1. DeedRepository.sol : un jeton d’acte ERC721 à utiliser dans une vente aux enchères
pragma solidity ^0.5.16;
import "./ERC721/ERC721Token.sol";

/**
 * @title Repository of ERC721 Deeds
 * This contract contains the list of deeds registered by users.
 * This is a demo to show how tokens (deeds) can be minted and added 
 * to the repository.
 */
contract DeedRepository is ERC721Token {


    /**
    * @dev Created a DeedRepository with a name and symbol
    * @param _name string represents the name of the repository
    * @param _symbol string represents the symbol of the repository
    */
    constructor(string memory _name, string memory _symbol) 
        public ERC721Token(_name, _symbol) {}
    
    /**
    * @dev Public function to register a new deed
    * @dev Call the ERC721Token minter
    * @param _tokenId uint256 represents a specific deed
    * @param _uri string containing metadata/uri
    */
    function registerDeed(uint256 _tokenId, string memory _uri) public {
        _mint(msg.sender, _tokenId);
        addDeedMetadata(_tokenId, _uri);
        emit DeedRegistered(msg.sender, _tokenId);
    }

    /**
    * @dev Public function to add metadata to a deed
    * @param _tokenId represents a specific deed
    * @param _uri text which describes the characteristics of a given deed
    * @return whether the deed metadata was added to the repository
    */
    function addDeedMetadata(uint256 _tokenId, string memory _uri) public returns(bool){
        _setTokenURI(_tokenId, _uri);
        return true;
    }

    /**
    * @dev Event is triggered if deed/token is registered
    * @param _by address of the registrar
    * @param _tokenId uint256 represents a specific deed
    */
    event DeedRegistered(address _by, uint256 _tokenId);
}

Comme vous pouvez le constater, le contrat DeedRepository est une implémentation simple d’un jeton compatible ERC721.

Notre DApp d’enchères utilise le contrat DeedRepository pour émettre et suivre les jetons pour chaque enchère. L’enchère elle-même est orchestrée par le contrat AuctionRepository. Ce contrat est trop long pour être inclus ici dans son intégralité, mais AuctionRepository.sol : le principal contrat intelligent Auction DApp montre la définition principale du contrat et des structures de données. L’intégralité du contrat est disponible dans le référentiel GitHub du livre.

Example 2. AuctionRepository.sol : le principal contrat intelligent Auction DApp
contract AuctionRepository {

    // Tableau avec toutes les enchères
    Auction[] public auctions;

    // Mappage de l'index d'enchères aux offres des utilisateurs
    mapping(uint256 => Bid[]) public auctionBids;

    // Mappage du propriétaire à une liste d'enchères détenues
    mapping(address => uint[]) public auctionOwner;

    // Structure d'enchères pour retenir l'enchérisseur et le montant
    struct Bid {
        address from;
        uint256 amount;
    }

    // Structure d'enchères contenant toutes les informations requises
    struct Auction {
        string name;
        uint256 blockDeadline;
        uint256 startPrice;
        string metadata;
        uint256 deedId;
        address deedRepositoryAddress;
        address owner;
        bool active;
        bool finalized;
    }

Le contrat AuctionRepository gère toutes les enchères avec les fonctions suivantes :

getCount()
getBidsCount(uint _auctionId)
getAuctionsOf(address _owner)
getCurrentBid(uint _auctionId)
getAuctionsCountOfOwner(address _owner)
getAuctionById(uint _auctionId)
createAuction(address _deedRepositoryAddress, uint256 _deedId,
              string _auctionTitle, string _metadata, uint256 _startPrice,
              uint _blockDeadline)
approveAndTransfer(address _from, address _to, address _deedRepositoryAddress,
                   uint256 _deedId)
cancelAuction(uint _auctionId)
finalizeAuction(uint _auctionId)
bidOnAuction(uint _auctionId)

Vous pouvez déployer ces contrats sur la chaîne de blocs Ethereum de votre choix (par exemple, Ropsten) en utilisant truffle dans le référentiel du livre :

$ cd code/auction_dapp/backend
$ truffle init
$ truffle compile
$ truffle migrate --network ropsten

DApp de gouvernance

Si vous lisez les deux contrats intelligents de la DApp d’enchères, vous remarquerez quelque chose d’important : il n’y a pas de compte ou de rôle spécial qui dispose de privilèges spéciaux sur la DApp. Chaque enchère a un propriétaire avec des capacités spéciales, mais la DApp d’enchères elle-même n’a pas d’utilisateur privilégié.

Il s’agit d’un choix délibéré de décentraliser la gouvernance de la DApp et de renoncer à tout contrôle une fois celle-ci déployée. Certains DApp, en comparaison, ont un ou plusieurs comptes privilégiés avec des capacités spéciales, telles que la possibilité de résilier le contrat DApp, de remplacer ou de modifier sa configuration, ou d’opposer son veto à certaines opérations. Habituellement, ces fonctions de gouvernance sont introduites dans la DApp afin d’éviter des problèmes inconnus qui pourraient survenir en raison d’un bogue.

La question de la gouvernance est particulièrement difficile à résoudre car elle représente une arme à double tranchant. D’un côté, les comptes privilégiés sont dangereux ; s’ils sont compromis, ils peuvent compromettre la sécurité du DApp. De l’autre côté, sans compte privilégié, il n’y a pas d’options de récupération si un bogue est trouvé. Nous avons vu ces deux risques se manifester dans les DApp Ethereum. Dans le cas de The DAO ([real_world_example_the_dao] et [ethereum_fork_history]), il y avait des comptes privilégiés appelés les "conservateurs", mais ils étaient très limités dans leurs capacités. Ces comptes n’ont pas pu annuler le retrait des fonds par l’attaquant DAO. Dans un cas plus récent, l’échange décentralisé Bancor a subi un vol massif parce qu’un compte de gestion privilégié a été compromis. Il s’avère que Bancor n’était pas aussi décentralisé qu’on le supposait initialement.

Lors de la construction d’une DApp, vous devez décider si vous voulez rendre les contrats intelligents vraiment indépendants, les lancer et n’avoir ensuite aucun contrôle, ou créer des comptes privilégiés et courir le risque que ceux-ci soient compromis. L’un ou l’autre choix comporte des risques, mais à long terme, les vraies DApps ne peuvent pas avoir un accès spécialisé pour les comptes privilégiés - ce n’est pas décentralisé.

DApp d’enchères : interface utilisateur frontale

Une fois les contrats de la DApp d’enchères déployés, vous pouvez interagir avec eux à l’aide de votre console JavaScript préférée et de web3.js, ou d’une autre bibliothèque web3. Cependant, la plupart des utilisateurs auront besoin d’une interface facile à utiliser. Notre interface utilisateur de la DApp d’enchères est construite à l’aide du cadre de développement (framework) JavaScript Vue2/Vuetify de Google.

Vous pouvez trouver le code de l’interface utilisateur dans le dossier code/auction_dapp/frontend dans https://github.com/ethereumbook/ethereumbook [le référentiel du livre]. Le répertoire a la structure et le contenu suivants :

frontend/
|-- build
|   |-- build.js
|   |-- check-versions.js
|   |-- logo.png
|   |-- utils.js
|   |-- vue-loader.conf.js
|   |-- webpack.base.conf.js
|   |-- webpack.dev.conf.js
|   `-- webpack.prod.conf.js
|-- config
|   |-- dev.env.js
|   |-- index.js
|   `-- prod.env.js
|-- index.html
|-- package.json
|-- package-lock.json
|-- README.md
|-- src
|   |-- App.vue
|   |-- components
|   |   |-- Auction.vue
|   |   `-- Home.vue
|   |-- config.js
|   |-- contracts
|   |   |-- AuctionRepository.json
|   |   `-- DeedRepository.json
|   |-- main.js
|   |-- models
|   |   |-- AuctionRepository.js
|   |   |-- ChatRoom.js
|   |   `-- DeedRepository.js
|   `-- router
|       `-- index.js

Une fois que vous avez déployé les contrats, modifiez la configuration du frontend dans frontend/src/config.js et entrez les adresses des contrats DeedRepository et AuctionRepository, tels que déployés. L’application frontale a également besoin d’accéder à un nœud Ethereum offrant une interface JSON-RPC et WebSockets. Une fois que vous avez configuré l’interface, lancez-la avec un serveur Web sur votre machine locale :

$ npm install
$ npm run dev

L’interface Auction DApp sera lancée et sera accessible via n’importe quel navigateur Web à l’adresse http://localhost:8080.

Si tout se passe bien, vous devriez voir l’écran affiché dans Interface utilisateur de la DApp d’enchères, qui illustre l’exécution de la DApp d’enchères dans un navigateur Web.

Interface utilisateur de la DApp d’enchères
Figure 3. Interface utilisateur de la DApp d’enchères

Décentraliser davantage la DApp d’enchères

Notre DApp est déjà assez décentralisé, mais nous pouvons améliorer les choses.

Le contrat AuctionRepository fonctionne indépendamment de tout contrôle, ouvert à tous. Une fois déployé, il ne peut pas être arrêté, et aucune enchère ne peut être contrôlée. Chaque enchère a une salle de chat séparée qui permet à quiconque de communiquer sur l’enchère sans censure ni identification. Les différents actifs d’enchères, tels que la description et l’image associée, sont stockés sur Swarm, ce qui les rend difficiles à censurer ou à bloquer.

N’importe qui peut interagir avec la DApp en créant des transactions manuellement ou en exécutant l’interface Vue sur sa machine locale. Le code de la DApp lui-même est à source libre et développé en collaboration sur un référentiel public.

Il y a deux choses que nous pouvons faire pour rendre cette DApp décentralisée et résiliente :

  • Stockez tout le code d’application sur Swarm ou IPFS.

  • Accédez au DApp par référence à un nom, en utilisant le service de nom Ethereum.

Nous explorerons la première option dans la section suivante, et nous approfondirons la seconde dans Le service de noms Ethereum (ENS).

Stockage de la DApp d’enchères sur Swarm

Nous avons introduit Swarm dans Swarm, plus haut dans ce chapitre. Notre DApp d’enchères utilise déjà Swarm pour stocker l’image de l’icône pour chaque enchère. C’est une solution beaucoup plus efficace que de tenter de stocker des données sur Ethereum, ce qui coûte cher. Il est également beaucoup plus résistant que si ces images étaient stockées dans un service centralisé comme un serveur Web ou un serveur de fichiers.

Mais on peut aller plus loin. Nous pouvons stocker l’intégralité de l’interface du DApp lui-même dans Swarm et l’exécuter directement à partir d’un nœud Swarm, au lieu d’exécuter un serveur Web.

Préparation de Swarm

Pour commencer, vous devez installer Swarm et initialiser votre nœud Swarm. Swarm fait partie de la suite d’outils Go-Ethereum de la Fondation Ethereum. Reportez-vous aux instructions d’installation de Go-Ethereum dans [go_ethereum_geth], ou pour installer une version binaire Swarm, suivez les instructions de la documentation Swarm.

Une fois que vous avez installé Swarm, vous pouvez vérifier qu’il fonctionne correctement en le lançant avec la commande version :

$ swarm version
Version: 0.3
Git Commit: 37685930d953bcbe023f9bc65b135a8d8b8f1488
Go Version: go1.10.1
OS: linux

Pour commencer à exécuter Swarm, vous devez lui dire comment se connecter à une instance de Geth, pour accéder à l’API JSON-RPC. Commencez en suivant les instructions du Guide de démarrage.

Lorsque vous démarrez Swarm, vous devriez voir quelque chose comme ceci :

Maximum peer count                       ETH=25 LES=0 total=25
Starting peer-to-peer node               instance=swarm/v0.3.1-225171a4/linux...
connecting to ENS API                    url=http://127.0.0.1:8545
swarm[5955] : [189B blob data]
Starting P2P networking
UDP listener up                          self=enode://f50c8e19ff841bcd5ce7d2d...
Updated bzz local addr                   oaddr=9c40be8b83e648d50f40ad3... uaddr=e
Starting Swarm service
9c40be8b hive starting
detected an existing store. trying to load peers
hive 9c40be8b: peers loaded
Swarm network started on bzz address: 9c40be8b83e648d50f40ad3d35f...
Pss started
Streamer started
IPC endpoint opened                      url=/home/ubuntu/.ethereum/bzzd.ipc
RLPx listener up                         self=enode://f50c8e19ff841bcd5ce7d2d...

Vous pouvez vérifier que votre nœud Swarm fonctionne correctement en vous connectant à l’interface Web de la passerelle Swarm locale : http://localhost:8500.

Vous devriez voir un écran comme celui de Passerelle Swarm sur localhost et pouvoir interroger n’importe quel hachage Swarm ou nom ENS.

Passerelle Swarm sur localhost
Figure 4. Passerelle Swarm sur localhost

Télécharger des fichiers sur Swarm

Une fois que votre nœud et votre passerelle Swarm locaux sont en cours d’exécution, vous pouvez télécharger vers Swarm et les fichiers seront accessible sur n’importe quel nœud Swarm, simplement par référence au hachage du fichier.

Testons cela en téléchargeant un fichier :

$ swarm up code/auction_dapp/README.md
ec13042c83ffc2fb5cb0aa8c53f770d36c9b3b35d0468a0c0a77c97016bb8d7c

Swarm a téléchargé le fichier README.md et renvoyé un hachage que vous pouvez utiliser pour accéder au fichier à partir de n’importe quel nœud Swarm. Par exemple, vous pouvez utiliser la https://bit.ly/2znWUP9 [passerelle Swarm publique].

Bien que le téléchargement d’un fichier soit relativement simple, il est un peu plus complexe de télécharger une interface DApp entière. En effet, les différentes ressources DApp (HTML, CSS, JavaScript, bibliothèques, etc.) ont des références intégrées les unes aux autres. Normalement, un serveur Web traduit les URL en fichiers locaux et fournit les bonnes ressources. Nous pouvons obtenir la même chose pour Swarm en empaquetant notre DApp.

Dans la DApp d’enchères, il existe un script pour regrouper toutes les ressources :

$ cd code/auction_dapp/frontend
$ npm run build

> [email protected] build /home/aantonop/Dev/ethereumbook/code/auction_dapp/frontend
> node build/build.js

Hash: 9ee134d8db3c44dd574d
Version: webpack 3.10.0
Time: 25665ms
Asset     Size
static/js/vendor.77913f316aaf102cec11.js  1.25 MB
static/js/app.5396ead17892922422d4.js   502 kB
static/js/manifest.87447dd4f5e60a5f9652.js  1.54 kB
static/css/app.0e50d6a1d2b1ed4daa03d306ced779cc.css  1.13 kB
static/css/app.0e50d6a1d2b1ed4daa03d306ced779cc.css.map  2.54 kB
static/js/vendor.77913f316aaf102cec11.js.map  4.74 MB
static/js/app.5396ead17892922422d4.js.map   893 kB
static/js/manifest.87447dd4f5e60a5f9652.js.map  7.86 kB
index.html  1.15 kB

Build complete.

Le résultat de cette commande sera un nouveau répertoire, code/auction_dapp/frontend/dist, qui contient l’intégralité de l’interface Auction DApp, regroupée :

dist/
|-- index.html
`-- static
    |-- css
    |   |-- app.0e50d6a1d2b1ed4daa03d306ced779cc.css
    |   `-- app.0e50d6a1d2b1ed4daa03d306ced779cc.css.map
    `-- js
        |-- app.5396ead17892922422d4.js
        |-- app.5396ead17892922422d4.js.map
        |-- manifest.87447dd4f5e60a5f9652.js
        |-- manifest.87447dd4f5e60a5f9652.js.map
        |-- vendor.77913f316aaf102cec11.js
        `-- vendor.77913f316aaf102cec11.js.map

Vous pouvez maintenant télécharger l’intégralité du DApp sur Swarm, en utilisant la commande up et l’option --recursive. Ici, nous disons également à Swarm que index.html est le defaultpath pour charger cette DApp :

$ swarm --bzzapi http://localhost:8500 --recursive \
  --defaultpath dist/index.html up dist/

ab164cf37dc10647e43a233486cdeffa8334b026e32a480dd9cbd020c12d4581

Désormais, l’intégralité de notre DApp d’enchères est hébergée sur Swarm et accessible par l’URL Swarm :

  • bzz://ab164cf37dc10647e43a233486cdeffa8334b026e32a480dd9cbd020c12d4581

Nous avons fait quelques progrès dans la décentralisation de notre DApp, mais nous l’avons rendu plus difficile à utiliser. Une URL comme celle-là est beaucoup moins conviviale qu’un joli nom comme auction_dapp.com. Sommes-nous obligés de sacrifier l’utilisabilité pour gagner en décentralisation ? Pas nécessairement. Dans la section suivante, nous examinerons le service de noms d’Ethereum, qui nous permet d’utiliser des noms faciles à lire tout en préservant la nature décentralisée de notre application.

Le service de noms Ethereum (ENS)

Vous pouvez concevoir le meilleur contrat intelligent au monde , mais si vous ne fournissez pas une bonne interface aux utilisateurs, ils ne pourront pas y accéder.

Sur Internet traditionnel, le système de noms de domaine (DNS) nous permet d’utiliser des noms lisibles par l’homme dans le navigateur tout en résolvant ces noms en adresses IP ou autres identifiants dans les coulisses. Sur la chaîne de blocs Ethereum, le Ethereum Naming System (ENS) résout le même problème, mais de manière décentralisée.

Par exemple, l’adresse de don de la Fondation Ethereum est 0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359 ; dans un portefeuille qui prend en charge ENS, c’est simplement ethereum.eth.

ENS est plus qu’un contrat intelligent ; c’est une DApp fondamentale en elle-même, offrant un service de noms décentralisé. En outre, ENS est pris en charge par un certain nombre de DApps pour l’enregistrement, la gestion et les enchères de noms enregistrés. ENS démontre comment les DApps peuvent fonctionner ensemble : c’est une DApp conçue pour servir d’autres DApps, prise en charge par un écosystème de DApps, intégrée dans d’autres DApps, etc.

Dans cette section, nous verrons comment fonctionne ENS. Nous montrerons comment vous pouvez configurer votre propre nom et le lier à un portefeuille ou à une adresse Ethereum, comment vous pouvez intégrer ENS dans un autre DApp et comment vous pouvez utiliser ENS pour nommer vos ressources DApp afin de les rendre plus faciles à utiliser.

Histoire des services de noms Ethereum

L’enregistrement de noms a été la première application non monétaire des chaînes de blocs, lancée par Namecoin. L’Ethereum White Paper a donné un système d’enregistrement de type Namecoin à deux lignes comme l’un de ses exemples d’applications.

Les premières versions de Geth et du client C++ Ethereum avaient un contrat namereg intégré (qui n’est plus utilisé), et de nombreuses propositions et ERC pour les services de noms ont été faites, mais ce n’est que lorsque Nick Johnson a commencé à travailler pour la Fondation Ethereum en 2016. et a pris le projet sous son aile que le travail sérieux sur un registraire a commencé.

ENS a été lancé le Star Wars Day, le 4 mai 2017 (après une tentative infructueuse de le lancer le Pi Day, le 15 mars).

La spécification ENS

ENS est spécifié principalement dans trois propositions d’amélioration d’Ethereum : EIP-137, qui spécifie les fonctions de base d’ENS ; EIP-162, qui décrit le système d’enchères pour la racine .eth ; et EIP-181, qui spécifie la résolution inverse des adresses.

ENS suit une philosophie de conception "sandwich" : une couche très simple en bas, suivie de couches de code plus complexes mais remplaçables, avec une couche supérieure très simple qui conserve tous les fonds dans des comptes séparés.

Couche inférieure : nommez les propriétaires et les résolveurs

L’ENS fonctionne sur des "nœuds" au lieu de noms lisibles par l’homme : un nom lisible par l’homme est converti en nœud à l’aide de l’algorithme "Namehash".

La couche de base d’ENS est un contrat astucieusement simple (moins de 50 lignes de code) défini par ERC137 qui permet uniquement aux propriétaires de nœuds de définir des informations sur leurs noms et de créer des sous-nœuds (l’équivalent ENS des sous-domaines DNS).

Les seules fonctions sur la couche de base sont celles qui permettent à un propriétaire de nœud de définir des informations sur son propre nœud (en particulier le résolveur, la durée de vie ou le transfert de propriété) et de créer des propriétaires de nouveaux sous-nœuds.

L’algorithme Namehash

Namehash est un algorithme récursif qui peut convertir n’importe quel nom en un hachage qui identifie le nom.

"Récursif" signifie que nous résolvons le problème en résolvant un sous-problème qui est un problème plus petit du même type, puis utilisons la solution du sous-problème pour résoudre le problème d’origine.

Namehash hache de manière récursive les composants du nom, produisant une chaîne unique de longueur fixe (ou "nœud") pour tout domaine d’entrée valide. Par exemple, le nœud Namehash de subdomain.example.eth est keccak('<example.eth> ' nœud) + keccak('<subdomain>')'. Le sous-problème que nous devons résoudre est de calculer le nœud pour `+example.eth+, qui est keccak('<.eth>' node) + keccak('<example>')'. Pour commencer, nous devons calculer le nœud pour `+eth+, qui est `keccak(<root node>) + keccak('<eth>')'.

Le nœud racine est ce que nous appelons le "cas de base" de notre récursivité, et nous ne pouvons évidemment pas le définir de manière récursive, sinon l’algorithme ne se terminera jamais ! Le nœud racine est défini comme 0x00000000000000000000000000000000000000000000000000000000000 (32 zéro octets).

En mettant tout cela ensemble, le nœud de subdomain.example.eth est donc keccak(keccak(keccak(0x0...0 + keccak('eth')) + keccak('example')) + keccak('subdomain')).

En généralisant, nous pouvons définir la fonction Namehash comme suit (le cas de base pour le nœud racine, ou nom vide, suivi de l’étape récursive) :

namehash([]) = 0x0000000000000000000000000000000000000000000000000000000000000000
namehash([label, ...]) = keccak256(namehash(...) + keccak256(label))

En Python cela devient :

def namehash(name):
  if name == '':
    return '\0' * 32
  else:
    label, _, remainder = name.partition('.')
    return sha3(namehash(remainder) + sha3(label))

Thus, mastering-ethereum.eth will be processed as follows:

namehash('mastering-ethereum.eth')
⇒ sha3(namehash('eth') + sha3('mastering-ethereum'))
⇒ sha3(sha3(namehash('') + sha3('eth')) + sha3('mastering-ethereum'))
⇒ sha3(sha3(('\0' * 32) + sha3('eth')) + sha3('mastering-ethereum'))

Bien sûr, les sous-domaines peuvent eux-mêmes avoir des sous-domaines : il peut y avoir un sub.subdomain.example.eth après subdomain.example.eth, puis un sub.sub.subdomain.example.eth, et ainsi de suite. Pour éviter un recalcul coûteux, puisque Namehash ne dépend que du nom lui-même, le nœud d’un nom donné peut être précalculé et inséré dans un contrat, éliminant ainsi le besoin de manipulation de chaîne et permettant une recherche immédiate des enregistrements ENS quel que soit le nombre de composants dans le nom brut.

Comment choisir un nom valide

Les noms consistent en une série d’étiquettes séparées par des points. Bien que les lettres majuscules et minuscules soient autorisées, toutes les étiquettes doivent suivre un processus de normalisation UTS #46 qui plie les étiquettes avant de les hacher, de sorte que les noms avec une casse différente mais une orthographe identique se retrouveront avec le même Namehash.

Vous pouvez utiliser des étiquettes et des domaines de n’importe quelle longueur, mais pour des raisons de compatibilité avec l’ancien DNS, les règles suivantes sont recommandées :

  • Les libellés ne doivent pas comporter plus de 64 caractères chacun.

  • Les noms ENS complets ne doivent pas dépasser 255 caractères.

  • Les étiquettes (labels) ne doivent pas commencer ou se terminer par des traits d’union, ni commencer par des chiffres.

Propriété du nœud racine

L’un des résultats de ce système hiérarchique est qu’il s’appuie sur les propriétaires du nœud racine, qui sont capables de créer des domaines de premier niveau (TLD).

Alors que l’objectif final est d’adopter un processus décisionnel décentralisé pour les nouveaux TLD, au moment de la rédaction, le nœud racine est contrôlé par un multisig 4 sur 7, détenu par des personnes de différents pays (construit comme un reflet des 7 détenteurs de clés du système DNS). En conséquence, une majorité d’au moins 4 des 7 détenteurs de clés est requise pour effectuer tout changement.

Actuellement, le but et l’objectif de ces détenteurs de clés est de travailler en consensus avec la communauté pour :

  • Migrer et mettre à niveau la propriété temporaire du TLD .eth vers un contrat plus permanent une fois le système évalué.

  • Autoriser l’ajout de nouveaux TLD, si la communauté convient qu’ils sont nécessaires.

  • Migrer la propriété du multisig racine vers un contrat plus décentralisé, lorsqu’un tel système est convenu, testé et mis en œuvre.

  • Servir de moyen de dernier recours pour traiter les bogues ou les vulnérabilités dans les registres de niveau supérieur.

Résolveurs

Le contrat ENS de base ne peut pas ajouter de métadonnées aux noms ; c’est le travail des soi-disant « contrats de résolveur ». Ce sont des contrats créés par l’utilisateur qui peuvent répondre à des questions sur le nom, telles que l’adresse Swarm associée à l’application, l’adresse qui reçoit les paiements à l’application (en ether ou en jetons) ou le hachage de l’application (pour vérifier son intégrité).

Couche intermédiaire : les nœuds .eth

Au moment de la rédaction, le seul domaine de premier niveau pouvant être enregistré de manière unique dans un contrat intelligent est .eth.

Note

Des travaux sont en cours pour permettre aux propriétaires de domaines DNS traditionnels de revendiquer la propriété ENS. Bien qu’en théorie cela puisse fonctionner pour .com, le seul domaine pour lequel cela a été implémenté jusqu’à présent est .xyz, et uniquement sur le testnet de Ropsten.

Les domaines .eth sont distribués via un système d’enchères. Il n’y a pas de liste réservée ni de priorité, et la seule façon d’acquérir un nom est d’utiliser le système. Le système d’enchères est un morceau de code complexe (plus de 500 lignes) ; la plupart des premiers efforts de développement (et des bugs !) dans ENS concernaient cette partie du système. Cependant, il est également remplaçable et évolutif, sans risque pour les fonds - nous en reparlerons plus tard.

Enchères Vickrey

Les noms sont distribués via une enchère Vickrey modifiée. Dans une enchère Vickrey traditionnelle, chaque enchérisseur soumet une offre scellée, et tous sont révélés simultanément, auquel cas le plus offrant remporte l’enchère mais ne paie que la deuxième offre la plus élevée. Par conséquent, les enchérisseurs sont incités à ne pas enchérir moins que la valeur réelle du nom pour eux, car enchérir sur leur valeur réelle augmente les chances qu’ils gagnent mais n’affecte pas le prix qu’ils paieront finalement.

Sur une chaîne de blocs, certains changements sont nécessaires :

  • Pour s’assurer que les enchérisseurs ne soumettent pas d’enchères qu’ils n’ont pas l’intention de payer, ils doivent verrouiller au préalable une valeur égale ou supérieure à leur enchère, afin de garantir la validité de l’enchère.

  • Étant donné que vous ne pouvez pas cacher de secrets sur une chaîne de blocs, les enchérisseurs doivent exécuter au moins deux transactions (un processus de validation-révélation) afin de masquer la valeur et le nom d’origine sur lesquels ils ont enchéri.

  • Étant donné que vous ne pouvez pas révéler toutes les offres simultanément dans un système décentralisé, les enchérisseurs doivent révéler eux-mêmes leurs propres offres ; s’ils ne le font pas, ils perdent leurs fonds bloqués. Sans ce forfait, on pourrait faire de nombreuses offres et choisir de n’en révéler qu’une ou deux, transformant une enchère à offre scellée en une enchère de prix croissant traditionnelle.

Par conséquent, l’enchère est un processus en quatre étapes :

  1. Lancez l’enchère. Ceci est nécessaire pour diffuser l’intention d’enregistrer un nom. Cela crée toutes les dates limites d’enchères. Les noms sont hachés, de sorte que seuls ceux qui ont le nom dans leur dictionnaire sauront quelle enchère a été ouverte. Cela permet une certaine confidentialité, ce qui est utile si vous créez un nouveau projet et que vous ne souhaitez pas partager de détails à son sujet. Vous pouvez ouvrir plusieurs enchères fictives en même temps, donc si quelqu’un vous suit, il ne peut pas simplement enchérir sur toutes les enchères que vous ouvrez.

  2. Faites une offre scellée. Vous devez le faire avant la date limite d’enchère, en liant une quantité donnée d’ether au hachage d’un message secret (contenant, entre autres, le hachage du nom, le montant réel de l’enchère et un sel). Vous pouvez verrouiller plus d’ether que vous n’enchérissez réellement afin de masquer votre véritable évaluation.

  3. Révélez l’enchère. Pendant la période de révélation, vous devez effectuer une transaction qui révèle l’enchère, qui calculera ensuite l’enchère la plus élevée et la deuxième enchère la plus élevée et renverra l’ether aux enchérisseurs non retenus. Chaque fois que l’enchère est révélée, le gagnant actuel est recalculé ; par conséquent, le dernier à être défini avant l’expiration du délai de révélation devient le grand gagnant.

  4. Nettoyer après. Si vous êtes le gagnant, vous pouvez finaliser l’enchère afin de récupérer la différence entre votre enchère et la deuxième enchère la plus élevée. Si vous avez oublié de révéler, vous pouvez faire une révélation tardive et récupérer une partie de votre enchère.

Couche supérieure : les actes

La couche supérieure d’ENS est encore un autre contrat super simple avec un seul but : détenir les fonds.

Lorsque vous gagnez un nom, les fonds ne sont en fait envoyés nulle part, mais sont simplement bloqués pendant la période pendant laquelle vous souhaitez conserver le nom (au moins un an). Cela fonctionne comme un rachat garanti : si le propriétaire ne veut plus du nom, il peut le revendre au système et récupérer son ether (ainsi, le coût de détention du nom est le coût d’opportunité de faire quelque chose avec un rendement supérieur à zéro ).

Bien sûr, avoir un seul contrat détenant des millions de dollars en ether s’est avéré très risqué, donc à la place, ENS crée un contrat d’acte pour chaque nouveau nom. Le contrat d’acte est très simple (environ 50 lignes de code), et il ne permet que les fonds d’être transférés vers un seul compte (le propriétaire de l’acte) et d’être appelés par une seule entité (le contrat du registraire). Cette approche réduit considérablement la surface d’attaque où les bogues peuvent mettre les fonds en danger.

Enregistrer un nom

L’enregistrement d’un nom dans ENS est un processus en quatre étapes, comme nous l’avons vu dans Enchères Vickrey. Nous plaçons d’abord une enchère pour n’importe quel nom disponible, puis nous révélons notre enchère après 48 heures pour sécuriser le nom. Calendrier ENS pour l’enregistrement est un schéma montrant le calendrier d’enregistrement.

Enregistrons notre premier nom !

Nous utiliserons l’une des nombreuses interfaces conviviales disponibles pour rechercher les noms disponibles, placer une enchère sur le nom ethereumbook.eth, révéler l’enchère et sécuriser le nom.

Il existe un certain nombre d’interfaces Web vers ENS qui nous permettent d’interagir avec l’ENS DApp. Pour cet exemple, nous utiliserons l’interface MyCrypto, en conjonction avec MetaMask comme portefeuille.

ens flow
Figure 5. Calendrier ENS pour l’enregistrement

Tout d’abord, nous devons nous assurer que le nom que nous voulons est disponible. En écrivant ce livre, nous voulions vraiment enregistrer le nom mastering.eth, mais hélas, Recherche de noms ENS sur MyCrypto.com a révélé qu’il était déjà pris ! Comme les inscriptions à l’ENS ne durent qu’un an, il pourrait devenir possible d’obtenir ce nom à l’avenir. En attendant, recherchons ethereumbook.eth (Recherche de noms ENS sur MyCrypto.com).

Génial ! Le nom est disponible. Pour l’enregistrer, nous devons avancer avec Démarrer une offre d’enchère pour un nom ENS. Débloquons MetaMask et commençons notre enregistrement pour ethereumbook.eth.

Démarrer une offre d’enchère pour un nom ENS
Figure 7. Démarrer une offre d’enchère pour un nom ENS

Faisons notre offre. Pour ce faire, nous devons suivre les étapes de Placer une offre pour un nom ENS.

Placer une offre d’enchère pour un nom ENS
Figure 8. Placer une offre pour un nom ENS
Warning

Comme mentionné dans Enchères Vickrey, vous devez révéler votre enchère dans les 48 heures suivant la fin de l’enchère, sinon vous perdez les fonds de votre enchère. Avons-nous oublié de le faire et avons-nous perdu 0,01 ETH nous-mêmes ? Vous pariez que nous l’avons fait.

Prenez une capture d’écran, enregistrez votre phrase secrète (comme sauvegarde pour votre enchère) et ajoutez un rappel dans votre calendrier pour la date et l’heure de révélation, afin de ne pas oublier et de ne pas perdre vos fonds.

Enfin, nous confirmons la transaction en cliquant sur le gros bouton vert de soumission affiché dans [ens-metamask-bid].

Transaction MetaMask contenant votre enchère
Figure 9. Transaction MetaMask contenant votre enchère

Si tout se passe bien, après avoir soumis une transaction de cette manière, vous pouvez revenir et révéler l’offre dans les 48 heures, et le nom que vous avez demandé sera enregistré sur votre adresse Ethereum.

Gérer votre nom ENS

Une fois que vous avez enregistré un nom ENS, vous pouvez le gérer à l’aide d’une autre interface conviviale : ENS Manager.

Une fois là-bas, saisissez le nom que vous souhaitez gérer dans la zone de recherche (voir L’interface web ENS Manager). Vous devez avoir votre portefeuille Ethereum (par exemple, MetaMask) déverrouillé, afin que le DApp ENS Manager puisse gérer l’enregistrement en votre nom.

L’interface web de l’ENS Manager
Figure 10. L’interface web ENS Manager

À partir de cette interface, nous pouvons créer des sous-domaines, définir un contrat de résolution (nous en reparlerons plus tard) et connecter chaque nom à la ressource appropriée, telle que l’adresse Swarm d’une interface DApp.

Création d’un sous-domaine ENS

Commençons par créer un sous-domaine pour notre exemple de DApp d’enchères (voir [ens-manager-add-subdomain]). Nous nommerons le sous-domaine auction, donc le nom complet sera auction.ethereumbook.eth.

Ajout du sous-domaine auction.ethereumbook.eth
Figure 11. Ajout du sous-domaine auction.ethereumbook.eth

Une fois que nous avons créé le sous-domaine, nous pouvons saisir auction.ethereumbook.eth dans la zone de recherche et le gérer, tout comme nous avons géré le domaine ethereumbook.eth précédemment.

Résolveurs ENS

Dans ENS, la résolution d’un nom est un processus en deux étapes :

  1. Le registre ENS est appelé avec le nom à résoudre après l’avoir haché. Si l’enregistrement existe, le registre renvoie l’adresse de son résolveur.

  2. Le résolveur est appelé, en utilisant la méthode appropriée à la ressource demandée. Le résolveur renvoie le résultat souhaité.

Ce processus en deux étapes présente plusieurs avantages. Séparer la fonctionnalité des résolveurs du système de nommage lui-même nous donne beaucoup plus de flexibilité. Les propriétaires de noms peuvent utiliser des résolveurs personnalisés pour résoudre n’importe quel type ou ressource, étendant ainsi les fonctionnalités d’ENS. Par exemple, si à l’avenir vous vouliez lier une ressource de géolocalisation (longitude/lattitude) à un nom ENS, vous pourriez créer un nouveau résolveur qui répond à une requête de géolocalisation. Qui sait quelles applications pourraient être utiles à l’avenir ? Avec les résolveurs personnalisés, la seule limite est votre imagination.

Pour plus de commodité, il existe un résolveur public par défaut qui peut résoudre une variété de ressources, y compris l’adresse (pour les portefeuilles ou les contrats) et le contenu (un hachage Swarm pour les DApps ou le code source du contrat).

Puisque nous voulons lier notre DApp d’enchères à un hachage Swarm, nous pouvons utiliser le résolveur public, qui prend en charge la résolution de contenu, comme indiqué dans Définition du résolveur public par défaut pour auction.ethereumbook.eth ; nous n’avons pas besoin de coder ou de déployer un résolveur personnalisé.

Définir le résolveur public par défaut pour auction.ethereumbook.eth
Figure 12. Définition du résolveur public par défaut pour auction.ethereumbook.eth

Résolution d’un nom en un hachage Swarm (contenu)

Une fois que le résolveur pour auction.ethereumbook.eth est défini pour être le résolveur public, nous pouvons le configurer pour qu’il renvoie le hachage Swarm comme contenu de notre nom (voir Définition du 'contenu' à retourner pour auction.ethereumbook.eth).

Définir le retour 'contenu' pour auction.ethereumbook.eth
Figure 13. Définition du 'contenu' à retourner pour auction.ethereumbook.eth

Après avoir attendu un peu de temps pour que notre transaction soit confirmée, nous devrions être en mesure de résoudre correctement le nom. Avant de définir un nom, notre DApp d’enchères pouvait être trouvée sur une passerelle Swarm par son hachage :

  • https://swarm-gateways.net/bzz:/ab164cf37dc10647e43a233486cdeffa8334b026e32a480dd9cbd020c12d4581

ou en recherchant dans un navigateur DApp ou une passerelle Swarm pour l’URL Swarm :

  • bzz://ab164cf37dc10647e43a233486cdeffa8334b026e32a480dd9cbd020c12d4581

Maintenant que nous l’avons attaché à un nom, c’est beaucoup plus simple :

  • http://swarm-gateways.net/bzz:/auction.ethereumbook.eth/

Nous pouvons également le trouver en recherchant "auction.ethereumbook.eth" dans n’importe quel portefeuille compatible ENS ou navigateur DApp (par exemple, Mist).

De l’application à la DApp

Au cours des dernières sections, nous avons progressivement construit une application décentralisée. Nous avons commencé avec une paire de contrats intelligents pour organiser une vente aux enchères d’actes ERC721. Ces contrats ont été conçus pour ne pas avoir de compte gouvernant ou privilégié, de sorte que leur fonctionnement est véritablement décentralisé. Nous avons ajouté une interface, implémentée en JavaScript, qui offre une interface pratique et conviviale à notre DApp. La DApp d’enchères utilise le système de stockage décentralisé Swarm pour stocker les ressources d’application telles que les images. La DApp utilise également le protocole de communication décentralisé Whisper pour offrir une salle de chat cryptée pour chaque enchère, sans aucun serveur central.

Nous avons téléchargé l’intégralité de l’interface sur Swarm, afin que notre DApp ne s’appuie sur aucun serveur Web pour servir les fichiers. Enfin, nous avons attribué un nom à notre DApp en utilisant ENS, en le connectant au hachage Swarm de l’interface, afin que les utilisateurs puissent y accéder avec un nom simple et facile à retenir, lisible par l’homme.

A chacune de ces étapes, nous avons augmenté la décentralisation de notre application. Le résultat final est une DApp qui n’a pas de point central d’autorité, pas de point central de défaillance, et exprime la vision "web3".

Architecture DApp d’enchères montre l’architecture complète de la DApp d’enchères.

Architecture DApp d’enchères
Figure 14. Architecture DApp d’enchères

Conclusion

Les applications décentralisées sont l’aboutissement de la vision d’Ethereum, telle qu’exprimée par les fondateurs dès les premières conceptions. Alors que de nombreuses applications s’appellent aujourd’hui "DApps", la plupart ne sont pas entièrement décentralisées. Cependant, il est déjà possible de construire des applications presque totalement décentralisées. Au fil du temps, à mesure que la technologie mûrit, de plus en plus de nos applications peuvent être décentralisées, ce qui se traduit par un Web plus résilient, résistant à la censure et libre.