Oracles and how to work with Oraclize and Ethereum.
Blockchains are by their nature sand-boxed systems necessitating strict determinism in the manner of how they execute instructions and process data input. This is particularly important in the context of smart contracts as such, but also for allowing of the nodes running the network to be able to come to a consensus about the state of the blockchain. Everything in the chain must be objectively verifiable by all participating nodes using only the data in the blockchain itself -- introducing any non-deterministic behavior would make the whole network come to a halt.
However, events out 'in the wild' of the off-chain world are not necessarily deterministic (complex systems can be unpredictable) and can furthermore be tampered with. In the blockchain space, an oracle is a trusted entity which provides data feeds from the outside world (e.g., price feeds for assets, weather-related information, random number generation, etc.) as smart contracts cannot directly fetch the data they require. Oracles do that by watching the blockchain for concrete events and responding by bouncing the results of a query back to the contract, thereby interfacing with the outside world and enabling blockchains to react to observable events in the universe.
Oraclize in particular is the leading service specializing in providing data feeds on the blockchain in a manner which ensures authenticity via a cryptographic mechanism producing a document called authenticity proof.
The Oraclize Engine works by replicating the if-this-then-that logical contingency, i.e. it will execute some set of instructions if some other specified conditions are met. A valid Oraclize request should specify the following three arguments:
A data source type
- URL: enables access to a webpage or HTTP API endpoint.
- WolfgramAlpha: enables access to the WolfgramAlpha computational engine.
- IPFS: provides access to content stored in an IPFS file.
- random: provides untampered random bytes originating from a secured application running on a Ledger Nano S.
A query
- A query is an array of parameters specifying the data source type request. Additionally, a query may (and usually does) include a parsing helper (JSON, XML, HTML, etc.) for extracting a precise field in the API response. The oraclize_query function takes at least two arguments: the type of data-source (e.g., "URL") and the specific data-source with its corresponding parsing helper. For example:
oraclize_query("URL", "https://api.kraken.com/0/public/Ticker?pair=ETHXBT");
The above query fetches the price of ETH from the Kraken API. Or:
oraclize_query(60, "URL", "json(https://api.coinmarketcap.com/v1/ticker/ripple/");
In this example we get the price ticker of Ripple and have it updated every 60 seconds.
- Authenticity proof type: Authenticity proofs are optional and can be requested with the data via the oraclize_setProof function. When an authenticity proof is requested it must also nest a different callback function with the following arguments:
__callback(bytes32 queryId, string result, bytes proof)
The oraclize_setProof function has the following syntax:
oraclize_setProof(proofType_ | proofStorage_ )
Valid proofTypes parameters are:
proofType_NONE: default value
proofType_TLSNotary
proofType_Android
proofType_Native
proofType_Ledger
A smart contract which uses the Oraclize engine should inherit from the usingOraclize contract which is defined in the oraclizeAPI file in a dedicated Github repository. Namely, it should begin like this:
pragma solidity ^0.4.11;
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";
The interaction between Oraclize and an Ethereum contract is asynchronous and any request consists of two steps:
First, a specific transactional function of a smart contract is executed and broadcasted by a user. This function manifests to Oraclize which is continuously listening for such particular events.
Secondly, Oraclize will fetch/compute the result, sign and broadcast it back to the caller function. As specified by default, such transaction includes a __callback function which pays a fee to the miner to include the transaction in the next block (the cost of which should be correctly estimated as any unspent gas will be returned to Oraclize with no refund available).
Here is an example of a contract which uses Oraclize to fetch the last EUR/GBP from fixer.io APIs. The update process is initiated every time the function updatePrice() is called:
pragma solidity ^0.4.11;
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";
contract ExampleContract is usingOraclize {
string public EURGBP;
event LogPriceUpdated(string price);
event LogNewOraclizeQuery(string description);
function ExampleContract() payable {
updatePrice();
}
function __callback(bytes32 myid, string result) {
if (msg.sender != oraclize_cbAddress()) throw;
EURGBP = result;
LogPriceUpdated(result);
}
function updatePrice() payable {
if (oraclize_getPrice("URL") > this.balance) {
LogNewOraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee");
} else {
LogNewOraclizeQuery("Oraclize query was sent, standing by for the answer..");
oraclize_query("URL", "json(http://api.fixer.io/latest?symbols=USD,GBP).rates.GBP");
}
}
}
Oraclize provides a TestQuery page where one can test the correctness of a specific query, as well as an optimized version of the Remix IDE with added support for Oraclize-based contracts.
Additionally, a standardized oraclizeAPI package can be found on the Ethereum Package Management repository and installed via truffle by simply running:
truffle install oraclize-api
Pricing
First free request
The first call to Oraclize from a given contract, including the gas cost on the callback, are free of charge.
Call fee
The oraclize_query recovers the fee at run-time. This includes both the fee in USD (converted via a current exchange rate) for the data source and authenticity proof, and the amount of gas in Wei for the callback transaction. An URL query, for example, costs 0.01$, with an authenticity proof costing an additional 0.04 $. Here is the price list. For off-chain payments in various other currencies one can get in touch with Oraclize at info@oraclize.it.