Maîtriser le Web 3.0 avec Waves #6

Christophe Verdot
Maîtriser le Web 3.0 avec Waves
11 min readJul 23, 2019

Module #6 Lancer votre propre “Coupon Bazaar” Web 3 dApp

Hey! C’est la formation en ligne “Maîtriser le Web 3.0 avec Waves”. Dernier module — 6 !

Dans ce module, nous allons parler de:

  • Oracles
  • Récupération des données clé-valeur du compte depuis la node Blockchain à l’aide de l’API
  • Signature et publication de transactions à l’aide de Waves Keeper
  • Signature de plusieurs transactions en même temps avec W. Keeper et publication de tx sous certaines conditions
  • Création de dApp Web 3 multi-domaines
  • Les transactions sponsorisées pour rendre vos utilisateurs plus heureux!

Les Blockchains n’ont pas d’accès direct aux données du monde extérieur. Les Blockchains, par exemple, ne peuvent pas récupérer les informations telles que les taux de change, les prévisions météorologiques ou les cours boursiers directement à partir d’Internet.

Les oracles sont là pour vous aider en tant qu’interfaces qui connectent une Blockchain au monde extérieur.

Un Oracle est un agent — un être humain, un groupe de personnes ou un programme informatique, qui envoie des données du monde extérieur à la Blockchain (oracle entrant). Les oracles peuvent être utilisés dans les smart contracts.

Il existe de nombreux types d’oracles en fonction des besoins des développeurs dApp et des sources de données. En gros, ce sont toutes les informations du monde “externe” qui ont été enregistrées dans la blockchain.

La plateforme Waves permet aux utilisateurs de publier leur propre oracle et d’agir comme un support de données, une connexion fiable entre les API Web et votre dApp. Les oracles vous permettent d’écrire des données dans la Blockchain selon certaines règles.

Sur la base de l’outil fourni, certains utilisateurs seront en mesure de décrire leurs protocoles et de créer des Oracles, alors que d’autres pourront facilement trouver des oracles déjà créés et créer DApp à l’aide de ces protocoles.

Lien : https://oracles.wavesexplorer.com/

Documentation : https://docs.wavesplatform.com/en/waves-oracles/about-waves-oracles.html

Étapes pour créer un Oracle

  1. Créez un compte Waves ou utilisez la méthode GenerateAddress pour obtenir l’adresse avec les clés privées et publiques (une adresse peut créer un oracle). Le fournisseur peut également utiliser un compte existant et des clés.
  2. Installez Waves Keeper pour faciliter les autorisations.
  3. Ouvrez Waves Oracles et choisissez Créer un Oracle. Il doit être autorisé par Waves Keeper.
  4. Renseignez les informations du fournisseur de données, remplissez les spécifications et envoyez la data transaction.
  5. L’Oracle “card” (Carte d’informations de ce que fais cet Oracle) est créée ! Maintenant, vous avez une “carte” publique de votre oracle, qui indiquera aux autres utilisateurs quel type de données et sous quelle forme votre oracle sera transféré de l’extérieure à la Blockchain. Ensuite, commencez à envoyer une transaction dans n’importe quel format pris en charge par le protocol Waves.

Source: https://docs.wavesplatform.com/en/waves-oracles/about-waves-oracles.html

Tâche : créez votre propre oracle de données et mettez ici ses données de valeur-clé du compte de l’oracle

Comme vous le remarquerez peut-être, un ORACLE est simplement un compte sur lequel des données normalisées ont été enregistrées pour être utilisées dans d’autres dApps ou Smart Assets.

En plus de la normalisation d’oracles, vous êtes libre d’ajouter de la logique au-dessus de ce compte oracle … même en le transformant en compte dApp avec une certaine logique.

Nous construisons une place de marché Web 3.0 décentralisé pour des coupons de réduction — le «Coupons Bazaar». Chaque coupon — est un actif numérique (Digital Asset) qui représente une réduction spéciale de la part des fournisseurs.

