Modul #6 Web 3.0 mit Waves

Marc Jansen
Web3 mit Waves Platform
9 min readJul 14, 2019

Modul #6 Einführung einer eigenen “Coupon Basars” Web 3 dApp

Herzlich Willkommen beim letzten Modul des Online-Kurs “Mastering Web3 with Waves”. Modul — 6!

6.0 Oracle

6.1 Abruf der Key-Value-Daten des Kontos

6.2 Signieren und Veröffentlichen von Transaktionen mit Waves Keeper

6.3 Gleichzeitige Unterzeichnung mehrerer Transaktionen mit Waves Keeper

6.4 Multi-Domain Web 3 dApp

6.5 Gesponsorte Transaktionen

Blockchains haben keinen direkten Zugriff auf Daten von außerhalb der Blockchain. So können Blockchains beispielsweise Informationen wie Wechselkurse, Wettervorhersagen oder Börsenkurse nicht direkt aus dem Internet abrufen.

Oracles sind dazu da, um als Schnittstellen zu implementieren, die eine Blockchain mit der Außenwelt verbinden.

Ein Oracle ist ein Agent — ein Mensch, eine Gruppe von Personen oder ein Computerprogramm, das Daten von der Außenwelt an die Blockchain (Inbound Oracle) sendet. Oracle können innerhalb von Smart Contracts verwendet werden.

Es gibt viele verschiedene Arten von Oracles, je nach den Bedürfnissen der dApp-Entwickler und den Datenquellen. Grundsätzlich sind es immer Informationen aus der “externen” Welt, die in der Blockchain aufgezeichnet wurden und damit innerhalb der Blockchain zur Verfügung gestellt werden.

Die Waves-Plattform ermöglicht es Benutzern, ihr eigenes Orakel zu erstellen und Daten aus dem Oracle entsprechend zu speichern, eine zuverlässige Verbindung zwischen Web-APIs und Ihrer dApp. Oracle ermöglichen es Ihnen, Daten nach bestimmten Regeln in die Blockchain zu schreiben.

Basierend auf dem bereitgestellten Tool können Benutzer ihre Protokolle beschreiben und Oracle erstellen, während andere Benutzer bereits erstellte Oracle leicht finden und ihre eigene DApp mit diesen Protokollen erstellen können.

Link:

https://oracles.wavesexplorer.com/

Dokumente:

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

Schritte zum Erstellen eines Oracle:

  1. Erstellen Sie ein Waves-Konto oder verwenden Sie die Methode GenerateAddress, um die Adresse zusammen mit privaten und öffentlichen Schlüsseln zu erhalten (eine Adresse kann ein Oracle erstellen). Der Anbieter kann auch ein bestehendes Konto und Schlüssel verwenden.
  2. Installieren Sie Waves Keeper für eine einfache Autorisierung.
  3. Öffnen Sie Waves Oracles und wählen Sie Oracle erstellen. Der Zugriff muss vom Waves Keeper autorisiert werden.
  4. Füllen Sie die Datenlieferanteninformationen aus, legen Sie die Spezifikation an und senden Sie die initiierende Datentransaktion.
  5. Damit haben Sie ihre erste Oracle-Karte erstellt! Jetzt haben Sie eine öffentliche Karte Ihres Oracle, die anderen Benutzern sagt, welche Art von Daten und in welcher Form Ihr Oracle Off-Chain Daten in die Blockchain überträgt. Als nächstes starten Sie das Senden einer Transaktion in einem beliebigen, vom Waves-Protokoll unterstützten Format.

Quelle:

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

Wie Sie vielleicht bemerkt haben: ein Oracle ist nur ein Konto, in dem standardisierte Daten erfasst werden, die in anderen dApps oder Smart Assets verwendet werden können.

Neben der Standardisierung von Oraclen steht es Ihnen frei, mehr Logik über das Konto des Oracles hinzuzufügen, und es sogar mit einer bestimmten Logik zum dApp-Konto zu machen.

Wir bauen einen dezentralen Web3-Couponmarktplatz — “Coupon Bazaar”. Jeder Coupon — ist ein digitales Asset, das einen speziellen Rabatt von Lieferanten darstellt.

Was geschieht, wenn unsere Lieferanten ihre ausgegebenen Coupons nicht akzeptieren? Das wird den Kunden nicht gefallen und sie werden Berichte an ein “Verifier”-Oracle schicken.

Dieses Orakel ist in der Lage, den Status des Lieferanten in VERIFIZIERT oder BLACKLISTED zu ändern.

So, jetzt wird unser CouponBazaar alle neuen Artikel von BLACKLISTED-Lieferanten ablehnen.

Bitte erstellen Sie zwei dApps:

  1. Verifier-Oracle
  2. CouponBazaar: verwendet den Code aus dem vorherigen Schritt und versucht, einen neuen Artikel hinzuzufügen.

