Have you ever think of calling third-party APIs in your smart contracts? It can be possible using the Oraclize service . The Oraclize service enables smart contracts to access data from an external environment.
This article describes the use of Oraclize with testrpc,truffle,ethereum-bridge. It also explains the smart contract code which calls multiple APIs using Oraclize service.
You all are familiar with the dapp development using testrpc and truffle.For using Oraclize service you have to install another too ‘Ethereum-bridge’ as a prerequisite for your service.
Download and install ethereum-bridge from the following Github link: https://github.com/oraclize/ethereum-bridge.
You also have to get the solidity contract for using oraclize service from the link https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.4.sol . You have to download the contract to the truffle contracts folder of your working directory, and rename the file to
usingOraclize.sol
and use the above contract in your contract by importing.
import "./usingOraclize.sol";
Start your testrpc.
Then start Ethereum-bridge in active mode using the following command :-
node bridge -H localhost:8545 -a 1
The tag
-a
defines an account which is used to deploy oraclize contracts.It will return you an OAR address.
Please add this line to your constructor. OAR=OraclizeAddrResolverI(0x5049063e4a7704ac155e4f1f42a4954bbef5bbde);
You have to update your smart contract constructor with the new address resolver generated.
pragma solidity ^0.4.11;
import "./usingOraclize.sol"; //Importing Oraclize
//Constructor
function TestOraclizeCall() { OAR= OraclizeAddrResolverI(0x5049063e4a7704ac155e4f1f42a4954bbef5bbde); // rest of your constructor code
} // your code
}
In the Oraclize service, you have to send a query to the Oraclize smart contract.Oraclize receive your query and make the corresponding request. Once the service receive the data from API , they call a callback function in the smart contract where you’ll be able to access and process the requested data.
pragma solidity ^0.4.16;
import "./usingOraclize.sol"; //Importing Oraclize
contract TestOraclizeCall is usingOraclize {
uint public price;
event Log(string text);
//Constructor
function TestOraclizeCall() { OAR = OraclizeAddrResolverI(0x5049063e4a7704ac155e4f1f42a4954bbef5bbde); }
function __callback(bytes32 _myid, string _result) { require (msg.sender == oraclize_cbAddress()); Log(_result); price = parseInt(_result, 2); }
function update() payable {
oraclize_query("URL","json(https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD).USD");
}
}
The above code is used to retrieve the current USD price for 1 ETH.The
oraclize_query
function is used to inform the Oraclize about the third party API.
The
oraclize_query
accept the first string parameter as the type of request.Here in the example we are using it as ‘URL’. The second parameter must be the query we are requesting.It is also possible to add a third parameter in order to make the query delayed.
You have to define the
payable
modifier in the function.The transaction originating from Oraclize to the
__callback
function pays a fee to the miner which include the transaction in a block, just like any other transaction. The miner fee is paid in Ether and it is calculated by taking the amount of gas which covers the execution costs of the transaction multiplied by the selected gas/ether price. Oraclize will set those parameters accordingly to the parameters specified in the smart contract, for contract-wide settings, and in the
oraclize_query
function, for query-specific settings. The miner fee for the callback transaction is taken from the contract balance when the query transaction is executed.
Note:- The first query made by the oraclize contract is free.
In the
__callback
function, the first parameter is the id of the request. The second parameter is the result of your request.
You have to compile and run the contract using truffle.
Handling of Multiple Requests :-
The first parameter ‘id’ in the
__callback
will handle different requests in the same callback function.The following is the example dealing with multiple requests.
pragma solidity ^0.4.16; import "./usingOraclize.sol"; contract TestOraclizeCall is usingOraclize { // oraclize callback types: enum oraclizeState { ForUSD, ForDistance } //Events event LOG_OraclizeCallbackForDistance( string result, ); event LOG_OraclizeCallbackForWeatherCondition( string result, ); // the oraclize callback structure: we use several oraclize calls. // all oraclize calls will result in a common callback to __callback(...). // to keep track of the different querys we have to introduce this struct. struct oraclizeCallback { // for which purpose did we call? {ForUSD | ForDistance} oraclizeState oState; } // Lookup state from queryIds mapping (bytes32 => oraclizeCallback) public oraclizeCallbacks; // constructor function TestOraclizeCall() { OAR = OraclizeAddrResolverI(0x5049063e4a7704ac155e4f1f42a4954bbef5bbde); } //Function for distance retrieval function distanceRetrieve() payable returns(bool sufficient) { bytes32 queryId = oraclize_query(10,"URL",strConcat("json(http://www.distance24.org/route.json?stops=us).distance")); oraclizeCallbacks[queryId] = oraclizeCallback(oraclizeState.ForDistance); return true; } function update() payable returns(bool sufficient) { bytes32 queryId = oraclize_query("URL","json(https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD).USD"); oraclizeCallbacks[queryId] = oraclizeCallback(oraclizeState.ForUSD); return true; } //Function callback function __callback(bytes32 myid, string result) { if (msg.sender != oraclize_cbAddress()) throw; oraclizeCallback memory o = oraclizeCallbacks[myid]; if (o.oState == oraclizeState.ForDistance) { LOG_OraclizeCallbackForDistance(result); } else if(o.oState == oraclizeState.ForUSD) { LOG_OraclizeCallbackForUSD(result); } } }
To keep track of the different queries we have used struct to hold and defined a mapping between queryids and state of query.