Oracles
Letzte Änderung: @Coram_Deo(opens in a new tab), 25. Juli 2024
Oracles sind Datenleitungen, die Ethereum mit Offchain-Informationen in der realen Welt verbinden, so dass Sie Daten in Ihren Smart Contracts abfragen können. Zum Beispiel nutzen Vorhersagemarkt-dApps Oracles zur Begleichung von Zahlungen auf der Grundlage von Events. Ein Vorhersagemarkt könnte Sie fragen, Ihre ETH auf den nächsten Präsidenten der Vereinigten Staaten zu wetten. Sie werden ein Oracle verwenden, um das Ergebnis zu bestätigen und entsprechend an die Gewinner zu zahlen.
Voraussetzungen
Stellen Sie sicher, dass Sie mit Knotenpunkten, Konsensmechanismenund Smart Contract-Anatomievertraut sind, im speziellen Smart Contract-Events.
Was ist ein Oracle
Ein Oracle ist eine Brücke zwischen der Blockchain und der realen Welt. Sie fungieren als on-chain APIs, die Sie abfragen können, um Informationen für Ihre Smart Contracts zu bekommen. Dies könnte theoretisch alles sein, von Preisinformationen bis hin zu Wetterberichten. Oracles können auch bidirektional sein, um Daten in die reale Welt zu „senden".
Schauen Sie sich an, wie Patrick Oracles erklärt:
Warum werden sie benötigt?
Bei einer Blockchain wie Ethereum muss jeder Knotenpunkt im Netzwerk jede Transaktion wiederholen und am Ende garantiert das gleiche Ergebnis erzielen. APIs führen potenziell variable Daten ein. Wenn Sie ETH auf Basis eines vereinbarten $USD-Werts über eine Preis-API senden würden, würde die Abfrage von einem Tag auf den anderen ein anderes Ergebnis liefern. Nicht zu vergessen, die API könnte gehackt oder veraltet sein. Wenn dies geschieht, könnten sich die Knotenpunkte im Netzwerk nicht auf den aktuellen Zustand von Ethereum einigen und damit den Konsens brechen.
Oracles lösen dieses Problem, indem die Daten auf der Blockchain veröffentlicht werden. Jeder Knotenpunkt, der die Transaktion wiedergibt, verwendet also die gleichen unveränderlichen Daten, die für alle sichtbar sind. Dazu besteht ein Oracle in der Regel aus einem Smart Contract und einigen Off-Chain-Komponenten, die APIs abfragen können. Es werden regelmäßig Transaktionen gesendet, um die Daten des Smart Contract zu aktualisieren.
Das Oracle-Problem
Wie wir bereits erwähnt haben, können Ethereum-Transaktionen nicht direkt auf Off-Chain-Daten zugreifen. Gleichzeitig ist es unsicher, sich bei der Bereitstellung von Daten auf eine einzige Quelle der Wahrheit zu verlassen, und es macht die Dezentralisierung eines Smart Contract zunichte. Dies ist als Oracle-Problem bekannt.
Wir können das Oracle-Problem vermeiden, indem wir ein dezentrales Oracle verwenden, das Daten aus mehreren Quellen schöpft. Wenn eine Datenquelle gehackt wird oder ausfällt, funktioniert der Smart Contract trotzdem wie vorgesehen.
Sicherheit
Ein Oracle ist nur so sicher wie seine Datenquelle(n). Wenn ein dApp Uniswap als Oracle für seinen ETH/DAI-Preis-Feed verwendet, kann ein Angreifer den Preis auf Uniswap verschieben, um das Verständnis des dApps für den aktuellen Preis zu manipulieren. Ein Beispiel dafür, wie man dem entgegenwirken kann, ist ein Feed-System(opens in a new tab) wie das von MakerDAO, das Preisdaten aus vielen externen Preis-Feeds zusammenführt, anstatt sich nur auf eine einzige Quelle zu verlassen.
Architektur
Dies ist ein Beispiel für eine einfache Oracle-Architektur, aber es gibt noch mehr Möglichkeiten, um Berechnungen außerhalb der Kette auszulösen.
- Senden Sie ein Protokoll mit Ihrem Smart-Contract-Event aus
- Ein Off-Chain-Dienst hat diese spezifischen Logs abonniert (normalerweise mit dem JSON-RPC
eth_subscribe
Befehl). - Der Off-Chain-Dienst führt einige Aufgaben aus, die im Protokoll festgelegt sind.
- Der Off-Chain-Dienst gibt mit den angeforderten Daten in einer Sekundärtransaktion eine Antwort an den Smart Contract.
Auf diese Weise erhalten Sie die Daten 1 zu 1. Um die Sicherheit zu erhöhen, sollten Sie jedoch dezentralisieren, wie Sie Ihre Off-Chain-Daten sammeln.
Der nächste Schritt könnte ein Netzwerk mit diesen Knotenpunkten sein, die diese Aufrufe an verschiedene APIs und Quellen tätigen und die Daten in der Kette zusammenführen.
Chainlink Off-Chain Reporting(opens in a new tab) (Chainlink OCR) hat diese Methode verbessert, indem die Off-Chain-Oracles des Netzwerks miteinander kommunizieren, ihre Antworten kryptographisch signieren, ihre Antworten off-chain zusammenfassen und nur eine Transaktion mit dem Ergebnis on-chain senden. Auf diese Weise wird weniger Gas verbraucht, aber Sie erhalten trotzdem die Garantie dezentraler Daten, da jeder Knotenpunkt seinen Teil der Transaktion signiert hat, so dass er von dem Knotenpunkt, der die Transaktion sendet, nicht mehr geändert werden kann. Die Eskalationsrichtlinie tritt in Kraft, wenn der Knotenpunkt keine Transaktion durchführt, und der nächste Knotenpunkt eine Transaktion sendet.
Verwendung
Mit Diensten wie Chainlink können Sie dezentrale Daten auf der Kette referenzieren, die bereits aus der realen Welt gezogen und aggregiert wurden. Eine Art öffentliches Gemeingut, aber für dezentralisierte Daten. Sie können auch Ihre eigenen modularen Oracle Netzwerke aufbauen, um alle gewünschten Daten zu erhalten. Darüber hinaus können Sie auch Berechnungen außerhalb der Blockchain durchführen und Informationen an die reale Welt senden. Chainlink verfügt über die nötige Infrastruktur:
- Erhalten Sie Krypto-Preis-Feeds in Ihrem Vertrag(opens in a new tab)
- Generieren Sie überprüfbare zufällige Zahlen (nützlich zum Spielen)(opens in a new tab)
- Aufruf externer APIs(opens in a new tab) – Eine neuartige Anwendung dieser Methode ist die Überprüfung der wBTC-Reserven(opens in a new tab)
Hier ist ein Beispiel dafür, wie Sie den neuesten ETH-Preis in Ihrem Smart Contract mithilfe eines Chainlink-Preis-Feeds erhalten:
Chainlink-Datenleitungen
1pragma solidity ^0.6.7;23import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";45contract PriceConsumerV3 {67 AggregatorV3Interface internal priceFeed;89 /**10 * Network: Kovan11 * Aggregator: ETH/USD12 * Address: 0x9326BFA02ADD2366b30bacB125260Af64103133113 */14 constructor() public {15 priceFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);16 }1718 /**19 * Returns the latest price20 */21 function getLatestPrice() public view returns (int) {22 (23 uint80 roundID,24 int price,25 uint startedAt,26 uint timeStamp,27 uint80 answeredInRound28 ) = priceFeed.latestRoundData();29 return price;30 }31}Alles anzeigenKopieren
Sie können dies in Remix mit diesem Link testen(opens in a new tab)
Dokumentation ansehen(opens in a new tab)
Chainlink-VRF
Chainlink-VRF (Verifiable Random Function) ist eine nachweislich faire und überprüfbare Zufallsquelle, die für Smart Contracts entwickelt wurde. Entwickler von Smart Contracts können Chainlink-VRF als manipulationssichere Zufallszahlengenerierung (RNG) verwenden, um zuverlässige Smart Contracts für alle Anwendungen zu erstellen, die auf unvorhersehbare Ergebnisse angewiesen sind:
- Blockchain-Spiele und NFTs
- Zufällige Zuweisung von Aufgaben und Ressourcen (z. B. zufällige Zuweisung von Richtern zu Fällen)
- Auswahl einer repräsentativen Stichprobe für Konsensmechanismen
Zufallszahlen sind schwierig, weil Blockchains deterministisch sind.
Die Arbeit mit Chainlink Oracles außerhalb von Datenleitungen folgt dem Anfrage- und Empfangszyklus(opens in a new tab) der Arbeit mit Chainlink. Sie verwenden den LINK-Token, um Oracle-Anbietern Oracle-Gas für Antworten zu senden. Der LINK-Token wurde speziell für die Arbeit mit Oracles entwickelt und basiert auf dem aktualisierten ERC-677 Token, der mit ERC-20 rückwärts kompatibel ist. Der folgende Code, falls er im Kovan-Testnet eingesetzt wird, wird eine kryptographisch erwiesene Zufallsnummer abrufen. Um den Antrag zu stellen, finanzieren Sie den Vertrag mit einem Testnet LINK-Token, den Sie über den Kovan LINK Faucet(opens in a new tab) erhalten können.
12pragma solidity 0.6.6;34import "@chainlink/contracts/src/v0.6/VRFConsumerBase.sol";56contract RandomNumberConsumer is VRFConsumerBase {78 bytes32 internal keyHash;9 uint256 internal fee;1011 uint256 public randomResult;1213 /**14 * Constructor inherits VRFConsumerBase15 *16 * Network: Kovan17 * Chainlink VRF Coordinator address: 0xdD3782915140c8f3b190B5D67eAc6dc5760C46E918 * LINK token address: 0xa36085F69e2889c224210F603D836748e7dC008819 * Key Hash: 0x6c3699283bda56ad74f6b855546325b68d482e983852a7a82979cc4807b641f420 */21 constructor()22 VRFConsumerBase(23 0xdD3782915140c8f3b190B5D67eAc6dc5760C46E9, // VRF Coordinator24 0xa36085F69e2889c224210F603D836748e7dC0088 // LINK Token25 ) public26 {27 keyHash = 0x6c3699283bda56ad74f6b855546325b68d482e983852a7a82979cc4807b641f4;28 fee = 0.1 * 10 ** 18; // 0.1 LINK (varies by network)29 }3031 /**32 * Requests randomness from a user-provided seed33 */34 function getRandomNumber(uint256 userProvidedSeed) public returns (bytes32 requestId) {35 require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet");36 return requestRandomness(keyHash, fee, userProvidedSeed);37 }3839 /**40 * Callback function used by VRF Coordinator41 */42 function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {43 randomResult = randomness;44 }45}Alles anzeigen
Chainlink Keeper
Smart Contracts können ihre eigenen Funktionen nicht zu beliebigen Zeiten oder unter beliebigen Bedingungen auslösen oder initiieren. Zustandsänderungen treten nur auf, wenn ein anderes Konto eine Transaktion initiiert (z. B. ein Benutzer, ein Oracle oder ein Vertrag). Das Chainlink Keeper Netzwerk(opens in a new tab) bietet Optionen für Smart Contracts, um regelmäßige Wartungsaufgaben auf eine vertrauensminimierte und dezentralisierte Weise auszulagern.
Um Chainlink Keeper zu verwenden, muss ein Smart Contract das Keeper-Compatible Interface(opens in a new tab) implementieren, das aus zwei Funktionen besteht:
checkUpkeep
- Prüft, ob der Vertrag Arbeiten erfordert.performUpkeep
- Führt die Arbeit an dem Vertrag aus, wenn er von checkUpkeep angewiesen wurde.
Das folgende Beispiel ist ein einfacher Gegenvertrag. Die Variable Counter
wird bei jeder Abfrage von performUpkeep
um eins erhöht. Sie können den folgenden Code mit Remix(opens in a new tab) ausprobieren
1// SPDX-License-Identifier: MIT2pragma solidity ^0.7.0;34// KeeperCompatible.sol imports the functions from both ./KeeperBase.sol and5// ./interfaces/KeeperCompatibleInterface.sol6import "@chainlink/contracts/src/v0.7/KeeperCompatible.sol";78contract Counter is KeeperCompatibleInterface {9 /**10 * Public counter variable11 */12 uint public counter;1314 /**15 * Use an interval in seconds and a timestamp to slow execution of Upkeep16 */17 uint public immutable interval;18 uint public lastTimeStamp;1920 constructor(uint updateInterval) {21 interval = updateInterval;22 lastTimeStamp = block.timestamp;2324 counter = 0;25 }2627 function checkUpkeep(bytes calldata /* checkData */) external override returns (bool upkeepNeeded, bytes memory /* performData */) {28 upkeepNeeded = (block.timestamp - lastTimeStamp) > interval;29 // We don't use the checkData in this example. Die checkData werden bei der Registrierung des Upkeep definiert.30 }3132 function performUpkeep(bytes calldata /* performData */) external override {33 lastTimeStamp = block.timestamp;34 counter = counter + 1;35 // We don't use the performData in this example. Das performData wird durch die Abfrage der Funktion checkUpkeep durch den Keeper erzeugt36 }37}Alles anzeigen
Nachdem Sie einen Keeper-kompatiblen Vertrag eingerichtet haben, müssen Sie den Vertrag für Upkeep(opens in a new tab) registrieren und mit LINK finanzieren, um das Keeper-Netzwerk über Ihren Vertrag zu informieren, damit Ihre Arbeit kontinuierlich ausgeführt wird.
Keeper-Projekte
Chainlink API Aufruf
Chainlink API Calls(opens in a new tab) sind der einfachste Weg, um Daten aus der Off-Chain-Welt auf die traditionelle Art und Weise zu erhalten, wie das Web funktioniert: API-Aufrufe. Da es nur eine einzige Instanz und nur ein Oracle gibt, ist es von Natur aus zentralisiert. Um wirklich dezentralisiert zu sein, müsste eine Smart-Contract-Plattform zahlreiche Knotenpunkte in einem externen Datenmarkt(opens in a new tab) verwenden.
Auch dies folgt dem Anfrage- und Empfangszyklus von Oracles und setzt voraus, dass der Vertrag mit Kovan LINK (dem Oracle-Gas) finanziert wird, um zu funktionieren.
1pragma solidity ^0.6.0;23import "@chainlink/contracts/src/v0.6/ChainlinkClient.sol";45contract APIConsumer is ChainlinkClient {67 uint256 public volume;89 address private oracle;10 bytes32 private jobId;11 uint256 private fee;1213 /**14 * Network: Kovan15 * Oracle: 0x2f90A6D021db21e1B2A077c5a37B3C7E75D15b7e16 * Job ID: 29fa9aa13bf1468788b7cc4a500a45b817 * Fee: 0.1 LINK18 */19 constructor() public {20 setPublicChainlinkToken();21 oracle = 0x2f90A6D021db21e1B2A077c5a37B3C7E75D15b7e;22 jobId = "29fa9aa13bf1468788b7cc4a500a45b8";23 fee = 0.1 * 10 ** 18; // 0.1 LINK24 }2526 /**27 * Create a Chainlink request to retrieve API response, find the target28 * data, then multiply by 1000000000000000000 (to remove decimal places from data).29 */30 function requestVolumeData() public returns (bytes32 requestId)31 {32 Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);3334 // Set the URL to perform the GET request on35 request.add("get", "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD");3637 // Set the path to find the desired data in the API response, where the response format is:38 // {"RAW":39 // {"ETH":40 // {"USD":41 // {42 // "VOLUME24HOUR": xxx.xxx,43 // }44 // }45 // }46 // }47 request.add("path", "RAW.ETH.USD.VOLUME24HOUR");4849 // Multiply the result by 1000000000000000000 to remove decimals50 int timesAmount = 10**18;51 request.addInt("times", timesAmount);5253 // Sends the request54 return sendChainlinkRequestTo(oracle, request, fee);55 }5657 /**58 * Receive the response in the form of uint25659 */60 function fulfill(bytes32 _requestId, uint256 _volume) public recordChainlinkFulfillment(_requestId)61 {62 volume = _volume;63 }64}Alles anzeigen
Sie können mehr über die Anwendungen von Chainlink erfahren, indem Sie den Chainlink-Entwickler-Blog(opens in a new tab) lesen.
Oracle-Dienste
- Chainlink(opens in a new tab)
- Witnet(opens in a new tab)
- Provable(opens in a new tab)
- Paralink(opens in a new tab)
- Dos.Netzwerk(opens in a new tab)
Erstellen Sie einen Oracle-Smart-Contract
Hier ist ein Oracle-Beispielvertrag von Pedro Costa. Weitere Anmerkungen finden Sie in seinem Artikel: Implementierung eines Blockchain Oracles auf Ethereum(opens in a new tab).
1pragma solidity >=0.4.21 <0.6.0;23contract Oracle {4 Request[] requests; //list of requests made to the contract5 uint currentId = 0; //increasing request id6 uint minQuorum = 2; //minimum number of responses to receive before declaring final result7 uint totalOracleCount = 3; // Hardcoded oracle count89 // defines a general api request10 struct Request {11 uint id; //request id12 string urlToQuery; //API url13 string attributeToFetch; //json attribute (key) to retrieve in the response14 string agreedValue; //value from key15 mapping(uint => string) anwers; //answers provided by the oracles16 mapping(address => uint) quorum; //oracles which will query the answer (1=oracle hasn't voted, 2=oracle has voted)17 }1819 //event that triggers oracle outside of the blockchain20 event NewRequest (21 uint id,22 string urlToQuery,23 string attributeToFetch24 );2526 //triggered when there's a consensus on the final result27 event UpdatedRequest (28 uint id,29 string urlToQuery,30 string attributeToFetch,31 string agreedValue32 );3334 function createRequest (35 string memory _urlToQuery,36 string memory _attributeToFetch37 )38 public39 {40 uint length = requests.push(Request(currentId, _urlToQuery, _attributeToFetch, ""));41 Request storage r = requests[length-1];4243 // Hardcoded oracles address44 r.quorum[address(0x6c2339b46F41a06f09CA0051ddAD54D1e582bA77)] = 1;45 r.quorum[address(0xb5346CF224c02186606e5f89EACC21eC25398077)] = 1;46 r.quorum[address(0xa2997F1CA363D11a0a35bB1Ac0Ff7849bc13e914)] = 1;4748 // launch an event to be detected by oracle outside of blockchain49 emit NewRequest (50 currentId,51 _urlToQuery,52 _attributeToFetch53 );5455 // increase request id56 currentId++;57 }5859 //called by the oracle to record its answer60 function updateRequest (61 uint _id,62 string memory _valueRetrieved63 ) public {6465 Request storage currRequest = requests[_id];6667 //check if oracle is in the list of trusted oracles68 //and if the oracle hasn't voted yet69 if(currRequest.quorum[address(msg.sender)] == 1){7071 //marking that this address has voted72 currRequest.quorum[msg.sender] = 2;7374 //iterate through "array" of answers until a position if free and save the retrieved value75 uint tmpI = 0;76 bool found = false;77 while(!found) {78 //find first empty slot79 if(bytes(currRequest.anwers[tmpI]).length == 0){80 found = true;81 currRequest.anwers[tmpI] = _valueRetrieved;82 }83 tmpI++;84 }8586 uint currentQuorum = 0;8788 //iterate through oracle list and check if enough oracles(minimum quorum)89 //have voted the same answer has the current one90 for(uint i = 0; i < totalOracleCount; i++){91 bytes memory a = bytes(currRequest.anwers[i]);92 bytes memory b = bytes(_valueRetrieved);9394 if(keccak256(a) == keccak256(b)){95 currentQuorum++;96 if(currentQuorum >= minQuorum){97 currRequest.agreedValue = _valueRetrieved;98 emit UpdatedRequest (99 currRequest.id,100 currRequest.urlToQuery,101 currRequest.attributeToFetch,102 currRequest.agreedValue103 );104 }105 }106 }107 }108 }109}Alles anzeigenKopieren
Wir würden gerne mehr Dokumentation über die Erstellung eines Oracle-Smart-Contract erhalten. Wenn Sie helfen können, erstellen Sie bitte eine PR!
Weiterführende Informationen
Artikel
- Was ist ein Blockchain-Oracle?(opens in a new tab) - Chainlink
- Was ist ein Blockchain-Oracle?(opens in a new tab) - Patrick Collins
- Dezentralisierte Oracle: Ein umfassender Überblick(opens in a new tab) - Julien Thevenard
- Implementieren eines Blockchain-Oracles auf Ethereum(opens in a new tab) - Pedro Costa
- Warum können Smart Contracts keine API-Aufrufe tätigen?(opens in a new tab) - StackExchange
- Warum wir dezentralisierte Oracles brauchen(opens in a new tab) - Banklos
- Sie wollen also ein Preis-Oracle benutzen(opens in a new tab) -samczsun
Videos
- Oracle und die Ausweitung der Blockchain-Nutzung(opens in a new tab) - Real Vision Finance
Lernprogramme