Bitte erstellen Sie zwei dApps:

  1. Verifier-Oracle
  2. CouponBazaar mit dem Code aus dem vorherigen Schritt. Setzen Sie den Status auf VERIFIZIERT mit Hilfe des Verifier-Oracle für einige Konten. Versuchen Sie, einen neuen Artikel aus dem VERIFIZIERTEN Konto hinzuzufügen.

Wir bauen einen dezentralen Web3-Couponmarktplatz — “Coupon Bazaar”. Die Nutzer suchen nach Rabatten für Waren und Dienstleistungen und können diese zu einem kleinen Preis auf dem Marktplatz kaufen.

Wie Sie sehen können, gibt es keinen Server mit Datenbank für unsere Artikel/Coupons. Alles wird in der Blockchain in einem Key-Value dApp Account Storage gespeichert.

Wie kann man das Item-Array aus der Blockchain (Account-Daten) in die JavaScript-Client-seitige Umgebung holen?

In früheren Modulen haben wir bereits mit dem @waves-transaction package experimentiert.

Es gibt viele sehr nützliche API-Funktionen, um mit dem Blockchain-Knoten zu interagieren. Betrachten wir die nodeinteraction:

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

Wahrscheinlich haben Sie bereits bemerkt, dass Blockchains einen speziellen Wert namens “height” haben, dieser beschreibt die Anzahl der Blöcke, die nach dem ersten “genesis”-Block bereits generiert wurden. Dieser Wert wird oft als Maß für die “Zeit” in Smart Contracts verwendet.

Über den folgenden Befehl können Sie auf die aktuelle Höhe der Blockchain zugreifen:

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

Um alle Datensätze des aktuellen dApp-Status zu erhalten, verwenden Sie folgenden Befehl:

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

Es ist auch möglich, die dApp-Daten in der Konsole der IDE zu testen und hiermit zu experimentieren:

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

P.S.: Wenn Sie kein JS verwenden, können Sie die Node API direkt verwenden:

https://nodes.wavesplatform.com/api-docs/index.html#!/addresses/getData_1

zum Beispiel, wenn Sie versuchen, nur bestimmte Daten aus dem dApp-Speicher zu holen.

Es steht Ihnen frei, diese Anforderung in Form eines RegEx-Musters (Regular Expression) zu definieren:

async _accountDataPattern(matches) {return await axios.get(`addresses/data/${this.dal.dApp}?matches=${matches}`, {baseURL: this.nodeUrl,validateStatus}).then(process400).then(x => x.data);}mitthis.nodeUrl = process.env.APP_NODE_URL || ‘https://testnodes.wavesnodes.com';und PATTERN können aus der Liste der benötigten Schlüssel generiert werden ([ “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);}

Im Web3 kontrollieren diejenigen, die SEEDs kontrollieren, alle entsprechenden Aktivitäten des Kontos: Transaktionen, Daten, digitale Vermögenswerte und die Interaktion mit Smart Contracts. Deshalb muss der SEED irgendwie gut geschützt und gleichzeitig einfach vom Kunden zu bedienen sein.

Waves Keeper ist eine Browser-Erweiterung, mit der Benutzer ihre Konten (Schlüssel) verwalten und sicher und nahtlos mit Waves-fähigen Webservices und dApps interagieren können.

Wir haben Waves Keeper bereits in unserer Web3-Anwendung in Modul 1 installiert und konfiguriert.

Waves Keeper kann für die Transaktionssignierung und -veröffentlichung verwendet werden.

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

Um eine invokeTransaction “zu signieren & zu veröffentlichen”, müssen wir ein Sendeobjekt mit entsprechenden Feldern erstellen:

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”}]}

ACHTUNG:

Die MoneyLike-Syntax für den Parameter PAYMENT könnte so aussehen:

{ token: 1, assetId: “WAVES” }

oder

{ coins: 100000000000000, assetId: “WAVES” }

oder

{ amount: 1000000000000, assetId: null }

In den drei Nachrichten wird der gleiche Preis von 1 WAVES konfiguriert. Sie können Münzen leicht in Token umwandeln und zurück, wenn Sie wissen, in welchem Vermögenswert der Preis angegeben ist und Sie die Anzahl seiner Dezimalstellen (Genauigkeit) kennen:

Münzen / (10 ** Genauigkeit)

Wenn das Feld andere Typen als MoneyLike enthält, z.B. String/MoneyLike, wird die Summe als Zahl in Münzen angegeben.

Um mehr über die Waves Keeper API zu erfahren, lesen Sie die Dokumentation:

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

