Ethereum Oracle Contracts: Einrichtung und Orientierung
Veröffentlicht: 2022-03-11Ethereum Smart Contracts sind mehr als nur „das neue heiße Ding“. Ich bin davon überzeugt, dass sie (oder etwas Ähnliches) bereit sind, die Art und Weise zu verändern, wie Menschen im bevorstehenden neuen Zeitalter des Internets Geschäfte miteinander machen. Ob dem so ist, wird die Zeit zeigen.
Dies ist der erste eines dreiteiligen Artikels über die Entwicklung intelligenter Verträge von Ethereum mit Solidity, der insbesondere die Verwendung von Verträgen mit sogenannten „Orakeln“ untersucht – das sind im Grunde Verträge, die Daten in die Blockchain pumpen, um von anderen intelligenten Verträgen verwendet zu werden.
- Teil 1: Eine Einführung in die Entwicklung mit Truffle und Projektaufbau für weitere Experimente
- Teil 2: Eintauchen in den Code für eine tiefere Untersuchung
- Teil 3: Eine konzeptionelle Diskussion über Orakel mit Smart Contracts
Das Ziel von diesem, Teil 1 der Serie, ist es nicht, viel in das Konzept von Orakelverträgen, die Philosophie dahinter oder sogar sehr tief in das einzudringen, was sie sind; Das Ziel dieses Teils unseres Ethereum-Orakel-Tutorials ist einfach:
- Bereiten Sie sich auf die Erstellung intelligenter Verträge mit Truffle vor.
- Erstellen Sie ein intelligentes Vertragsprojekt, das uns in den Teilen 2 und 3 dienen wird.
- Stellen Sie einige Konzepte vor, die sich auf Ethereum Smart Contracts und die Codierung von Smart Contracts beziehen.
- Führen Sie den Compile/Run/Debug-Zyklus mit Truffle und Smart Contracts ein.
Bedeutung: Orakel. Ein Mittel für Smart Contracts, um auf Daten aus der Welt außerhalb der Blockchain zuzugreifen. Orakel, die selbst eine Art Smart Contract sind, nehmen Daten von der Außenwelt und fügen sie in die Blockchain ein, damit andere Smart Contracts sie nutzen können.
Der erste Teil dieses Artikels besteht aus der Einrichtung mit allen Voraussetzungen. Dann richten wir einen einzelnen Ethereum-Vertrag ein und testen ihn mit Truffle. Schließlich trennen wir das Orakel vom Client und testen sie gemeinsam.
Software Anforderungen
- Jedes größere Betriebssystem wird funktionieren, obwohl einige der Installationen und Einstellungen natürlich auf verschiedenen Systemen unterschiedlich sein werden. Ich habe das alles unter Ubuntu Linux (16.04) gemacht. Ich hatte auch keine Probleme beim Einrichten der Umgebung unter Windows. Ich habe den Mac nicht ausprobiert, obwohl ich weiß, dass dies auch auf dem Mac üblich ist.
- Es ist nicht erforderlich, einen vollständigen eth-Knoten auszuführen; Wir werden Truffle verwenden, das mit einem eigenen Testnetz geliefert wird. Wenn Sie ein bisschen wissen, was Sie tun, können Sie jedes andere Testnetz Ihrer Wahl verwenden. Das lokale Entwickler-Testnetz von Truffle ist für die Zwecke dieses Tutorials einfach das einfachste und zugänglichste.
Wissensanforderungen
- Grundlegende Kenntnisse zur Funktionsweise von Blockchain
- Verstehen, was ein Blockchain-basierter Smart Contract ist
- Einige grundlegende Erfahrungen mit der Entwicklung intelligenter Verträge sind hilfreich, aber nicht erforderlich, wenn Sie intelligent und ehrgeizig sind. (Und ich weiß, dass du es bist!)
Diese Artikelserie kann als allererste Einführung in Smart Contracts dienen, entwickelt sich aber sehr schnell zu fortgeschritteneren Konzepten. Wenn es Ihr erstes eth-Smart-Contract-Tutorial ist, seien Sie darauf vorbereitet, schnell in die Höhe zu steigen. Wenn Sie sich sicher fühlen, großartig; Wenn nicht, können Sie sich gerne zuerst ein oder zwei einfachere Tutorials vom Typ „Hallo Welt“ besorgen. Schauen Sie sich für den Anfang einen der oder frühere Ethereum-Artikel und Cryptozombies an.
Vorbehalt: Der Smart-Contract-Bereich, der so neu ist, ändert sich schnell. Solidity-Syntaxfeatures, die neu waren, als dieser Artikel geschrieben wurde, sind möglicherweise veraltet oder veraltet, wenn Sie diesen Artikel lesen. Geth-Versionen sind möglicherweise gekommen und gegangen. Solidity fügt ständig neue Sprachfeatures hinzu und veraltet alte. Viele neue Funktionen sind derzeit in Arbeit. Seien Sie also darauf vorbereitet, die Informationen in diesem Artikel gegebenenfalls an die neue Landschaft der Zukunft anzupassen; Wenn Sie es ernst meinen, die Entwicklung intelligenter Verträge zu lernen, dann habe ich Vertrauen in Sie.
Beschreibung der Beispiel-App
Anwendungsfall: Nutzer wetten auf Boxkämpfe.
- Der Benutzer kann eine Liste mit wettenfähigen Boxkämpfen ziehen.
- Der Benutzer kann ein Match auswählen und eine Wette auf den Gewinner platzieren.
- Der Benutzer kann jeden Betrag über einem bestimmten Minimum setzen.
- Wenn die Auswahl des Benutzers verliert, verliert der Benutzer den gesamten Einsatzbetrag.
- Wenn die Auswahl des Benutzers gewinnt, erhält der Benutzer einen Teil des Pots basierend auf der Höhe seines Einsatzes und des Gesamtbetrags, der auf den Verlierer des Spiels gesetzt wird, nachdem das Haus (der Vertragseigentümer) einen kleinen Prozentsatz des Gewinns erhält .
Was ist ein Ethereum-Orakel?
Smart Contracts sind immer noch etwas Neues; Sie müssen noch den Mainstream erobern, und so viele Aspekte ihrer Funktionsweise sind noch nicht ausgearbeitet und standardisiert. Ich werde kurz den Impetus hinter der Idee des „Orakels“ erläutern – und Geduld haben; wir werden uns in späteren Teilen eingehender damit befassen.
Das Entwickeln eines Blockchain-Vertrags ist nicht wie das Programmieren einer Client-Server-App. Ein wichtiger Unterschied besteht darin, dass Daten, mit denen der Vertrag interagiert, bereits auf der Blockchain vorhanden sein müssen. Es erfolgt kein Aufruf aus der Blockchain. Es wird nicht nur von der Sprache nicht unterstützt, es wird auch nicht vom Blockchain-Paradigma unterstützt. Der Vertrag kann Wetten in Form von Ethereum-basierter Währung annehmen, sie im Vertrag speichern und sie gemäß einer Formel an die richtigen Wallet-Adressen freigeben, wenn der Gewinner eines Spiels bekannt gegeben wird. Aber woher kennt der Vertrag den Gewinner? Es kann keine REST-API oder ähnliches abfragen. Es kann nur Daten verwenden, die sich bereits in der Blockchain befinden! Viele, viele Anwendungsfälle von Smart Contracts stoßen auf ein ähnliches Problem – sie sind stark eingeschränkt, es sei denn, sie können mit der Welt außerhalb der Blockchain interagieren.
Wenn der Vertrag nur mit Daten auf der Blockchain interagieren kann, besteht eine naheliegende Lösung darin, die erforderlichen Daten in die Blockchain einzufügen. Und genau das ist ein Orakel. Ein Orakel ist ein weiterer Vertrag, der Daten in die Blockchain einfügt und es anderen Verträgen ermöglicht, sie zu konsumieren. Während dies Fragen zu Vertrauen und Vertrauenslosigkeit aufwerfen mag, akzeptieren Sie einfach, dass dies ein Orakel ist. In Teil 3 dieser Serie werden wir diese Nuancen besprechen. In unserem beispielhaften Anwendungsfall ist das Orakel der Vertrag, der Daten in die Blockchain einfügt, in Bezug auf (a) welche Spiele verfügbar sind und (b) wer diese Spiele gewonnen hat, sobald die Entscheidung gefallen ist.
Einrichten der Ethereum-Entwicklungsumgebung
Für die grundlegende Einrichtung installieren wir:
- Geth (vorerst optional)
- Trüffel
- Ganache-CLI (optional)
- Eine Entwicklungsumgebung (optional)
Dieser Artikel hat nicht den Platz, um eine vollständige Anleitung zum Einrichten der Umgebung zu geben, sondern dient nur als grobe Anleitung. Das ist jedoch in Ordnung, da es bereits viele vollständigere Setup-Anleitungen für Ihr spezielles Betriebssystem gibt und das Internet nicht wirklich eine neue benötigt. Ich werde Sie also schnell auf den Weg bringen und Sie auf einige Ressourcen verweisen, um bei Bedarf weitere Details zu erhalten. Bereiten Sie sich darauf vor, die Anforderungen und Voraussetzungen so zu installieren, wie es Ihr System erfordert und wie Google Sie anweist.
Geth installieren (optional)