Et si nos fournisseurs n’acceptaient pas les bons émis ? Les clients mécontent pourront envoyer des rapports à certains Oracle “vérificateurs”.

Cet oracle peut changer le statut du fournisseur en VERIFIED (Vérifier) ou BLACKLISTED (Blacklisté).

Donc, maintenant, notre Coupon Bazaar rejettera tous les nouveaux articles des fournisseurs BLACKLISTED.

S’il vous plaît, créez deux dApps :

1. Oracle-Verifier

2. CouponBazaar en utilisant le code de l’étape précédente et essayez d’ajouter un nouvel élément.

Mettez ici le résultat de la clé (key) “value” du compte CouponBazaar:

Indice : Oracle-Verifier n’a pas encore marqué le compte.

S’il vous plaît, créez deux dApps :

1. Oracle-Verifier

2. CouponBazaar en utilisant le code de l’étape précédente. Définissez le statut sur VERIFIED en utilisant Oracle-Verifier pour certains comptes. Essayez d’ajouter un nouvel élément du compte VERIFIÉ.

Mettez ici le résultat de la clé (key) “value” du compte CouponBazaar:

Nous construisons une place de marché Web 3.0 décentralisé de coupons de réduction, le «bazar des coupons». Les utilisateurs recherchent des remises sur les produits et services et peuvent les acheter à un prix modique sur le marché.

Comme vous pouvez le constater, il n’existe pas de serveur avec base de données pour nos articles / coupons. Tout est stocké dans la Blockchain dans un stockage clé-valeur de compte dApp .

Comment extraire le tableau d’éléments de la Blockchain (account data) vers l’environnement JavaScript côté client?

Dans les modules précédents, nous avons déjà commencé à expérimenter la librairie (package) @waves-transaction.

Il existe de nombreuses fonctions API utiles pour interagir avec une node Blockchain. Regardons nodeInteraction :

https://github.com/wavesplatform/waves-transactions/blob/master/src/nodeInteraction.ts

Vous avez probablement déjà remarqué que les Blockchains ont une valeur spéciale appelée «height», qui correspond au nombre de blocs créés depuis le premier blocs, appelé le «Genesis». Cette valeur est souvent utilisée comme mesure du «temps» dans les smart contracts.

Pour récupérer le “height” actuelle de la blockchain, vous pouvez utiliser :

export declare const currentHeight: (apiBase: string) => Promise<number>;

Pour récupérer tous les enregistrements de l’état actuel de la dApp, vous pouvez utiliser :

export declare function accountData(address: string, nodeUrl: string): Promise<Record<string, IDataEntry>>;

Il est également possible de tester et d’expérimenter les données dApp dans la console de l’IDE :

export declare function accountDataByKey(key: string, address: string, nodeUrl: string): Promise<IDataEntry>;

P.S : Si vous n’utilisez pas JS, vous pouvez utiliser directement l’API Node : https://nodes.wavesplatform.com/api-docs/index.html#!/addresses/getData_1

Par exemple, si vous essayez d’extraire uniquement des données spécifiques du stockage dApp. Vous êtes libre de définir cette requête sous la forme d’un modèle d’expression régulière (RegEx):

async _accountDataPattern(matches) {
return await axios.get(`addresses/data/${this.dal.dApp}?matches=${matches}`, {
baseURL: this.nodeUrl,
validateStatus
})
.then(process400)
.then(x => x.data);
}

ou

this.nodeUrl = process.env.APP_NODE_URL || 'https://testnodes.wavesnodes.com';

et PATTERN peut être généré à partir de la liste des clés requises ([ “key1”, “key2”, …, “key3” ]).

/**
* Get node data by multiple keys
* @param {string[]} keys
* @returns {Promise<null|string | number | boolean>}
*/
async nodeFetchKeys(keys) {
const regexpKeys = keys.map(key => _escapeRegExp(key));
const regexp = new RegExp('^(' + regexpKeys.join('|') + ')$');
const data = await this.nodeFetchPattern(regexp);
return keys.map(key => data[key] || null);
}

