Oracles
Los oráculos son feeds de datos que conectan Ethereum a información del mundo real, externa a la blockchain (off-chain) para que puedas consultar datos en tus contratos inteligentes. Por ejemplo, las dapps de mercados de predicciones utilizan oráculos para establecer pagos basados en eventos. Un mercado de predicción podría pedirte que apostases tu ETH sobre el próximo presidente de los Estados Unidos. Utilizarán un oráculo para confirmar el resultado y pagar a los ganadores.
Requisitos previos
Asegúrate de estar familiarizado con los nodos, los mecanismos de consenso y la anatomía de los contratos inteligentes, especialmente con los eventos.
¿Qué es un oráculo?
Un oráculo es un puente entre la blockchain y el mundo real. Los oráculos actúan como API internas a la cadena de bloques (on-chain), que puedes consultar a fin de aportar información a los contratos inteligentes. Esta información podría ser muy variada: desde datos de precios hasta informes climáticos.
¿Por qué son necesarios?
En una blockchain como Ethereum, es necesario que cada nodo de la red sea capaz de replicar cada transacción y obtener el mismo resultado de manera garantizada. Las API introducen información potencialmente variable. Si le mandaras una cierta cantidad de ETH a alguien según un valor de $USD acordado y para ello utilizaras una API, la consulta (query) arrojaría un resultado diferente de un día para otro. Esto sin mecionar que la API podría ser hackeada o tornarse obsoleta. Si esto ocurriera, los nodos de la red no serían capaces de lograr un acuerdo sobre el estado actual de Ethereum, lo que llevaría a una ruptura del consenso.
Los oráculos resuelven este problema por medio de la publicación de información en la blockchain. De modo que cualquier nodo que replique la transacción usará los mismos datos inmutables que se publicaron en la red. Para ello, un oráculo típicamente constará de un contrato inteligente y algunos componentes externos a la cadena de bloques (off-chain) que consultan diversas API y posteriormente envían transacciones para actualizar los datos de los contratos inteligentes.
Seguridad
Un oráculo es tan seguro como las fuentes de datos que utiliza. Si una dapp utiliza Uniswap como oráculo para su fuente de precios del par ETH/DAI, es posible que un atacante altere el precio de Uniswap para manipular el entendimiento del precio actual que posee la dapp. Un ejemplo de cómo contrarrestar esta situación es un sistema de feed, como el utilizado por MakerDAO, que recopila información de precios proveniente de numerosos feeds de precio externos en lugar de simplemente apoyarse en una única fuente.
Uso
Oracles como un servicio
Servicios como Chainlink ofrecen oracles-as-a-service (oráculos como un servicio), que puedes utilizar. Este tipo de servicios cuentan con la infraestructura para realizar actividades como las siguientes:
- Obtener feeds de precio de criptomonedas en tu contrato inteligente
- Generar números aleatorios verificables (útiles para gaming)
- Hacer llamadas a API externas: Un caso de uso novedoso de esto es revisar reservas de wBTC
Aquí se presenta un ejemplo de cómo obtener el precio más reciente mediante tu contrato inteligente con ayuda de un feed de precios de 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}32Mostrar todoCopiar
Servicios de oráculo
Construir un contrato inteligente de oráculo
Aquí se presenta un ejemplo de un contrato inteligente de oráculos diseñado por Pedro Costa. Puedes encontrar anotaciones adicionales en su artículo: Implementación de un Oracle de la blockchain de 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}110Mostrar todoCopiar
Nos encantaría tener más documentación sobre la creación de un contrato inteligente de oráculos. Si puedes colaborar, crea una PR.
Más información
- Oráculos descentralizados: una visión general completa –Thevenard Julien
- Implementación de un Oráculo de Blockchain en Ethereum –Pedro Costa
- Oráculos –Ethub
Ayúdanos con esta página
Si eres un experto en el tema y quieres contribuir, edita esta página y esparce tu sabiduría.
Recibirás una acreditación y estarás ayudando a la comunidad de Ethereum.
Usar esta opción flexible plantilla de documentación
¿Tienes preguntas? Consúltanos en el canal #content en nuestro Servidor Discord
Editar página