Auf Browserseiten, die unter HTTP/HTTPS arbeiten (lokale Seiten mit file:// Protokoll funktionieren nicht) und installierter Waves Keeper-Erweiterung, ist das globale Waves Keeper-Objekt mit den folgenden Methoden verfügbar:

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

Alle Methoden, mit Ausnahme von “on”, arbeiten asynchron und geben Promises zurück.

Manchmal haben wir Situationen, in denen:

  1. Wir mehrere Transaktionen unterschreiben und gleichzeitig später veröffentlichen müssen.Es handelt sich um ein paar Lieferantentransaktionen: (1) Neue Token ausgeben — Coupons; (2) Neue Artikel hinzufügen — Tx aufrufen — Coupons an das dApp-Konto senden.
  2. Wir müssen gleichzeitig eine Reihe von Transaktionen unterschreiben, aber wir werden sie separat veröffentlichen, abhängig von bestimmten Bedingungen (Triggern).

Z.B. ist dies der Fall, wenn Kunden “für” oder “gegen” den Lieferanten stimmen: (1) tx übertragen, (2) tx offenbaren

Unterzeichnete, aber noch nicht veröffentlichte Transaktionen sind innerhalb von ca. 1,5 Stunden gültig.

Um eine Reihe von Transaktionen ohne Veröffentlichung zu signieren, werden wir verwenden:

let txIssueSigned = await WavesKeeper.signTransaction(txIssue);let txAddItemSigned = await WavesKeeper.signTransaction(txAddItem);und dann den synchronen Aufruf (Broadcast):let resultIssue = await nodeInteraction.broadcast(JSON.parse(txIssueSigned), nodeUrl);let resultAddItem = await nodeInteraction.broadcast(JSON.parse(txAddItemSigned), nodeUrl);

ACHTUNG: 1 — JSON.parse(….) ist hier erforderlich. 2 — Sie können die tx.id generieren, bevor Sie sie signieren oder veröffentlichen (siehe Dokumentation).

oder

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

und rufen Sie dann publish für die “commit tx” auf. Speichern Sie “reveal tx” im localStorage des Browsers. Extrahieren Sie “reveal tx” aus dem localStorage und senden Sie sie an die Blockchain, nachdem alle Teilnehmer ihre Commit-Schritte abgeschlossen haben.

Jetzt können Sie jede beliebige “Pipeline”-Logik mit Transaktionen im Browser JS-Code entwickeln!

Das Letzte, was wir mit Waves Keeper in diesem Modul besprechen werden: Wie erkennt man Benutzer, die sich bereits in Ihrer dApp registriert haben?

Als Beispiel möchten wir uns die Profilseite des Lieferanten auf CouponBazaar ansehen.

Um das zu tun, verwenden wir den folgenden Code:

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 */})

Die Adresse des aktuellen Benutzers befindet sich in der Variablen: state.account.address.

Traditionelle Webapplikationen haben “Server” und “Client” Teile. Wenn ein Benutzer die Seite in seinem Browser öffnet, antwortet der Server auf statische Inhalte der Webseite, HTML, Assets (wie Bilder und Schriften) und JavaScript-Code.

Wenn ein Benutzer mit Benutzeroberflächenkomponenten der Webseite interagiert, z. B. Schaltflächen und Formulare, erstellt der JavaScript-Code neue Anfragen an den Server, um mehr Daten zum Anzeigen oder Schreiben einiger Daten in die Datenbank des Servers.

Nach der Verarbeitung dieser Anforderung gibt der Server eine Antwort als in der Regel im JSON Datenformat zurück. Der Browser verwendet diese Daten, um den Status und die Ansicht einer Client-Anwendung zu ändern.

Das Web3 funktioniert etwas anders. Natürlich benötigt die Web3-App auch den HTML plus JavaScript-Code, um sie im Browser auszuführen. Dazu wird also noch der Server mit dem Client-Anwendungscode benötigt.

Wenn ein Benutzer mit der Client-Anwendung interagiert, wird die Anforderung “Lesen” erstellt. Diese Anforderung wird von Knoten des Distributed Ledger — Blockchain Network bearbeitet. Der Hauptunterschied besteht darin, dass diese Daten von jedem gelesen werden können. Es ist öffentlich für öffentliche Distributed Ledger.

Der wichtigste Moment ist: wie man eine neue Information in das Blockchain-Netzwerk schreibt. Hier haben wir den Begriff der Transaktions und eine digitale Signatur.

Alle Updates im Blockchain-Netzwerk müssen durch Transaktions-Submit erfolgen, was eine digitale Signatur des Transaktionsinitiators erfordert.

Wie Sie sehen können, ist der einzige Grund, einen Server zu haben, — nur das Hosting von JavaScript+HTML der Browseranwendung.

Das bedeutet also, dass wir ein dApp-Konto als “Backend” für viele verschiedene Websites mit unterschiedlichen Domains, JS+HTML-Code und Assets wie Bilder, Gifs usw. verwenden können.

Wir wünschen Ihnen viel Erfolg mit Ihren tollen dApps! Viel Spaß mit Web3!

Herzlichen Glückwunsch, Sie haben den Kurs “Mastering Web3 with Waves” abgeschlossen.

--

--