Ouvrez le code source du module nodeInteratcion. Mettez ici la fonction, qui est utilisée pour publier une transaction dans la blockchain.

Dans ce cours en ligne, nous avons principalement travaillé dans l’IDE et les signatures pour les transactions ont été générées directement à partir de variables contenant les phrases secrètes “SEED”.

const accountCustomerSeed = "genuine portion citizens waiting space merry solar above grow task lunar blanket"

Dans les applications Web 3.0, ceux qui contrôlent les SEED contrôlent toutes les activités correspondantes aux comptes associés à ces seeds : transactions, data transactions, actifs numériques, interaction avec des smart contracts. Donc une SEED doit être bien protégé et, en même temps, facile à utiliser par les clients.

Waves Keeper est une extension de navigateur qui permet aux utilisateurs de gérer leurs comptes (clés) et d’interagir de manière sécurisée et transparente avec les services Web compatibles Waves.

Nous avons déjà installé et configuré Keeper dans notre application Web3 en Module 1.

Waves Keeper peut être utilisé pour la signature et la publication de transactions.

WavesKeeper.signAndPublishTransaction(tx).then((data) => {
// published tx result
}).catch((error) => {
//processing errors
});

Afin de “signer et publier” invokeTransaction, nous devons créer un objet tx avec les champs appropriés :

