天天看點

Setting up of Oraclize Service in Smart Contracts

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.

繼續閱讀