Geth ist Go-ethereum, die Kernsoftware von Ethereum; Obwohl es für diese Übung überhaupt nicht notwendig ist, sollte jeder angehende Ethereum-Entwickler es haben und damit vertraut sein. Es wird notwendig sein, wenn Sie Ihren Smart Contract jemals im Live-Ethereum-Netzwerk einsetzen wollen.
- http://www.talkcrypto.org/blog/2018/01/23/what-is-geth/
- https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-Ubuntu
- https://github.com/ethereum/go-ethereum/wiki/Installation-instructions-for-Windows
Trüffel installieren

Trüffel ist die Hauptsache, die wir für die Entwicklung verwenden werden, und ist absolut eine Voraussetzung für diesen Leitfaden. Suchen und befolgen Sie die spezifischen Anweisungen für Ihr Betriebssystem, um Truffle zu installieren. Nachfolgend finden Sie einige Links, die Ihnen hoffentlich weiterhelfen.
- https://truffleframework.com/docs/truffle/getting-started/installation
- https://github.com/trufflesuite/truffle
- https://truffleframework.com/tutorials/how-to-install-truffle-and-testrpc-on-windows-for-blockchain-development
Ganache-CLI installieren (optional)

Ich empfehle die Installation von Ganache CLI als weiteres Testtool, obwohl wir es nicht für unser Tutorial verwenden werden. Es ist optional.
https://github.com/trufflesuite/ganache-cli
Ethereum-Entwicklungsumgebung
Es wäre mehr als möglich, dieses gesamte Tutorial mit jedem einfachen Texteditor wie Notepad++, gedit, vi oder einem beliebigen Texteditor oder einer IDE Ihrer Wahl durchzuführen. Ich persönlich verwende Visual Studio Code mit den folgenden Erweiterungen:
- Solidität
- Solidität erweitert
- Material-Icon-Thema
Hinweis: Die Erweiterungen sind nicht erforderlich – sie sorgen lediglich für eine bessere Programmierumgebung.
Einrichten des Codes
Projektaufbau
Truffle ist ein sehr praktisches Tool zum Kompilieren von Smart Contracts, deren Migration in eine Blockchain und bietet außerdem Entwicklungs- und Debugging-Dienstprogramme. Für die Integration mit Truffle sind einige Projekteinstellungen erforderlich. Jetzt richten wir die Shell für unser Projekt ein, sowohl in Truffle als auch in der Verzeichnisstruktur. Lehnen Sie sich einfach zurück, folgen Sie den Schritten zunächst roboterhaft und genießen Sie.
Erstellen Sie ein Verzeichnis, um den gesamten Code aufzunehmen; Nennen Sie es Orakelbeispiel .
Erstellen Sie im Stammverzeichnis zwei Unterverzeichnisse, da das Projekt schließlich aus zwei Unterprojekten bestehen wird. Erstellen Sie die Verzeichnisse:
- /oracle-beispiel/client
- /oracle-beispiel/oracle
Gehen Sie in den Kundenordner, denn das ist das erste Projekt, das wir entwickeln werden. Öffnen Sie ein Terminalfenster (Befehlszeile) im Ordner /oracle-example/client .
Führen Sie den Befehl truffle init
.
Beachten Sie, dass unter vielen erstellten Dateien truffle-config.js und truffle.js sind. Wir brauchen nicht beide, also löschen Sie truffle-config.js (nur um Verwirrung und Unordnung zu vermeiden).
Wir müssen truffle.js bearbeiten, um Truffle zum Testen in die richtige Richtung zu lenken. Ersetzen Sie den Inhalt von truffle.js durch Folgendes:
module.exports = { networks: { development: { host: "localhost", port: 8545, network_id: "*" // Match any network id } } };
https://github.com/jrkosinski/oracle-example/tree/part1-step1/client/truffle.js
Beachten Sie, dass Truffle init ein Verzeichnis namens migrations ( oracle-example/client/migrations ) erstellt hat. In diesem Ordner sollte sich eine Datei mit dem Namen 1_initial_migration.js befinden .
Fügen Sie eine weitere Datei im Migrationsverzeichnis hinzu und nennen Sie sie 2_deploy_contracts.js mit folgendem Inhalt:
var BoxingBets = artifacts.require("BoxingBets"); module.exports = function(deployer) { deployer.deploy(BoxingBets); };
https://github.com/jrkosinski/oracle-example/tree/part1-step1
Hinzufügen des Codes
Jetzt, da die einfache Einrichtung aus dem Weg geräumt ist, können wir mit dem Codieren beginnen. Denken Sie daran, dass dieser Teil des Artikels immer noch Einführung und Einrichtung ist, also werden wir den Code ziemlich schnell durchgehen. Wir werden uns in Teil 2 eingehender mit Erläuterungen des Codes und in Teil 3 mit einer eingehenderen Diskussion der Architektur und des Konzepts befassen. Trotzdem werden wir schnell auf einige Kernkonzepte eingehen, die im Code offensichtlich sind. Folgen Sie sorgfältig, um Schritt zu halten.
Der vollständige Code für diesen Schritt im Prozess ist auf GitHub verfügbar: https://github.com/jrkosinski/oracle-example/tree/part1-step1
Verträge in Solidität
Ein „Vertrag“ in Solidity ist grob analog zu einer Klasse in anderen objektorientierten Sprachen. Die Sprache selbst wurde unter anderem mit Golang und JavaScript verglichen. Einige andere Sprachkonstrukte in Solidity – für die wir später Beispiele haben werden – sind Modifikatoren, Bibliotheken und Schnittstellen. Vererbung (einschließlich Mehrfachvererbung) wird für Verträge unterstützt. Solidity-Vertragsdateien haben die Erweiterung .sol.
Oracle-Schnittstelle
Fügen Sie diese Datei zu Ihrem Projekt hinzu: /oracle-example/client/contracts/OracleInterface.sol
https://github.com/jrkosinski/oracle-example/tree/part1-step1/client/contracts/OracleInterface.sol

Normalerweise wäre die Oracle-Schnittstelle genau das – eine Schnittstelle. Für diese allererste Iteration ist es nur eine einfache Klasse, die im Solidity-Projekt enthalten ist, nur als Platzhalter für den Moment. Wir werden es im nächsten Schritt verschieben, nachdem wir den Vertrag auf Truffle erfolgreich kompiliert und ausgeführt haben. Nachdem wir dies später in eine tatsächliche Schnittstelle umgewandelt haben, sind die Funktionsimplementierungen leer.
Kundenvertrag
Fügen Sie diese Datei zu Ihrem Projekt hinzu: /oracle-example/client/contracts/BoxingBets.sol
https://github.com/jrkosinski/oracle-example/tree/part1-step1/client/contracts/BoxingBets.sol
Dies ist der Vertrag, der die Boxkampfdaten verbraucht, es Benutzern ermöglicht, verfügbare Spiele abzufragen und Wetten darauf zu platzieren. In späteren Iterationen werden Gewinne berechnet und ausgezahlt.
Kompilieren und Ausführen
Jetzt werden wir sehen, ob wir beim ersten Mal alles richtig gemacht haben!
Kompilieren und migrieren Sie den Vertrag
Öffnen Sie ein Terminal im Ordner /oracle-example/client/
Kompilieren Sie den Code mit diesem Befehl:
truffle compile


Alternative: Verwenden Sie mein Shell-Skript recompile.sh (https://github.com/jrkosinski/oracle-example/tree/part1-step1/client/recompile.sh).
Beachten Sie, dass Sie viele Warnungen sehen werden, da unser Code noch nicht in seiner endgültigen Form vorliegt!

Öffnen Sie die Truffle-Entwicklungskonsole:
truffle develop
Migrieren Sie jetzt in der Truffle-Entwicklerkonsole zum Testnetzwerk:
truffle(develop)> migrate
Führen Sie den Vertrag aus
Geben Sie an der Eingabeaufforderung der Entwicklungskonsole die folgende Codezeile ein:
truffle(develop)> BoxingBets.deployed().then(inst => { instance = inst })
Nun ist „Instanz“ die Variable, die sich auf den BoxingBets-Vertrag bezieht und zum Aufrufen seiner öffentlichen Methoden verwendet werden kann.
Testen Sie es mit dem folgenden Befehl:
truffle(develop)> instance.test(3, 4)
Beachten Sie, dass wir eine öffentliche „Test“-Funktion in BoxingBets.sol integriert haben . Es addiert die zwei Zahlen, die Sie ihm übergeben, nur um zu demonstrieren, dass der Vertrag Code ausführt und dass wir ihn von der Truffle-Entwicklungskonsole aus aufrufen können. Wenn wir eine vernünftig aussehende Antwort erhalten (siehe unten), dann ist unsere Arbeit hier erledigt (zumindest für den Moment).
Trennen Sie das Ethereum-Orakel
Wenn bisher alles gelungen ist, dann sind wir über den Berg. Als nächstes trennen wir den Oracle-Vertrag vom BoxingBets-Vertrag. In der Praxis existiert der Vertrag des Orakels getrennt vom Kundenvertrag auf der Blockchain, also müssen wir in der Lage sein:
- Instanziieren Sie es nach Blockchain-Adresse.
- Ändern Sie dynamisch die Oracle-Adresse, die der Clientvertrag verwendet, um auf das Oracle zu verweisen.
Kurz gesagt, was wir jetzt tun werden, ist, das Orakel und den Kunden in zwei separate Blockchain-Vertragseinheiten zu trennen und sie dazu zu bringen, miteinander zu sprechen. Der Client instanziiert das Orakel per Adresse und ruft es auf.
Kundenvertrag
Zunächst ändern wir den Client-Vertrag (client) so, dass er sich auf eine dynamische Schnittstelle zu einem Orakel und nicht auf eine konkrete Klasse bezieht. Dann stellen wir sicher, dass es das Orakel aus einem externen Vertrag instanziiert.
Gehen Sie zu /oracle-example/client/contracts/OracleInterface.sol . Wie wir bereits angemerkt haben, ist dies derzeit keine Schnittstelle, aber wir sind dabei, sie zu einer zu machen. Ersetzen Sie den Inhalt durch den Inhalt von:
https://github.com/jrkosinski/oracle-example/tree/part1-step2/client/contracts/OracleInterface.sol
pragma solidity ^0.4.17; contract OracleInterface { enum MatchOutcome { Pending, //match has not been fought to decision Underway, //match has started & is underway Draw, //anything other than a clear winner (eg cancelled) Decided //index of participant who is the winner } function getPendingMatches() public view returns (bytes32[]); function getAllMatches() public view returns (bytes32[]); function matchExists(bytes32 _matchId) public view returns (bool); function getMatch(bytes32 _matchId) public view returns ( bytes32 id, string name, string participants, uint8 participantCount, uint date, MatchOutcome outcome, int8 winner); function getMostRecentMatch(bool _pending) public view returns ( bytes32 id, string name, string participants, uint participantCount, uint date, MatchOutcome outcome, int8 winner); function testConnection() public pure returns (bool); function addTestData() public; }
In BoxingBets.sol werden wir diese Zeile ersetzen:
OracleInterface internal boxingOracle = new OracleInterface();
Mit diesen beiden Zeilen:
address internal boxingOracleAddr = 0; OracleInterface internal boxingOracle = OracleInterface(boxingOracleAddr);
Was wir jetzt wollen, ist eine Möglichkeit, die Adresse des Orakels dynamisch festzulegen, und eine Funktion, die wir aufrufen können, um die aktuelle Orakeladresse herauszufinden. Fügen Sie diese beiden Funktionen zu BoxingBets.sol hinzu :
/// @notice sets the address of the boxing oracle contract to use /// @dev setting a wrong address may result in false return value, or error /// @param _oracleAddress the address of the boxing oracle /// @return true if connection to the new oracle address was successful function setOracleAddress(address _oracleAddress) external onlyOwner returns (bool) { boxingOracleAddr = _oracleAddress; boxingOracle = OracleInterface(boxingOracleAddr); return boxingOracle.testConnection(); } /// @notice gets the address of the boxing oracle being used /// @return the address of the currently set oracle function getOracleAddress() external view returns (address) { return boxingOracleAddr; }
Und schließlich können wir zum Testen der Verbindung zwischen dem Client und dem Orakel die Testfunktion in BoxingBets durch eine Funktion zum Testen der Orakelverbindung ersetzen:
/// @notice for testing; tests that the boxing oracle is callable /// @return true if connection successful function testOracleConnection() public view returns (bool) { return boxingOracle.testConnection(); }
Besitzbar
Beachten Sie, dass der Definition für setOracleAddress
ein onlyOwner
-Modifizierer folgt. Dadurch wird verhindert, dass diese Funktion von jemand anderem als dem Eigentümer des Vertrags aufgerufen wird, obwohl die Funktion öffentlich ist. Das ist keine Sprachfunktion. Das wird uns durch den Ownable-Vertrag bereitgestellt, der aus der OpenZeppelin-Bibliothek von Solidity-Verträgen für allgemeine Zwecke herausgenommen wird. Wir werden in Teil 2 auf die Details eingehen, aber um die Verwendung dieses Modifikators onlyOwner
zu erleichtern, müssen wir ein paar Änderungen vornehmen:
Kopieren Sie Ownable.sol von https://github.com/jrkosinski/oracle-example/tree/part1-step2/client/contracts/Ownable.sol in /oracle-example/client/contracts/ .
Fügen Sie oben in BoxingBets.sol einen Verweis darauf hinzu, etwa so:
import "./Ownable.sol";
(Sie können es direkt unter der Zeile hinzufügen, die OracleInterface.sol importiert.)
Ändern Sie die Vertragserklärung von BoxingBets, um sie von Ownable zu erben, von diesem:
contract BoxingBets {
Dazu:
contract BoxingBets is Ownable {
Und wir sollten bereit sein. Der vollständige Code ist hier, falls Sie sich verlaufen haben: https://github.com/jrkosinski/oracle-example/tree/part1-step2/client/contracts
Oracle-Verträge
Aufstellen
Nun, da der BoxingBets-Vertrag versucht, per Adresse auf einen völlig separaten Vertrag (das ist das Orakel) zu verweisen, besteht unsere nächste Aufgabe darin, diesen Orakel-Vertrag zu erstellen. Also werden wir jetzt ein ganz separates Projekt erstellen, das den Orakelvertrag enthalten wird. Es ist im Wesentlichen das gleiche Setup, das wir bereits für das Kundenvertragsprojekt durchgeführt haben; das heißt, Truffle zum Kompilieren und Entwickeln einrichten.
Sie sollten bereits einen Ordner namens /oracle-example/oracle/ haben, den wir in einem vorherigen Schritt erstellt haben (oder falls nicht, erstellen Sie jetzt dieses leere Verzeichnis). Öffnen Sie ein Terminal in diesem Verzeichnis.
- Führen Sie den Befehl
truffle init
. - Löschen Sie /oracle-example/oracle/truffle-config.js .
- Bearbeiten Sie /oracle-example/oracle/truffle.js wie folgt:
module.exports = { networks: { development: { host: "localhost", port: 8545, network_id: "*" // Match any network id } } };
Siehe das Beispiel hier: https://github.com/jrkosinski/oracle-example/tree/part1-step2/oracle/truffle.js
Erstellen Sie in /oracle-example/oracle/migrations/ eine Datei namens 2_deploy_contracts.js mit folgendem Inhalt:
var BoxingOracle = artifacts.require("BoxingOracle"); module.exports = function(deployer) { deployer.deploy(BoxingOracle); };
Siehe das Beispiel hier: https://github.com/jrkosinski/oracle-example/tree/part1-step2/oracle/migrations/2_deploy_contracts.js
Oracle-Code
Kopieren Sie für diesen Schritt einfach die folgenden drei Dateien von https://github.com/jrkosinski/oracle-example/tree/part1-step2/oracle/contracts/ in Ihren Ordner /oracle-example/oracle/contracts/
:
- BoxingOracle.sol: Der Hauptvertrag des Orakels.
- Ownable.sol: Für Owner-Only-Funktionen, wie wir sie bereits im Kundenvertrag verwendet haben.
- DateLib.sol: Eine Datumsbibliothek. Wir werden uns in Teil 2 dieser Serie genauer damit befassen.
Testen des Orakels
Jetzt, in der aktuellen Iteration des Projekts, müssen wir unser Smart-Contract-Orakel wirklich gründlich testen, da dies unsere Basis sein wird, auf der wir den Rest des Projekts aufbauen werden. Nachdem wir nun das Oracle-Projekt eingerichtet und den Code kopiert haben, möchten wir Folgendes tun:
- Kompilieren Sie das Orakel.
- Stellen Sie sicher, dass das Orakel ausgeführt wird.
- Führen Sie einige Funktionen in der Truffle-Konsole aus, um sicherzustellen, dass das Orakel wie erwartet funktioniert.
Kompilieren und migrieren Sie das Oracle
Führen Sie immer noch in einem Terminal, das für /oracle-example/oracle/
geöffnet ist, die folgenden Befehle aus. Auch diese Schritte sind identisch mit dem, was wir bereits getan haben, um den Clientvertrag zu kompilieren und zu migrieren.
truffle compile
Alternative: Verwenden Sie mein Shell-Skript recompile.sh (https://github.com/jrkosinski/oracle-example/tree/part1-step2/oracle/recompile.sh).
Öffnen Sie die Truffle-Entwicklungskonsole:
truffle develop
Zum Testnetz migrieren:
truffle(develop)> migrate
Führen Sie das Oracle aus und testen Sie es
Geben Sie immer noch in der Truffle-Entwicklungskonsole Folgendes ein, um einen verwendbaren Zeiger auf den Orakelvertrag zu erfassen:
truffle(develop)> BoxingOracle.deployed().then(inst => { instance = inst })
Jetzt können (und sollten) wir eine Reihe von Tests an unserem Oracle-Vertrag durchführen, um ihn zu testen. Versuchen Sie, die folgenden Befehle nacheinander auszuführen, und untersuchen Sie die Ergebnisse.
truffle(develop)> instance.testConnection() ... truffle(develop)> instance.getAllMatches() ... truffle(develop)> instance.addTestData() ... truffle(develop)> instance.getAllMatches() ...
Sie werden an dieser Stelle ermutigt, den Oracle-Code durchzusehen, zu sehen, welche öffentlichen Methoden verfügbar sind, die Kommentare im Code zu lesen und einige Ihrer eigenen Tests zum Ausführen zu entwickeln (und sie hier in der Konsole auszuführen, als oben gezeigt).
Testen und Debuggen
Jetzt sind wir bereit für den letzten Test: um zu testen, ob der Client-Vertrag den Oracle-Vertrag aufrufen kann, der sich bereits in der Blockchain befindet, und seine Daten abrufen und verwenden kann. Wenn all dies funktioniert, haben wir ein Client-Orakel-Paar, das wir für weitere Experimente verwenden können. Unsere Schritte zur Durchführung des End-to-End-Tests:
- Kompilieren Sie den Oracle-Vertrag und führen Sie ihn aus
- Kompilieren Sie den Clientvertrag und führen Sie ihn aus
- Holen Sie sich die Adresse des Oracle-Vertrags
- Stellen Sie die Oracle-Adresse im Client-Vertrag ein
- Testdaten zum Oracle-Vertrag hinzufügen
- Testen Sie, ob wir diese Daten im Kundenvertrag abrufen können
Öffnen Sie zwei Terminalfenster:
- Einer in /oracle-example/client/
- Und das andere in /oracle-example/oracle/
Ich schlage vor, dass Sie das /oracle-example/client/ auf der linken Seite und das /oracle-example/oracle/ auf der rechten Seite offen lassen und genau folgen, um Verwirrung zu vermeiden.
Kompilieren Sie den Oracle-Vertrag und führen Sie ihn aus
Führen Sie die folgenden Befehle im Terminal /oracle-example/oracle/ aus:
bash recompile.sh truffle develop truffle(develop)> migrate truffle(develop)> BoxingOracle.deployed().then(inst => { instance = inst })
Kompilieren Sie den Client-Vertrag und führen Sie ihn aus
Führen Sie die folgenden Befehle im Terminal /oracle-example/client/ aus:
bash recompile.sh truffle develop truffle(develop)> migrate truffle(develop)> BoxingBets.deployed().then(inst => { instance = inst })
Rufen Sie die Adresse des Oracle-Vertrags ab
Führen Sie den folgenden Befehl für Truffle im Terminal /oracle-example/oracle/ aus:
truffle(develop)> instance.getAddress()
Kopieren Sie die Adresse, die die Ausgabe dieses Aufrufs ist; und verwenden Sie es im nächsten Schritt.
Legen Sie die Oracle-Adresse im Client-Vertrag fest
Führen Sie den folgenden Befehl aus, um im /oracle-example/client/ -Terminal zu trüffeln:
truffle(develop)> instance.setOracleAddress('<insert address here, single quotes included>')
Und teste es:
truffle(develop)> instance.testOracleConnection()
Wenn die Ausgabe true
ist, können wir loslegen.
Testen Sie, ob wir diese Daten im Kundenvertrag abrufen können
Führen Sie den folgenden Befehl aus, um im /oracle-example/client/ -Terminal zu trüffeln:
truffle(develop)> instance.getBettableMatches()
Es sollte ein leeres Array zurückgeben, da der Orakelseite noch keine Testdaten hinzugefügt wurden.
Führen Sie den folgenden Befehl aus, um im Terminal /oracle-example/oracle/ zu trufflen und Testdaten hinzuzufügen:
truffle(develop)> instance.addTestData()
Führen Sie den folgenden Befehl aus, um im Terminal /oracle-example/client/ zu trüffeln, um zu sehen, ob wir die neu hinzugefügten Testdaten vom Client abrufen können:
truffle(develop)> instance.getBettableMatches()
Wenn Sie nun einzelne Adressen aus dem von getBettableMatches()
zurückgegebenen Array nehmen und sie in getMatch()
.
Sie werden an dieser Stelle ermutigt, den Client-Code durchzusehen, zu sehen, welche öffentlichen Methoden verfügbar sind, die Kommentare im Code zu lesen und einige Ihrer eigenen auszuführenden Tests zu entwickeln (und sie hier in der Konsole auszuführen, als Oben).
Abschluss des ersten Teils
Unsere Ergebnisse aus dieser Übung sind begrenzt, aber unsere Ziele waren es auch, um ein realistisches Tempo zu halten. Unser Kunde ist noch nicht in der Lage, Wetten anzunehmen, Gelder zu verwalten, Gewinne aufzuteilen usw. Was wir haben – abgesehen von den gewonnenen Kenntnissen und Erfahrungen – ist:
- Ein größtenteils funktionales Smart-Contract-Orakel
- Ein Client, der sich mit dem Orakel verbinden und mit ihm interagieren kann
- Ein Rahmen für Weiterentwicklung und Lernen
Und das ist nicht schlecht für einen kurzen Artikel.
In Teil zwei dieser Serie werden wir uns eingehender mit dem Code befassen und einige der Funktionen betrachten, die für die intelligente Vertragsentwicklung einzigartig sind, sowie einige der Sprachfunktionen, die spezifisch für Solidity sind. Viele der Dinge, die in diesem Teil nur beschönigt wurden, werden im nächsten erklärt.
In Teil drei dieser Serie werden wir ein wenig über die Philosophie und das Design von Smart Contracts diskutieren, insbesondere in Bezug auf ihre Verwendung mit Orakeln.
Weitere optionale Schritte
Solo-Experimente sind eine gute Art zu lernen. Hier sind ein paar einfache Vorschläge, wenn Sie darüber nachdenken, wie Sie dieses Tutorial erweitern können, um mehr Wissen zu erlangen (keiner der folgenden Punkte wird in den Teilen 2 und 3 behandelt):
- Stellen Sie die Verträge auf Ganache (früher testrpc) bereit und führen Sie dieselben Tests durch, um die Funktion zu überprüfen.
- Stellen Sie die Verträge in Ropsten- oder Rinkeby-Testnetzen bereit und führen Sie dieselben Tests durch, um die Funktion zu überprüfen.
- Erstellen Sie ein web3js-Frontend entweder für das Orakel oder den Client (oder beides).
Viel Glück und bei Fragen können Sie sich gerne an mich wenden. Ich kann nicht unbedingt eine schnelle Antwort garantieren, aber ich werde mein Bestes tun.