Financial Oracle Documentation

Contract name

EthernityFinancialOracle

Data Source

https://coinmarketcap.com/currencies/

Addresses

Mainnetwork: 0x604E244D5157c3ae734642364ace6C633fB1f278

Kovan: 0xB86a23c8D2896F253bFf6d3F79E18c08D5b6956D

Rinkeby: 0xE89d64c24BF13965D38368F3FDf2611dFDE1322E

ABI of EthernityOracle

Interface

In order to use Ethernity Financial Oracle from within a contract, you must copy or import the following interface into your contract.

contract EthernityFinancialOracle {
event Request (string _coin , string _againstCoin , address _address , uint _gasPrice , uint _gasLimit);
// Requests (you only need to have the ones that you will use it)
function requestEtherToUSD(bool _callBack , uint _gasPrice, uint _gasLimit) payable;
function requestCoinToUSD(string _coin , bool _callBack , uint _gasPrice , uint _gasLimit) payable;
function requestRate(string _coin, string _againstCoin , bool _callBack , uint _gasPrice , uint _gasLimit) payable;
// Following are optionals. You can have the ones that you will use
function getRefund();
// Getters
function getResponse() public constant returns(string _response);
function getPrice(uint _gasPrice , uint _gasLimit) public constant returns(uint _price);
function getBalance() public constant returns(uint _balance);
uint public feePrice;
uint public gasLimit;
uint public gasPrice;
}


Usage

Basic usage for the Rinkeby test network:

function callOracle {
// Define Oracle (using Rinkeby address) invoking the interface
EthernityFinancialOracle EFOracle = EthernityFinancialOracle(0xE89d64c24BF13965D38368F3FDf2611dFDE1322E);
// Make request
EFOracle.requestEtherToUSD(true);
}

// Function to be called by EFOracle when request is ready
function EFOcallBack(string _response) {
require(msg.sender == 0xE89d64c24BF13965D38368F3FDf2611dFDE1322E);
// Here you can process the received _response
}


Payment

Payment is mandatory for EthernityFinancialOracle to trigger a transaction carrying our response to your query. The request price includes a fixed fee for EthernityFinancialOracle, plus an amount that EthernityFinancialOracle will use to pay gas for the transaction.


There are two ways to pay for your requests.


1. In any moment prior to making your request, you can deposit Ether into the contract with a simple send. Such Ether will be automatically stored as credit balance for your address. You can make as many additional requests as desired from the same address, as long as you have balance enough. You can check your balance at any moment with:

getBalance();

Any excedent balance that has not been used to pay for your requests can be refunded at any moment with:

getRefund();

2. You can send your payment along with each of your requests. It can be done programmatically from solidity:

requestEtherToUSD.value(_payment)(true);

(where _payment should indicate the amount to send in weis). Or you can make a manual transaction from Myetherwallet or other system that allows you to send a value.



Calculating payment

The price of each request is a single value composed of three variables:


feePrice, gasPrice and gasLimit.


The first variable is the amount that EthernityFinancialOracle will receive as a payment, and can not be modified. It is now set at 0.0005 ethers, and may change in the future. The second and third variables are the values that will be used by EthernityFinancialOracle as a network gas fee to send the answer back. You can set those values at your will, or you can rely on the default ones (20 gwei for gas price and 60.000 for limit = 0.0012 ether). Note that EthernityFinancialOracle will retain any remaining gas resulting from this transaction. Thus, the total price for a request with default values is 0.0017 ether.


There are two ways to calculate the amount to pay, depending if you want to use default values for gasPrice and gasLimit or if you want to set them at your will.


a. Calculating request price using default values for gasPrice and gasLimit:

getPrice();

It will tell you how much will be taken from your balance with each default request (or how much you need to send as value with each request).


b. Calculating request price for specific gasPrice and gasLimit:


To retrieve the total price for a request with a specified gasPrice and a gasLimit:

getPrice(gasPrice , gasLimit);

This will give you the total price for the gas, plus the price of the fee, which will be the total that will be discounted from your balance (or expected to be sent as value with the request) when you do a request with those values. To do a request specifying gas price and gas limit, the function is:


This will tell EthernityFinancialOracle to use such values to pay the fee for the transaction with your required answer. For it to work, you have to send enough balance to

requestEtherToUSD(true , gasPrice , gasLimit);

EthernityFinancialOracle first, or you can send it along with the request with a command similar to this one:

