Oracoli
Gli oracoli sono feed di dati che collegano Ethereum a informazioni del mondo reale esternamente alla catena, in modo da poter interrogare i dati negli Smart Contract. Ad esempio, le dapp dei mercati predittivi utilizzano gli oracoli per effettuare i pagamenti in base a eventi. Un mercato predittivo potrebbe chiedere di puntare ETH sul prossimo presidente degli Stati Uniti. UserΓ un oracolo per confermare l'esito e pagare i vincitori.
Prerequisiti
Γ necessario avere familiaritΓ con nodi, meccanismi di consenso e anatomia degli Smart Contract, in particolare eventi.
Cos'Γ¨ un oracolo
Un oracolo Γ¨ un ponte tra la blockchain e il mondo reale. Agisce come API sulla catena, che Γ¨ possibile interrogare per ottenere informazioni da inserire negli Smart Contract. Si puΓ² trattare di qualsiasi cosa, da informazioni sui prezzi a previsioni meteo.
PerchΓ© sono necessari?
Con una blockchain come Ethereum Γ¨ necessario che ogni nodo della rete sia in grado di riprodurre ogni transazione e ottenere lo stesso risultato, garantito. Le API introducono dati potenzialmente variabili. Se hai inviato a qualcuno una quantitΓ di ETH basata su un valore concordato in $USD utilizzando un'API per i prezzi, la query restituirΓ un risultato diverso ogni giorno. Per non parlare del fatto che l'API potrebbe venire compromessa o essere obsoleta. In tal caso, i nodi della rete non sarebbero in grado di concordare lo stato corrente di Ethereum e, di fatto, verrebbe meno il consenso.
Gli oracoli risolvono questo problema pubblicando i dati sulla blockchain. Quindi ogni nodo che riproduce la transazione utilizzerΓ gli stessi dati immutabili che vengono pubblicati affinchΓ© siano visibili a tutti. A questo scopo, un oracolo in genere Γ¨ costituito da uno Smart Contract e da alcuni componenti esterni alla catena che possono interrogare le API e poi inviare periodicamente transazioni per aggiornare i dati dello Smart Contract.
Sicurezza
La sicurezza di un oracolo Γ¨ pari a quella delle sue origini sue fonte(i) di dati. Se una dapp utilizza Uniswap come oracolo per il suo feed di prezzo ETH/DAI, Γ¨ possibile per un aggressore spostare il prezzo su Uniswap al fine di manipolare la conoscenza della dapp del prezzo corrente. Un esempio per contrastare questa situazione ciΓ² Γ¨ un sistema di feed come quello usato da MakerDAO, che raccoglie i dati sui prezzi da una serie di feed di prezzo esterni anzichΓ© fare affidamento su una sola origine.
Utilizzo
Oracoli come servizio
Servizi come Chainlink offrono gli oracoli sotto forma di servizio. Hanno giΓ l'infrastruttura, ad esempio, per:
- ricevere feed sul prezzo di una criptovaluta nel contratto
- generare numeri casuali verificabili (utili per il gioco)
- chiamare API esterne β un nuovo uso in questo senso Γ¨ per controllare le riserve wBTC
Questo Γ¨ un esempio di come ottenere il prezzo piΓΉ aggiornato degli ETH in uno Smart Contract utilizzando un feed di prezzo Chainlink:
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}32Mostra tuttoCopia
Servizi per oracoli
Creare uno Smart Contract oracolo
Ecco un esempio di contratto oracolo di Pedro Costa. Puoi trovare ulteriori commenti nel suo articolo: Implementing a Blockchain Oracle on Ethereum.
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 lenght = requests.push(Request(currentId, _urlToQuery, _attributeToFetch, ""));41 Request storage r = requests[lenght-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}110Mostra tuttoCopia
Ci piacerebbe avere piΓΉ documentazione sulla creazione di uno Smart Contract oracolo. Se vuoi dare il tuo aiuto, crea una PR!
Letture consigliate
- Decentralised Oracles: a comprehensive overview βJulien Thevenard
- Implementing a Blockchain Oracle on Ethereum βPedro Costa
- Oracles βEthHub
Aiutaci con questa pagina
Se conosci l'argomento e vuoi contribuire, modifica questa pagina e condividi un po' del tuo sapere.
Il tuo nome verrΓ aggiunto ai crediti e aiuterai la community di Ethereum!
Usa questo flessibile modello di documentazione
Domande? Chiedicelo nel canale #content sul nostro server Discord
Modifica pagina