let tx = {
type: 16,
data: {
fee: {
assetId: "WAVES",
tokens: "0.005"
},
dApp: "3NBB3iv7YDRsD8xxxxxxV5eTcsfqh3j2mvF",
call:{
function:"additem",
args:[
{type: "string", value: itemId},
{type: "integer", value: 2},
]},
payment: [{tokens: 1, asset: "WAVES"}]
}

ATTENTION:

MoneyLike syntax for PAYMENT parameter could look as:

{ tokens: 1, assetId: “WAVES” } or

{ coins: 100000000, assetId: “WAVES” } or

{ amount: 100000000, assetId: null }

Dans les 3 versions, le même prix de 1 WAVES est indiqué. Vous pouvez facilement convertir des Coins en Tokens et inversement, si vous savez en quel asset le prix est indiqué et que vous connaissez la précision (décimale) de ces Tokens = coin / (10 ** précision). Si le champ contient d’autres types que MoneyLike, par exemple, string / MoneyLike, la somme est indiquée sous forme de nombre de coins.

Pour en savoir plus sur l’API Waves Keeper, lisez la documentation :

https://docs.wavesplatform.com/en/waves-api-and-sdk/waves-keeper-api.html

Sur les pages de navigateur fonctionnant sous HTTP / HTTPS (pages locales non gérées avec des fichiers : // protocole) avec l’extension Waves Keeper installée, l’objet global Waves Keeper est alors disponible et présente les méthodes suivantes:

  • auth
  • publicState
  • signAndPublishCancelOrder
  • signAndPublishOrder
  • signAndPublishTransaction
  • signCancelOrder
  • signOrder
  • signTransaction
  • signRequest
  • signTransactionPackage
  • on

Toutes les méthodes, sauf “on”, fonctionnent de manière asynchrone et renvoient des promises.

Parfois, nous avons des situations où :

1. nous devons signer plusieurs transactions et les publier en même temps plus tard

C’est un cas pour une paire de transactions fournisseurs: (1) émettre de nouveaux Tokens / coupons; (2) Invoquer une transaction d’Ajout d’un nouvel élément — envoi de coupons au compte dApp.

2. Nous devons signer un lot de transactions en même temps, mais nous les publierons séparément en fonction de certaines conditions (déclencheurs)

Les clients doivent voter “pour” ou “contre” le fournisseur: (1) envoyer la tx, (2) révélez la tx

Les transactions qui ont été signées, mais pas encore publiées sont valables 1 heure et demi environ pour publication

Pour signer un lot de transactions sans publication, nous allons utiliser:

let txIssueSigned = await WavesKeeper.signTransaction(txIssue);let txAddItemSigned = await WavesKeeper.signTransaction(txAddItem);

puis faire un envoi de manière synchrone (broadcast):

let resultIssue = await nodeInteraction.broadcast(JSON.parse(txIssueSigned), nodeUrl);let resultAddItem = await nodeInteraction.broadcast(JSON.parse(txAddItemSigned), nodeUrl);

ATTENTION: 1 — JSON.parse(…) est nécessaire ici. 2 — vous pouvez générer le tx.id avant de signer ou publier (voir docs).

ou

let txCommitSigned = await WavesKeeper.signTransaction(txCommit);let txRevealSigned = await WavesKeeper.signTransaction(txReveal);

puis publiez la transaction de “commit” (txCommitSigned). Enregistrer les données de la transaction de “Reveal” (txRevealSigned) dans le stockage local du navigateur. Plus tard, récupérez les données de la transaction de “Reveal” depuis le LocalStorage et transmettez-les à la Blockchain une fois que tous les électeurs auront terminé leurs étapes de validation.

Vous pouvez maintenant développer toute logique de “pipelines” avec des transactions dans le code JS du navigateur !

La dernière chose concernant Keeper dont nous allons parler dans ce module : Comment reconnaître les utilisateurs qui se sont déjà enregistrés dans votre dApp?

À titre d’exemple, examinons la page de profil du fournisseur sur CouponBazaar.

Pour cela nous utiliserons :

WavesKeeper.publicState()
then(state => {
console.log(state); //displaying the result in the console
/*...processing data */
}).catch(error => {
console.error(error); // displaying the result in the console
/*...processing errors */
})

L’adresse de l’utilisateur courant est présente dans : state.account.address

Dans le module 2, nous savons qu’il existe des différences entre Web 2.0 (ancien) et Web 3.0 (nouveau) en termes d’architectures techniques.

Les services Web traditionnels comportent des côtés «serveur» et «client». Lorsqu’un utilisateur ouvre la page dans son navigateur, le serveur répond avec un contenu statique de page Web, du code HTML, des ressources (comme des images et des polices) et du code JavaScript.

Lorsque l’utilisateur interagit avec les composants d’interface utilisateur de la page Web, par exemple les boutons et les formulaires, le code Java Script crée de nouvelles demandes au serveur afin d’obtenir davantage de données à afficher ou à écrire dans la base de données du serveur.

Après le traitement de cette requête, le serveur renvoie une réponse sous forme de format de données clé-valeur JSON. Le navigateur utilise ces données pour modifier l’état et la vue d’une application client.

Le Web 3.0 fonctionne de manière légèrement différente. Bien entendu, l’application Web 3.0 nécessite toujours le code HTML et JavaScript pour s’exécuter dans le navigateur. Donc, de ce fait, le serveur avec le code de l’application client est toujours nécessaire.

Lorsque l’utilisateur interagit avec l’application cliente, la demande «Lire» est créée. Cette demande est traitée par le réseau Blockchain via la Node de l’application. La principale différence ici est que ces données peuvent être lues par n’importe qui. C’est public sur les registres distribués les plus populaires.

Le point le plus important est : comment écrire une nouvelle information sur le réseau Blockchain. Pour cela nous utilisons des Transaction et des Signatures Numériques

Toutes les mises à jour sur le réseau Blockchain doivent être implémentées par la soumission de transaction, qui nécessite une signature numérique de l’initiateur de la transaction.

Comme vous pouvez le constater, la seule raison d’avoir un serveur en Web 3.0 est simplement l’hébergement des fichiers JavaScript + HTML comme passerelle pour le navigateur et la Blockchain.

Cela signifie donc que nous pouvons utiliser un compte dApp comme côté “serveur” pour de nombreux sites Web différents, avec différents domaines, code JS + HTML et des éléments tels que des images, des gifs, etc.

Nous vous souhaitons bonne chance avec vos développement de dApps!

Enjoy Web3!

--

--

Christophe Verdot
Maîtriser le Web 3.0 avec Waves

Web Developer - Waves Platform France Tech Ambassador— Waves Platform Lead for Philippines - Signature Chain founder and Lead Developer / signature-chain.com