requestEtherToUSD.value( getPrice(gasPrice , gasLimit) )(true , gasPrice , gasLimit);

IMPORTANT: Note that the request price will not be refunded, no matter if the request was successful or not, and no matter if the gas was totally consumed or not by the answer. Any value sent that surpasses the request price will be stored as a credit for that address, and can consulted and used or refunded at any time.



Request types

There are two ways to get a request: passive or active. You can choose the kind of request with the first argument of the request. True for a passive callback; false (or just nothing) for an active way. These are the differences:


Passive way:


EthernityFinancialOracle will send you the answer by calling EFOcallBack(string _response) in your contract with the answer data in the _response variable.


Advantages: private, you can regulate the cost of the calling by making your callback function to fit your needs. Disadvantages: you need to use a contract to call the Oracle.


Active way:


EthernityFinancialOracle will store the answer in an internal mapping and it will write the event Response (address _address , string _response) in the blockchain. You should watch for the event, and then you can retrieve the data from the same event, or by calling getResponse();


Advantages: it may be cheaper than using a callback function (approx 30.000 gas consumed / 40.000 the first time); you can make calls from a simple address (no need to be a contract). Disadvantages: data will be public, and you have to watch for the event before reading the data.



Requests

To get actual Ether price in USD:

requestEtherToUSD (bool _callBack , uint _gasPrice , uint _gasLimit);

To retrieve the rate of any coin in USD:

requestCoinToUSD (string _coin , bool _callBack , uint _gasPrice , uint _gasLimit);

To retrieve the rate of any coin against a fiat currency:

requestRate (string _coin , string _currency , bool _callBack , uint _gasPrice , uint _gasLimit);

NOTE: If you send a new request before receiving the answer for the first one, the second one will overwrite the previous one, but you will be charged the price for both of them.




Functions and getters

Functions:


requestEtherToUSD (bool _callBack , uint _gasPrice , uint _gasLimit)

It will create a request for the actual price of Ether in USD. All parameters are optional.


If _callBack is true, the answer will be a callback. If it’s false or absent, answer will be stored in a mapping and in a log event.


If _gasPrice and _gasLimit are specified, they will be used for EthernityFinancialOracle to make the callback (or to store the answer). If they are not specified, EthernityFinancialOracle will use the default values. Note that you have to send the total value (gas plus fee) along with the request, or you can fill your balance before by just sending ether to the contract. You can also consult how much you have to pay in any case with the corresponding getters (described below).


requestCoinToUSD (string _coin , bool _callBack , uint _gasPrice , uint _gasLimit)

To request the rate of any cryptocoin in USD. You have to specify the coin in the first parameter. The following parameters are optionals, same as in the previous case.


requestRate (string _coin , string _currency , bool _callBack , uint _gasPrice , uint _gasLimit)

To request the rate of any coin against any currency. You have to specify both coins and currency in the first two parameters.


