Oracole
Oracolele sunt fluxuri de date care conectează Ethereum la informații din lumea reală, în afara lanțului, astfel încât să poți interoga datele în contractele tale inteligente. De exemplu, aplicațiile dapp de predicție de piață utilizează oracole pentru a deconta plăți pe baza evenimentelor. O piață de predicție îți poate cere să pariezi ETH pe următorul președinte al Statelor Unite. Vor folosi un oracol pentru a confirma rezultatul și pentru a plăti câștigătorilor.
Condiții prealabile
Asigură-te că ești familiar cu nodurile, mecanismele de consens și anatomia contractelor inteligente, evenimente speciale.
Ce este un oracol
Un oracol este o punte între blockchain și lumea reală. Acestea acționează ca API-uri pe lanț pe care le poți interoga pentru a obține informații în contractele inteligente. Acest lucru ar putea fi orice, de la informații de preț, la rapoarte meteorologice.
De ce este nevoie de oracole?
Cu un blockchain ca Ethereum ai nevoie de fiecare nod din rețea pentru a putea reda fiecare tranzacție și a termina cu același rezultat, garantat. API-urile introduc date potențial variabile. Dacă ai trimite cuiva o sumă de ETH în baza unei valori $USD convenită utilizând un API de preț, interogarea va returna un rezultat diferit de la o zi la alta. Ca să nu mai vorbim, API-ul ar putea fi piratat sau perimat. Dacă se întâmplă acest lucru, nodurile din rețea nu ar fi în măsură să se pună de acord asupra stării actuale a Ethereum, încălcând în mod efectiv consensul.
Oracolele rezolvă această problemă postând datele pe blockchain. De aceea, orice nod care redă tranzacția va utiliza aceleași date imuabile care sunt postate pentru ca toți să le vadă. Pentru a face acest lucru, un oracol este format de obicei dintr-un contract inteligent și unele componente din lanț care pot interoga API-urile, apoi trimit periodic tranzacții pentru a actualiza datele contractului inteligent.
Securitate
Un oracol este la fel de sigur ca sursele sale de date. Dacă o aplicație dapp folosește Uniswap ca oracol pentru fluxul său de preț ETH/DAI, un atacator ar putea să mute prețul pe Uniswap pentru a manipula înțelegerea de către dapp a prețului curent. Un exemplu al modului de combatere a acestui lucru este un sistem de alimentare precum cel folosit de MakerDAO, care strânge date despre prețuri dintr-o serie de fluxuri de prețuri în loc să se bazeze doar pe o singură sursă.
Utilizare
Oracolele ca serviciu
Servicii precum Chainlink oferă oracole-ca-serviciu pe care le poți utiliza. Au infrastructura pusă la dispoziție pentru a face lucruri precum:
- obținerea de fluxuri de preț cripto în contractul tău
- generarea de numere aleatorii verificabile (utile pentru jocuri)
- apelarea de API-uri externe – o nouă utilizare a acestui lucru este verificarea rezervelor wBTC
Acesta este un exemplu despre cum să obții cel mai recent preț ETH în contractul tău inteligent utilizând un flux de preț 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}32Afișează totCopiere
Servicii Oracle
Construiește un contract inteligent oracol
Iată un exemplu de contract oracol al lui Pedro Costa. Poți găsi adnotări suplimentare în articolul său: Implementarea unui Blockchain Oracol pe Ethereum.
1pragma solidity >=0.4.21 <0.6.0;23contract Oracle {4 Request[] requests; //lista cererilor adresate contractului5 uint currentId = 0; //creșterea ID-ului solicitării6 uint minQuorum = 2; //numărul minim de răspunsuri de primit înainte de declararea rezultatului final7 uint totalOracleCount = 3; // Număr de oracol codificat greu89 // definește o cerere API generală10 struct Request {11 uint id; //cerere id12 string urlToQuery; //API url13 string attributeToFetch; //atribut json (cheie) pentru a prelua în răspuns string agreedValue; //valoarea din cheie14 mapping(uint => string) anwers; //răspunsuri oferite de oracole15 mapping(address => uint) quorum; //oracole care vor interoga răspunsul (1 = oracolul nu a votat, 2 = oracolul a votat)16 }1718 //eveniment care declanșează oracolul în afara blockchain-ului19 event NewRequest (20 uint id,21 string urlToQuery,22 string attributeToFetch23 );2425 //declanșat atunci când există un consens cu privire la rezultatul final26 event UpdatedRequest (27 uint id,28 string urlToQuery,29 string attributeToFetch,30 string agreedValue31 );3233 function createRequest (34 string memory _urlToQuery,35 string memory _attributeToFetch36 )37 public38 {39 uint lenght = requests.push(Request(currentId, _urlToQuery, _attributeToFetch, ""));40 Request storage r = requests[lenght-1];4142 // adresa oracole codificată greu43 r.quorum[address(0x6c2339b46F41a06f09CA0051ddAD54D1e582bA77)] = 1;44 r.quorum[address(0xb5346CF224c02186606e5f89EACC21eC25398077)] = 1;45 r.quorum[address(0xa2997F1CA363D11a0a35bB1Ac0Ff7849bc13e914)] = 1;4647 //lansează un eveniment care va fi detectat de oracol în afara blockchain-ului48 emit NewRequest (49 currentId,50 _urlToQuery,51 _attributeToFetch52 );5354 // crește cererea id55 currentId++;56 }5758 //chemat de oracol pentru a înregistra răspunsul său59 function updateRequest (60 uint _id,61 string memory _valueRetrieved62 ) public {6364 Request storage currRequest = requests[_id];6566 //verifică dacă oracolul se află în lista oracolelor de încredere67 //și dacă oracolul nu a votat încă68 if(currRequest.quorum[address(msg.sender)] == 1){6970 //marcând că această adresă a votat71 currRequest.quorum[msg.sender] = 2;7273 //iterează prin „matricea” de răspunsuri până la o poziție dacă este liberă și salvează valoarea recuperată74 uint tmpI = 0;75 bool found = false;76 while(!found) {77 //găsește primul slot gol78 if(bytes(currRequest.anwers[tmpI]).length == 0){79 found = true;80 currRequest.anwers[tmpI] = _valueRetrieved;81 }82 tmpI++;83 }8485 uint currentQuorum = 0;8687 //iterează prin lista oracolelor și verifică dacă sunt suficiente oracole (cvorum minim)88 //au votat același răspuns ca și cel actual89 for(uint i = 0; i < totalOracleCount; i++){90 bytes memory a = bytes(currRequest.anwers[i]);91 bytes memory b = bytes(_valueRetrieved);9293 if(keccak256(a) == keccak256(b)){94 currentQuorum++;95 if(currentQuorum >= minQuorum){96 currRequest.agreedValue = _valueRetrieved;97 emit UpdatedRequest (98 currRequest.id,99 currRequest.urlToQuery,100 currRequest.attributeToFetch,101 currRequest.agreedValue102 );103 }104 }105 }106 }107 }108}109Afișează totCopiere
Ne-ar plăcea mai multă documentație privind crearea unui contract inteligent oracol. Dacă poți ajuta, creează un PR!
Referințe suplimentare
- Oracle descentralizat: o imagine de ansamblu cuprinzătoare –Julien Thevenard
- Implementarea unui Blockchain Oracle pe Ethereum –Pedro Costa
- Oracles –EthHub
Ajută-ne cu această pagină
Dacă ești expert pe această temă și dorești să contribui, editează această pagină și presar-o cu înțelepciunea ta.
Vei fi creditat și vei ajuta comunitatea Ethereum!
Utilizează acest șablon de documentație flexibil
Întrebări? Întreabă-ne pe canalul #content de pe serverul nostru Discord
Editare pagină