Valid values for coins (you can retrieve valid id’s from https://api.coinmarketcap.com/v1/ticker/):


i.e.: “bitcoin”, ”ripple”, ”bitcoin-cash”, ”litecoin”, “cardano”, “neo”, “stellar”, “eos”, “monero”, “nem”, “dash”, “iota”, “tron”, “tether”, “ethereum-classic”, “vechain”, “lisk”, “nano”, “omisego”, “qtum”, “bitcoin-gold”, “icon”, “zcash”, “binance-coin”, “populous”, “digixdao”, “steem”...


Valid values for currencies:


"AUD", "BRL", "CAD", "CHF", "CLP", "CNY", "CZK", "DKK", "EUR", "GBP", "HKD", "HUF", "IDR", "ILS", "INR", "JPY", "KRW", "MXN", "MYR", "NOK", "NZD", "PHP", "PKR", "PLN", "RUB", "SEK", "SGD", "THB", "TRY", "TWD", "ZAR"


getRefund()

It will send you back your available balance.



Getters:


getPrice()

It shows the total price you have to pay for each default request. You can send that value as a value with the request, or you can have it previously stored in your balance at the Oracle by sending ethers to it.


getPrice(gasPrice , gasLimit)

It shows the total price of each request if you specify a gas limit and gas price for the callback. You can choose both values, having in account that they will be used to call to your callback function or to write a mapping and a log event. If the amount is not enough for the call, the transaction with the answer will fail and you will lose the payment of your request


feePrice()

It shows the actual price of the fee that will be charged with each request. It is the amount to pay for the service of EthernityFinancialOracle and it is part of the total price to pay for each request (the other parts are the gas needed for the callback).


gasPrice(), gasLimit()

It shows the default gasPrice and gasLimit that will be used by the oracle to send you back the result (or to store it in a mapping and a log), except that you specify the price and limit you want. It is part of the total price of the request (the other part is the fee).


getBalance()

It shows your available credit that will be used for your requests.


getResponse()

It shows the answer of the last request from your address (it only works when you specify _callBack as false so the answer is logged and stored in a mapping).




Functional example

Contract name: Caller

Simple way to use this example contract:

- getPrice() will show the necessary value to send along with the request.

- request() will generate a request (you have to pay the value that you got with getPrice() along with the transaction

- response() will show the answer once Oracle has answered.


You can choose any values for gasPrice and gasLimit that you consider necessary for the Oracle to call your callBack function


- getPrice(gasPrice , gasLimit) will show the total price you have to pay for each request

- request(gasPrice , gasLimit) along with the value obtained before.

- response() will show the answer once Oracle has answered.


You can check the process at the Oracle contract.


Complete Caller code:


pragma solidity ^0.4.18;
contract EthernityFinancialOracle {
function requestEtherToUSD(bool _callBack , uint _gasPrice, uint _gasLimit) payable;
function getPrice(uint _gasPrice,uint _gasLimit) public constant returns(uint _price);
event Request (string _coin , string _againstCoin , address _address , uint _gasPrice , uint _gasLimit);
}

contract Caller {
string public response; // Public getter to see the answer
address public oracleAdd; // Oracle address
address public owner;

modifier onlyOwner{
require(msg.sender == owner);
_;
}
function Caller() {
owner = msg.sender;
oracleAdd = 0xE89d64c24BF13965D38368F3FDf2611dFDE1322E; // Rinkeby address
}
function EFOcallBack(string _response) {
require(msg.sender == oracleAdd);
response = _response;
}
// fallback function to receive Ethers
function() payable {
}

// Main function: request

function request(uint _gasPrice,uint _gasLimit) onlyOwner payable {
EthernityFinancialOracle oracle = EthernityFinancialOracle(oracleAdd);
oracle.requestEtherToUSD.value(oracle.getPrice(_gasPrice,_gasLimit))(true,_gasPrice,_gasLimit);
}

// Get actual price

function getPrice(uint _gasPrice,uint _gasLimit) public constant returns(uint _price) {
EthernityFinancialOracle oracle = EthernityFinancialOracle(oracleAdd);
return oracle.getPrice(_gasPrice,_gasLimit);
}

// Admin

function setOracleAdd(address _address) onlyOwner {
oracleAdd = _address;
}
}




Detailed description of the system


Every request is made of two main transactions.


1st transaction. Request

Request is a transaction originated by the user (or a user’s contract) to the Oracle address.


Fee: the fee for the ethereum network is the same of any ethereum transaction. Some wallets calculate it automatically. If it’s done manually, it’s recommended to put a gas limit of 120,000. It will be used between 75,000 to 105,000. The gas not used will be refunded to the originating address, same way as any other ethereum transaction.

Data The transaction data is the call to the request function at Oracle (requestEtherToUSD, requestCoinToUSD , etc). The function can be called with or without arguments. The first argument (_callBack) is a boolean that specify the desired type of response: if it’s true, Oracle will try to call a EFOcallBack(string) function at the originating address with the answer. If it’s false or if it’s not set, Oracle will store the answer in its own address and will generate an event log.


The second and third arguments will define the price to be charged for the request. This price is composed of a fee plus an amount that will be used by Oracle to send the answer back: if they are not present, Oracle will charge the default price (which can be retrieved with getPrice()) and will use its default values for gasPrice and gasLimit for the answer (which can be retrieved with gasPrice() and gasLimit() getters). If they are set, Oracle will use those values to set the price for its answer. The total price that will be charged to the originating address can be retrieved with getPrice(_gasPrice,_gasLimit), which calculates the price to pay to the Oracle based on those values, plus the fee for Oracle.


This is a delicate point here: if you pay more price than the required, the excedent will be added to your account balance: Oracle will only charge you the gas limit and gas price you specified (or the default ones, if you didn’t specified them) plus the fee for Oracle. But if the Oracle’s answer consumes less gas than you specified, the excedent will not be refunded nor stored as balance: it will be returned by the ethereum network to the Oracle, and will be used for administrative purposes.


Value: if you have a previous balance in your Oracle account and it’s enough to pay for the transaction, you don’t need to send value with the request. On the contrary case, the request should be accompanied of a value to pay the Oracle. The price of the request will depend on the arguments you passed to the request function, as it’s explained above. From that price, Oracle will take a fee as a payment for itself, and will use the specified gas price and gas limit to send the answer back. As we have noted before, if you sent more value than the calculated price, the excedent will be stored as part of your balance. In other hand, if the transaction with the answer consumes less gas than specified, the excedent will not be refunded to the user, but will remain in the Oracle for administrative purposes.


2nd transaction. Answer


Once the Oracle processes your request, it will retrieve the answer and it will send it in a ethereum transaction. This transaction is originated in a third address (registered as oracleAddress) that will send the answer to the oracle contract.


Fee: To set the gas price and gas limit for the ethereum network to send the answer, Oracle will use either its default values, or the values the user passed with the request. If the gas price or limit was set too low, the transaction may fail.


Data: oracleAddress will call setResponse function at Oracle contract with the data of the response in the _response string.


If the boolean argument sent with the request was false or absent, Oracle will generate the event Response(address,string) with the originating address and the answer as values, and will store the value in a mapping that can be accesed with the getter getResponse() called from the originating address. This transaction generally consumes 40,000 gas the first time from an address and 30,000 gas the following ones.


If the first argument sent with the request is true, Oracle will make an internal call to ECOcallBack(string) function in the originating address at the user contract. In this case, the gas consumption of this 2nd transaction including the internal one, will depend upon the function in the originating address. Its cost in gas can be calculated by making trials in Kovan or Rinkeby.




ABI of EthernityOracle:


[{"constant":false,"inputs":[{"name":"_user","type":"address"}],"name":"desBan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getBalance","outputs":[{"name":"_balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getResponse","outputs":[{"name":"_response","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_feePrice","type":"uint256"}],"name":"setFeePrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"feePrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_gasPrice","type":"uint256"},{"name":"_gasLimit","type":"uint256"}],"name":"getPrice","outputs":[{"name":"_price","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_user","type":"address"},{"name":"_result","type":"string"}],"name":"setResponse","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_coin","type":"string"},{"name":"_againstCoin","type":"string"},{"name":"_callBack","type":"bool"},{"name":"_gasPrice","type":"uint256"},{"name":"_gasLimit","type":"uint256"}],"name":"requestRate","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_coin","type":"string"},{"name":"_callBack","type":"bool"},{"name":"_gasPrice","type":"uint256"},{"name":"_gasLimit","type":"uint256"}],"name":"requestCoinToUSD","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_user","type":"address"}],"name":"ban","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"emergencyFlush","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"changeOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"users","outputs":[{"name":"response","type":"string"},{"name":"callBack","type":"bool"},{"name":"asked","type":"bool"},{"name":"balance","type":"uint256"},{"name":"banned","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oracleAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"getRefund","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_gasPrice","type":"uint256"}],"name":"setGasPrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"collectedFee","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_gasLimit","type":"uint256"}],"name":"setGasLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newOracleAdd","type":"address"}],"name":"changeOracleAdd","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"gasLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_address","type":"address"}],"name":"getBalance","outputs":[{"name":"_balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_callBack","type":"bool"},{"name":"_gasPrice","type":"uint256"},{"name":"_gasLimit","type":"uint256"}],"name":"requestEtherToUSD","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"gasPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_coin","type":"string"},{"indexed":false,"name":"_againstCoin","type":"string"},{"indexed":false,"name":"_address","type":"address"},{"indexed":false,"name":"_gasPrice","type":"uint256"},{"indexed":false,"name":"_gasLimit","type":"uint256"}],"name":"Request","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_address","type":"address"},{"indexed":false,"name":"_response","type":"string"}],"name":"Response","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_error","type":"string"}],"name":"Error","type":"event"}]



Ethernity Ethereum Consulting & Development are focused on Ethereum, Solidity and Blockchain technologies, plus the necessary technologies to deliver full stack dApps. We also provide back-end programming services in Python and Node js.

Our Newsletter

Stay updated with Crypto & Blockchain latest News.

Contact Info

La Fuente 2327

Montevideo, Uruguay

+59897688921

castiglionemaldonado@gmail.com

Mon-Sat 12pm-10pm UTC