Giter Club home page Giter Club logo

ethereum-api's Introduction

Provable Ethereum API Join the chat at https://gitter.im/oraclize/ethereum-api Info@Provable.xyz HitCount MIT Licence Build Status

 

Thanks to this Ethereum API, enriching your smart-contracts with external data using Provable is very easy!

In Solidity it is as simple as inheriting the usingProvable contract that you'll find in this repository.

This will provide your contract with functions like provable_query(...), which make it trivial for you to leverage our oracle technology straight away.

If you're using the Remix IDE it's even easier still - simply import the latest version of Provable into your contract like so:

import "github.com/provable-things/ethereum-api/provableAPI.sol";

Or if you need a specific version of the API, import that directly via:

import "github.com/provable-things/ethereum-api/contracts/solc-v0.8.x/provableAPI.sol";

There are versions of the API targetting the following solc compilers:

solc-v0.4.25
solc-v0.5.x
solc-v0.6.x
solc-v0.8.x

To learn more about the Provable technology, please refer to our documentation here.

 


 

💻 See It In Action!

For working examples of how to integrate the Provable API into your own smart-contracts, head on over to the Provable Ethereum Examples repository. Here you'll find various examples that use Provable to feed smart-contracts with data from a variety of external sources.

There are even some examples here showing you how you can use Provable in a local Truffle development environment!

 


 

📣 Get In Touch!

If you want to ask us something, or tell us something, there's loads of ways to get in touch:

We have a Twitter

And a Gitter

Or a Website

Alongside a Youtube

Plus a Github

 


 

☢️ A Note Regarding Serpent:

💀 CAUTION: It is highly recommended to avoid using Serpent, especially in production. The serpent version of the Provable API herein remains for historical reasons but support for it is no longer maintained. Serpent is considered outdated and audits have shown it to be flawed. Use it at your own risk!

ethereum-api's People

Contributors

adamjlemmon avatar allemanfredi avatar bertani avatar d-nice avatar gitter-badger avatar gskapka avatar marcogiglio avatar nya1 avatar oliviera9 avatar polybioz avatar shubhamtatvamasi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ethereum-api's Issues

Random number proof verification fails if delay is set

If oraclize_newRandomDSQuery(delay, N, callbackGas); is executed with a delay different than 0, when the callback is fired, the oraclize_randomDS_proofVerify__returnCode call will fail verification of proof.

The expected behavior would be for the callback to properly verify the random number generated even if it was delayed.

Tested on ropsten. Here's the code to reproduce it.
call scheduleRandomNumOnCreation(0); and it will work properly. -reaches event Testeo(2014)-
call scheduleRandomNumOnCreation(30); and the callback will fail the proof verification

pragma solidity ^0.4.4;

import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";

contract Raffle is usingOraclize{

  event Testeo(uint _number);

  function Raffle(){
    scheduleRandomNumOnCreation(0);
  }

   function __callback(bytes32 _queryId, string _result, bytes _proof)
  {
      Testeo(1022);
      // If we already generated a random number, we can't generate a new one.
      // if we reach this point successfully, it means that the attached authenticity proof has passed!
      require (msg.sender == oraclize_cbAddress());

      //Before using the random number we have to check if the minimum amount of participants was reached.
      //If not, we should abort. LATER, when dealing with money, we should also return funds to the participants.

      if (oraclize_randomDS_proofVerify__returnCode(_queryId, _result, _proof) != 0) {
        Testeo(1023);
          // the proof verification has failed, do we need to take any action here? (depends on the use case)
      } else {
          // the proof verification has passed
          Testeo(1024);
          // for simplicity of use, let's also convert the random bytes to uint if we need
          uint maxRange = 100; // this is the highest uint we want to get. It should never be greater than 2^(8*N), where N is the number of random bytes we had asked the datasource to return
          uint randomNumber = uint(sha3(_result)) % maxRange; // this is an efficient way to get the uint out in the [0, maxRange] range
          Testeo(randomNumber);
      }
    }

  function scheduleRandomNumOnCreation(uint _timeFromNow) internal{
    //Called on raffle constructor only
    oraclize_setProof(proofType_Ledger); // sets the Ledger authenticity proof in the constructor
    uint N = 4; // number of random bytes we want the datasource to return
    uint delay = _timeFromNow; // number of seconds to wait before the execution takes place
    uint callbackGas = 200000; // amount of gas we want Oraclize to set for the callback function
    bytes32 queryId = oraclize_newRandomDSQuery(delay, N, callbackGas); // this function internally generates the correct oraclize_query and returns its queryId
    
  }
  
}

deprecation of throw syntax

As of 0.4.10 throw has been deprecated in favor of assert(), require() and revert(). Would a PR to replace throw accordingly in the ethereum API be welcomed?

I'm new to Solidity so I didn't know if throw was being kept for backwards compatibility or another reason.

Kovan support

Is Oraclize supporting Kovan any time soon?

Thanks

How to reset and re-enter variables made by oraclize?

Hello guys. I tried to make token network using oraclize to give token by youtube view count.

https://github.com/ingyunson/token-transfer-using-orzclize/blob/5197e34ecd2a41d8694202c01d3a4ac8c0a9c5f0/youtube_viewcount.sol#L49

In my code, it works when it deployed on the first time.
After run the function YoutubeViews, I cannot reset and re-enter new information using same function.

When I remarked oraclize part(which are line 49 and 50), it works well so I think the problem from my oraclize lines.

If someone knows about this, please help me.

Sincery.

Incompatible SOLC warning

Hey Folks. Super new to this anyone know why I'm getting this error in Remix?
/* INCOMPATIBLE SOLC: import the following instead: "github.com/oraclize/ethereum-api/oraclizeAPI_0.4.sol" */ function f(bytes calldata x) external;

my solidity version is pragma solidity ^0.4.25 and my github import statement is just below perhaps the bug is here somwhere?
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";

I get the same bug when i use solidity 0.5.1 so that doesn't solve it.

I'm not doing anything too intense just trying to follow this tutorial from youtube https://www.youtube.com/watch?v=J05DBPdkeAo

Thank You and happy provide the rest of my code if anyone needs it to help me solve the bug!

Truffle install fails

When I try to install the Oraclize EthPM package in Truffle, I get the following error:

Error: Unknown server response 504 when downloading hash QmWrjVJkSUhpBbM7TR4hN1kxiuFjzhvEobEwtLgquaCfPi
    at ClientRequest.<anonymous> (/Users/.../node_modules/truffle/build/cli.bundled.js:132502:16)
    at Object.onceWrapper (events.js:293:19)
    at emitOne (events.js:96:13)
    at ClientRequest.emit (events.js:191:7)
    at HTTPParser.parserOnIncomingClient (_http_client.js:522:21)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:99:23)
    at TLSSocket.socketOnData (_http_client.js:411:20)
    at emitOne (events.js:96:13)
    at TLSSocket.emit (events.js:191:7)
    at readableAddChunk (_stream_readable.js:178:18)
error Command failed with exit code 1.

Installing a different package (I tried Zeppelin) does work.
I'm using Truffle version 3.2.8

The computation data source does not support multi-stage builds

This is not an issue with the Ethereum API per se, so let me know if I should report it somewhere else.

Basically, I found out that the computation data source does not support the "multi-stage builds" feature that has been available in Docker since 17.05.

If your Docker image uses multi-stage builds, the result passed to your __callback will be an empty string.

Random datasource doesn't work in rinkeby

oraclize.getPrice() returns with invalid opcode when oraclize_setProof() is not set

The documentation says the default is proofType_NONE
However when I call oraclize.getPrice() from browser-solidity then it returns with "VM Exception: invalid opcode" when I don't have proof set.
If I add oraclize_setProof(proofType_NONE); to constructor then it works fine.
Solidity version: 0.4.12-nightly.2017.5.4+commit.025b32d9.Emscripten.clang
Code to reproduce:

/*
  Oraclize.it decrypt datasource test
*/

pragma solidity ^0.4.0;
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";

contract CryptTest is usingOraclize {
    
    string public callBackResult;
    bytes32 public qId;
    bytes32 public resId;
    
    event newOraclizeQuery(string description);
    event newResult(string result);
    
    function CryptTest() payable {
        // oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
       // setProof not called causing invalid opcode for getDecryptPrice 
      // but If you uncomment the following line then it works
        // oraclize_setProof(proofType_NONE); 
    }

    function __callback(bytes32 myid, string result) {
        if (msg.sender != oraclize_cbAddress()) throw;
        resId = myid;
        callBackResult = result;
        newResult(callBackResult);
    }
    
    function getDecryptPrice() constant returns (uint){
        return oraclize.getPrice("decrypt") ;
    }
    
    function decrypt(string inp) payable {
        uint requiredBal = getDecryptPrice() ;
        if ( requiredBal> this.balance) {
            newOraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee" );
        } else {
            newOraclizeQuery("Oraclize query was sent, standing by for the answer..");
            qId = oraclize_query( "decrypt", inp);
        }
    }
} 

Just a minor annoyance, documenting if someone else happens to bump into it.

Mismatching queryId and myid in Remix JavascriptVM.

Wasn't sure where to open this issue, but I'm having troubles in mapping values from the query and then getting them in the __callback(). I.e. senderAddress[queryId] is different than senderAddress[myid] (the latter is 0x0 instead of showing the query msg.sender address).

In the testnets, everything is working fine. I wish you guys could fix this in the Remix JavascriptVM as well.

Possible improvement

With Tweedentity, since we try to let the user spend as less as possible for the gas, we continue to experience the same issue with Oraclize:

the query is called but the callback is triggered in the average 10 hours later or more.

I suppose that the reason why you prioritize transactions with higher gas price depends on how Ethereum manages multiple transactions from the same wallet, waiting for the confirmation of the one with the lower nounce before confirming the following. This implies that if you get stuck with a transaction at a low gas price the entire address would be blocked if you don't reverse the first transaction.

A solution could be that you use many wallets to call the callback.
Ideally, I would set a wallet for any possible gas price, but even a reasonable interval should be much better than the current approach. For example, wallet 0xAA could trigger all the callbacks with gas price > 60, 0xBB the callback with gas price more than 50, etc.

The code in the __callback could be something like

function __callback(bytes32 myid,string result)   {
    require(isAValidOraclizeCBAddress(msg.sender));
...

What do you think?

Next deployment todos

  • Make gasprice variable public in connector
  • Make getPrice constant in connector
  • Consider making reqc in connector public at next update, as well as gasprice and other variables. e.g. seeing gasprice would help eth-bridge figure out if it needs to send a tx to change gasprice.

Issues with Ropsten/Rinkeby

Is there any issues with the testnets? I am not receiving an Oraclize callback neither on Ropsten nor on Rinkeby.

Support encrypted arguments for computation

I need this. I will work in tests without encryption, but I can relay on some future way of sending encrypted arguments to a computation? Or make nested accept some string encoded arguments for computation.
Example:

encryptedArg = "${[decrypt] xxxx}:${[decrypt] xxxx}" notice that it has a : that is plain-text.
plainArg = "some-arg,other-arg"
oraclize_query("computation", [scriptIPFSUrl, plainArg, encyptedArg]);`

Oracle failing in online compiler

Hi there for some reason the oracle fails to send a query when i try run it on the online remix compiler

i tried the example contracts and this is the message i get

VM error: revert.
revert The transaction has been reverted to the initial state.
Note: The constructor should be payable if you send value. Debug the transaction to get more information.

it fails on this line in the api's contract

OraclizeI oraclize;
modifier oraclizeAPI {
if((address(OAR)==0)||(getCodeSize(address(OAR))==0))
oraclize_setNetwork(networkID_auto);

    if(address(oraclize) != OAR.getAddress()) //it fails here
        oraclize = OraclizeI(OAR.getAddress());

    _;
}

I was running the WolframAlpha example this happens with all the contracts

OraclizeAPI not compatible with solc ver > 4.0

When I try to compile with Truffle 2.0.1 which uses solc >4.0 it raises multiple compilation errors.

  1. Error: Expected token Semicolon got 'RBrace'

This is the due to the fact that you now have to append semicolon like _; in modifier.

  1. Error: Member "value" not found or not visible after argument-dependent lookup

After fixing #1, I still get the following errors.

OraclizeI.sol:97:16: Error: Member "value" not found or not visible after argument-dependent lookup in function (uint256,string memory,string memory) returns (bytes32) - did you forget the "payable" modifier?
        return oraclize.query.value(price)(0, datasource, arg);
               ^------------------^

Rejecting scheduled request

Using Oracle we can call scheduled functions. But is it possible to cancel scheduled function? I mean, for example, if I scheduled an function that updates something in my contract in 10 minutes but in 5 minutes I changed my mind, I don't need update something. In this case, can I cancel scheduled function?

Error deploying required libraries: Invalid bytecode format.

when deploying below code in oraclize online ide(no compile error), press create button, comes out "Error deploying required libraries: Invalid bytecode format."

but in remix, don't have this error, deploy successed, so either the library have problem or oraclize ide have problem, please check.

pragma solidity ^0.4.18;

// <ORACLIZE_API_LIB>
/*
Copyright (c) 2015-2016 Oraclize SRL
Copyright (c) 2016 Oraclize LTD

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

contract OraclizeI {
address public cbAddress;
function query(uint _timestamp, string _datasource, string _arg) external payable returns (bytes32 _id);
function query_withGasLimit(uint _timestamp, string _datasource, string _arg, uint _gaslimit) external payable returns (bytes32 _id);
function query2(uint _timestamp, string _datasource, string _arg1, string _arg2) public payable returns (bytes32 _id);
function query2_withGasLimit(uint _timestamp, string _datasource, string _arg1, string _arg2, uint _gaslimit) external payable returns (bytes32 _id);
function queryN(uint _timestamp, string _datasource, bytes _argN) public payable returns (bytes32 _id);
function queryN_withGasLimit(uint _timestamp, string _datasource, bytes _argN, uint _gaslimit) external payable returns (bytes32 _id);
function getPrice(string _datasource) public view returns (uint _dsprice);
function getPrice(string _datasource, uint gaslimit) public view returns (uint _dsprice);
function setProofType(byte _proofType) external;
function setCustomGasPrice(uint _gasPrice) external;
function randomDS_getSessionPubKeyHash() external view returns(bytes32);
}
contract OraclizeAddrResolverI {
function getAddress() public view returns (address _addr);
}
library oraclizeLib {

function proofType_NONE()
public
pure
returns (byte) {
    return 0x00;
}

function proofType_TLSNotary()
public
pure
returns (byte) {
    return 0x10;
}

function proofType_Android()
public
pure
returns (byte) {
    return 0x20;
}

function proofType_Ledger()
public
pure
returns (byte) {
    return 0x30;
}

function proofType_Native()
public
pure
returns (byte) {
    return 0xF0;
}

function proofStorage_IPFS()
public
pure
returns (byte) {
    return 0x01;
}

//OraclizeAddrResolverI constant public OAR = oraclize_setNetwork();

function OAR()
public
view
returns (OraclizeAddrResolverI) {
    return oraclize_setNetwork();
}

//OraclizeI constant public oraclize = OraclizeI(OAR.getAddress());

function oraclize()
public
view
returns (OraclizeI) {
    return OraclizeI(OAR().getAddress());
}

function oraclize_setNetwork()
public
view
returns(OraclizeAddrResolverI){
    if (getCodeSize(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed)>0){ //mainnet
        return OraclizeAddrResolverI(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed);
    }
    if (getCodeSize(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1)>0){ //ropsten testnet
        return OraclizeAddrResolverI(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1);
    }
    if (getCodeSize(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e)>0){ //kovan testnet
        return OraclizeAddrResolverI(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e);
    }
    if (getCodeSize(0x146500cfd35B22E4A392Fe0aDc06De1a1368Ed48)>0){ //rinkeby testnet
        return OraclizeAddrResolverI(0x146500cfd35B22E4A392Fe0aDc06De1a1368Ed48);
    }
    if (getCodeSize(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475)>0){ //ethereum-bridge
        return OraclizeAddrResolverI(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475);
    }
    if (getCodeSize(0x20e12A1F859B3FeaE5Fb2A0A32C18F5a65555bBF)>0){ //ether.camp ide
        return OraclizeAddrResolverI(0x20e12A1F859B3FeaE5Fb2A0A32C18F5a65555bBF);
    }
    if (getCodeSize(0x51efaF4c8B3C9AfBD5aB9F4bbC82784Ab6ef8fAA)>0){ //browser-solidity
        return OraclizeAddrResolverI(0x51efaF4c8B3C9AfBD5aB9F4bbC82784Ab6ef8fAA);
    }
}

function oraclize_getPrice(string datasource)
public
view
returns (uint){
    return oraclize().getPrice(datasource);
}

function oraclize_getPrice(string datasource, uint gaslimit)
public
view
returns (uint){
    return oraclize().getPrice(datasource, gaslimit);
}

function oraclize_query(string datasource, string arg)
public
returns (bytes32 id){
    return oraclize_query(0, datasource, arg);
}

function oraclize_query(uint timestamp, string datasource, string arg)
public
returns (bytes32 id){
    OraclizeI oracle = oraclize();
    uint price = oracle.getPrice(datasource);
    if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price
    return oracle.query.value(price)(timestamp, datasource, arg);
}

function oraclize_query(string datasource, string arg, uint gaslimit)
public
returns (bytes32 id){
    return oraclize_query(0, datasource, arg, gaslimit);
}

function oraclize_query(uint timestamp, string datasource, string arg, uint gaslimit)
public
returns (bytes32 id){
    OraclizeI oracle = oraclize();
    uint price = oracle.getPrice(datasource, gaslimit);
    if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price
    return oracle.query_withGasLimit.value(price)(timestamp, datasource, arg, gaslimit);
}

function oraclize_query(string datasource, string arg1, string arg2)
public
returns (bytes32 id){
    return oraclize_query(0, datasource, arg1, arg2);
}

function oraclize_query(uint timestamp, string datasource, string arg1, string arg2)
public
returns (bytes32 id){
    OraclizeI oracle = oraclize();
    uint price = oracle.getPrice(datasource);
    if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price
    return oracle.query2.value(price)(timestamp, datasource, arg1, arg2);
}

function oraclize_query(string datasource, string arg1, string arg2, uint gaslimit)
public
returns (bytes32 id){
    return oraclize_query(0, datasource, arg1, arg2, gaslimit);
}

function oraclize_query(uint timestamp, string datasource, string arg1, string arg2, uint gaslimit)
public
returns (bytes32 id){
    OraclizeI oracle = oraclize();
    uint price = oracle.getPrice(datasource, gaslimit);
    if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price
    return oracle.query2_withGasLimit.value(price)(timestamp, datasource, arg1, arg2, gaslimit);
}

// internalize w/o experimental
function oraclize_query(string datasource, string[] argN)
internal
returns (bytes32 id){
    return oraclize_query(0, datasource, argN);
}

// internalize w/o experimental
function oraclize_query(uint timestamp, string datasource, string[] argN)
internal
returns (bytes32 id){
    OraclizeI oracle = oraclize();
    uint price = oracle.getPrice(datasource);
    if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price
    bytes memory args = stra2cbor(argN);
    return oracle.queryN.value(price)(timestamp, datasource, args);
}

// internalize w/o experimental
function oraclize_query(string datasource, string[] argN, uint gaslimit)
internal
returns (bytes32 id){
    return oraclize_query(0, datasource, argN, gaslimit);
}

// internalize w/o experimental
function oraclize_query(uint timestamp, string datasource, string[] argN, uint gaslimit)
internal
returns (bytes32 id){
    OraclizeI oracle = oraclize();
    uint price = oracle.getPrice(datasource, gaslimit);
    if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price
    bytes memory args = stra2cbor(argN);
    return oracle.queryN_withGasLimit.value(price)(timestamp, datasource, args, gaslimit);
}

function oraclize_cbAddress()
public
view
returns (address){
    return oraclize().cbAddress();
}

function oraclize_setProof(byte proofP)
public {
    return oraclize().setProofType(proofP);
}

function oraclize_setCustomGasPrice(uint gasPrice)
public {
    return oraclize().setCustomGasPrice(gasPrice);
}

// setting to internal doesn't cause major increase in deployment and saves gas
// per use, for this tiny function
function getCodeSize(address _addr)
public
view
returns(uint _size) {
    assembly {
        _size := extcodesize(_addr)
    }
}

// expects 0x prefix
function parseAddr(string _a)
public
pure
returns (address){
    bytes memory tmp = bytes(_a);
    uint160 iaddr = 0;
    uint160 b1;
    uint160 b2;
    for (uint i=2; i<2+2*20; i+=2){
        iaddr *= 256;
        b1 = uint160(tmp[i]);
        b2 = uint160(tmp[i+1]);
        if ((b1 >= 97)&&(b1 <= 102)) b1 -= 87;
        else if ((b1 >= 65)&&(b1 <= 70)) b1 -= 55;
        else if ((b1 >= 48)&&(b1 <= 57)) b1 -= 48;
        if ((b2 >= 97)&&(b2 <= 102)) b2 -= 87;
        else if ((b2 >= 65)&&(b2 <= 70)) b2 -= 55;
        else if ((b2 >= 48)&&(b2 <= 57)) b2 -= 48;
        iaddr += (b1*16+b2);
    }
    return address(iaddr);
}

function strCompare(string _a, string _b)
public
pure
returns (int) {
    bytes memory a = bytes(_a);
    bytes memory b = bytes(_b);
    uint minLength = a.length;
    if (b.length < minLength) minLength = b.length;
    for (uint i = 0; i < minLength; i ++)
        if (a[i] < b[i])
            return -1;
        else if (a[i] > b[i])
            return 1;
    if (a.length < b.length)
        return -1;
    else if (a.length > b.length)
        return 1;
    else
        return 0;
}

function indexOf(string _haystack, string _needle)
public
pure
returns (int) {
    bytes memory h = bytes(_haystack);
    bytes memory n = bytes(_needle);
    if(h.length < 1 || n.length < 1 || (n.length > h.length))
        return -1;
    else if(h.length > (2**128 -1))
        return -1;
    else
    {
        uint subindex = 0;
        for (uint i = 0; i < h.length; i ++)
        {
            if (h[i] == n[0])
            {
                subindex = 1;
                while(subindex < n.length && (i + subindex) < h.length && h[i + subindex] == n[subindex])
                {
                    subindex++;
                }
                if(subindex == n.length)
                    return int(i);
            }
        }
        return -1;
    }
}

function strConcat(string _a, string _b, string _c, string _d, string _e)
internal
pure
returns (string) {
    bytes memory _ba = bytes(_a);
    bytes memory _bb = bytes(_b);
    bytes memory _bc = bytes(_c);
    bytes memory _bd = bytes(_d);
    bytes memory _be = bytes(_e);
    string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length);
    bytes memory babcde = bytes(abcde);
    uint k = 0;
    for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i];
    for (i = 0; i < _bb.length; i++) babcde[k++] = _bb[i];
    for (i = 0; i < _bc.length; i++) babcde[k++] = _bc[i];
    for (i = 0; i < _bd.length; i++) babcde[k++] = _bd[i];
    for (i = 0; i < _be.length; i++) babcde[k++] = _be[i];
    return string(babcde);
}

function strConcat(string _a, string _b, string _c, string _d)
internal
pure
returns (string) {
    return strConcat(_a, _b, _c, _d, "");
}

function strConcat(string _a, string _b, string _c)
internal
pure
returns (string) {
    return strConcat(_a, _b, _c, "", "");
}

function strConcat(string _a, string _b)
internal
pure
returns (string) {
    return strConcat(_a, _b, "", "", "");
}

// parseInt
function parseInt(string _a)
public
pure
returns (uint) {
    return parseInt(_a, 0);
}

// parseInt(parseFloat*10^_b)
function parseInt(string _a, uint _b)
public
pure
returns (uint) {
    bytes memory bresult = bytes(_a);
    uint mint = 0;
    bool decimals = false;
    for (uint i=0; i<bresult.length; i++){
        if ((bresult[i] >= 48)&&(bresult[i] <= 57)){
            if (decimals){
               if (_b == 0) break;
                else _b--;
            }
            mint *= 10;
            mint += uint(bresult[i]) - 48;
        } else if (bresult[i] == 46) decimals = true;
    }
    if (_b > 0) mint *= 10**_b;
    return mint;
}

function uint2str(uint i)
internal
pure
returns (string){
    if (i == 0) return "0";
    uint j = i;
    uint len;
    while (j != 0){
        len++;
        j /= 10;
    }
    bytes memory bstr = new bytes(len);
    uint k = len - 1;
    while (i != 0){
        bstr[k--] = byte(48 + i % 10);
        i /= 10;
    }
    return string(bstr);
}

function stra2cbor(string[] arr)
internal
pure
returns (bytes) {
    uint arrlen = arr.length;

    // get correct cbor output length
    uint outputlen = 0;
    bytes[] memory elemArray = new bytes[](arrlen);
    for (uint i = 0; i < arrlen; i++) {
        elemArray[i] = (bytes(arr[i]));
        outputlen += elemArray[i].length + (elemArray[i].length - 1)/23 + 3; //+3 accounts for paired identifier types
    }
    uint ctr = 0;
    uint cborlen = arrlen + 0x80;
    outputlen += byte(cborlen).length;
    bytes memory res = new bytes(outputlen);

    while (byte(cborlen).length > ctr) {
        res[ctr] = byte(cborlen)[ctr];
        ctr++;
    }
    for (i = 0; i < arrlen; i++) {
        res[ctr] = 0x5F;
        ctr++;
        for (uint x = 0; x < elemArray[i].length; x++) {
            // if there's a bug with larger strings, this may be the culprit
            if (x % 23 == 0) {
                uint elemcborlen = elemArray[i].length - x >= 24 ? 23 : elemArray[i].length - x;
                elemcborlen += 0x40;
                uint lctr = ctr;
                while (byte(elemcborlen).length > ctr - lctr) {
                    res[ctr] = byte(elemcborlen)[ctr - lctr];
                    ctr++;
                }
            }
            res[ctr] = elemArray[i][x];
            ctr++;
        }
        res[ctr] = 0xFF;
        ctr++;
    }
    return res;
}

function b2s(bytes _b)
internal
returns (string) {
    bytes memory output = new bytes(_b.length * 2);
    uint len = output.length;

    assembly {
        let i := 0
        let mem := 0
        loop:
            // isolate octet
            0x1000000000000000000000000000000000000000000000000000000000000000
            exp(0x10, mod(i, 0x40))
            // change offset only if needed
            jumpi(skip, gt(mod(i, 0x40), 0))
            // save offset mem for reuse
            mem := mload(add(_b, add(mul(0x20, div(i, 0x40)), 0x20)))
        skip:
            mem
            mul
            div
            dup1
            // check if alpha or numerical, jump if numerical
            0x0a
            swap1
            lt
            num
            jumpi
            // offset alpha char correctly
            0x0a
            swap1
            sub
        alp:
            0x61
            add
            jump(end)
        num:
            0x30
            add
        end:
            add(output, add(0x20, i))
            mstore8
            i := add(i, 1)
            jumpi(loop, gt(len, i))
    }

    return string(output);
}

}
// </ORACLIZE_API_LIB>

library DateTime {
/*
* Date and Time utilities for ethereum contracts
*
*/
struct _DateTime {
uint16 year;
uint8 month;
uint8 day;
uint8 hour;
uint8 minute;
uint8 second;
uint8 weekday;
}

    uint constant DAY_IN_SECONDS = 86400;
    uint constant YEAR_IN_SECONDS = 31536000;
    uint constant LEAP_YEAR_IN_SECONDS = 31622400;

    uint constant HOUR_IN_SECONDS = 3600;
    uint constant MINUTE_IN_SECONDS = 60;

    uint16 constant ORIGIN_YEAR = 1970;

    function isLeapYear(uint16 year) public pure returns (bool) {
            if (year % 4 != 0) {
                    return false;
            }
            if (year % 100 != 0) {
                    return true;
            }
            if (year % 400 != 0) {
                    return false;
            }
            return true;
    }

    function leapYearsBefore(uint year) public pure returns (uint) {
            year -= 1;
            return year / 4 - year / 100 + year / 400;
    }

    function getDaysInMonth(uint8 month, uint16 year) public pure returns (uint8) {
            if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
                    return 31;
            }
            else if (month == 4 || month == 6 || month == 9 || month == 11) {
                    return 30;
            }
            else if (isLeapYear(year)) {
                    return 29;
            }
            else {
                    return 28;
            }
    }

    function parseTimestamp(uint timestamp) internal pure returns (_DateTime dt) {
            uint secondsAccountedFor = 0;
            uint buf;
            uint8 i;

            // Year
            dt.year = getYear(timestamp);
            buf = leapYearsBefore(dt.year) - leapYearsBefore(ORIGIN_YEAR);

            secondsAccountedFor += LEAP_YEAR_IN_SECONDS * buf;
            secondsAccountedFor += YEAR_IN_SECONDS * (dt.year - ORIGIN_YEAR - buf);

            // Month
            uint secondsInMonth;
            for (i = 1; i <= 12; i++) {
                    secondsInMonth = DAY_IN_SECONDS * getDaysInMonth(i, dt.year);
                    if (secondsInMonth + secondsAccountedFor > timestamp) {
                            dt.month = i;
                            break;
                    }
                    secondsAccountedFor += secondsInMonth;
            }

            // Day
            for (i = 1; i <= getDaysInMonth(dt.month, dt.year); i++) {
                    if (DAY_IN_SECONDS + secondsAccountedFor > timestamp) {
                            dt.day = i;
                            break;
                    }
                    secondsAccountedFor += DAY_IN_SECONDS;
            }

            // Hour
            dt.hour = getHour(timestamp);

            // Minute
            dt.minute = getMinute(timestamp);

            // Second
            dt.second = getSecond(timestamp);

            // Day of week.
            dt.weekday = getWeekday(timestamp);
    }

    function getYear(uint timestamp) public pure returns (uint16) {
            uint secondsAccountedFor = 0;
            uint16 year;
            uint numLeapYears;

            // Year
            year = uint16(ORIGIN_YEAR + timestamp / YEAR_IN_SECONDS);
            numLeapYears = leapYearsBefore(year) - leapYearsBefore(ORIGIN_YEAR);

            secondsAccountedFor += LEAP_YEAR_IN_SECONDS * numLeapYears;
            secondsAccountedFor += YEAR_IN_SECONDS * (year - ORIGIN_YEAR - numLeapYears);

            while (secondsAccountedFor > timestamp) {
                    if (isLeapYear(uint16(year - 1))) {
                            secondsAccountedFor -= LEAP_YEAR_IN_SECONDS;
                    }
                    else {
                            secondsAccountedFor -= YEAR_IN_SECONDS;
                    }
                    year -= 1;
            }
            return year;
    }

    function getMonth(uint timestamp) public pure returns (uint8) {
            return parseTimestamp(timestamp).month;
    }

    function getDay(uint timestamp) public pure returns (uint8) {
            return parseTimestamp(timestamp).day;
    }

    function getHour(uint timestamp) public pure returns (uint8) {
            return uint8((timestamp / 60 / 60) % 24);
    }

    function getMinute(uint timestamp) public pure returns (uint8) {
            return uint8((timestamp / 60) % 60);
    }

    function getSecond(uint timestamp) public pure returns (uint8) {
            return uint8(timestamp % 60);
    }

    function getWeekday(uint timestamp) public pure returns (uint8) {
            return uint8((timestamp / DAY_IN_SECONDS + 4) % 7);
    }

    function toTimestamp(uint16 year, uint8 month, uint8 day) public pure returns (uint timestamp) {
            return toTimestamp(year, month, day, 0, 0, 0);
    }

    function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour) public pure returns (uint timestamp) {
            return toTimestamp(year, month, day, hour, 0, 0);
    }

    function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute) public pure returns (uint timestamp) {
            return toTimestamp(year, month, day, hour, minute, 0);
    }

    function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute, uint8 second) public pure returns (uint timestamp) {
            uint16 i;

            // Year
            for (i = ORIGIN_YEAR; i < year; i++) {
                    if (isLeapYear(i)) {
                            timestamp += LEAP_YEAR_IN_SECONDS;
                    }
                    else {
                            timestamp += YEAR_IN_SECONDS;
                    }
            }

            // Month
            uint8[12] memory monthDayCounts;
            monthDayCounts[0] = 31;
            if (isLeapYear(year)) {
                    monthDayCounts[1] = 29;
            }
            else {
                    monthDayCounts[1] = 28;
            }
            monthDayCounts[2] = 31;
            monthDayCounts[3] = 30;
            monthDayCounts[4] = 31;
            monthDayCounts[5] = 30;
            monthDayCounts[6] = 31;
            monthDayCounts[7] = 31;
            monthDayCounts[8] = 30;
            monthDayCounts[9] = 31;
            monthDayCounts[10] = 30;
            monthDayCounts[11] = 31;

            for (i = 1; i < month; i++) {
                    timestamp += DAY_IN_SECONDS * monthDayCounts[i - 1];
            }

            // Day
            timestamp += DAY_IN_SECONDS * (day - 1);

            // Hour
            timestamp += HOUR_IN_SECONDS * (hour);

            // Minute
            timestamp += MINUTE_IN_SECONDS * (minute);

            // Second
            timestamp += second;

            return timestamp;
    }

}

contract DSSafeAddSub {
function safeToAdd(uint a, uint b) pure internal returns (bool) {
return (a + b >= a);
}
function safeAdd(uint a, uint b) pure internal returns (uint) {
require(safeToAdd(a, b));
return (a + b);
}

function safeToSubtract(uint a, uint b) pure internal returns (bool) {
    return (b <= a);
}

function safeSub(uint a, uint b) pure internal returns (uint) {
    require(safeToSubtract(a, b));
    return (a - b);
}

}

/**

  • etherindex contract
    /
    contract Etherindex is DSSafeAddSub {
    /

    • 检查投注的合法性:
      1. 投注金额 > 0 todo:目前只检查了这一个条件
      1. 目标收益 > 0
      1. 最大收益 > 目标收益
      1. 投注日期合法
      1. 预测区间上限 > 下限
      1. 预测区间下限 > 0
        */
        modifier betIsValid(uint _userBetValue) {
        require(_userBetValue > 0);
        _;
        }

    /*

    • checks game is currently active
      */
      modifier systemIsActive {
      require(gamePaused == false);
      _;
      }

    /*

    • checks payouts are currently active
      */
      modifier payoutsAreActive {
      require(payoutsPaused == false);
      _;
      }

    /*

    • checks only Oraclize address is calling
      */
      modifier onlyOraclize {
      require(msg.sender == oraclizeLib.oraclize_cbAddress());
      _;
      }

    /*

    • checks only owner address is calling
      */
      modifier onlyOwner {
      require(msg.sender == owner);
      _;
      }

    /*

    • checks only treasury address is calling
      */
      modifier onlyTreasury {
      require(msg.sender == treasury);
      _;
      }

    /*

    • system vars
      */
      uint public minBet = 100000000000000000; // 最小投注0.1个ether todo: 待确认
      uint public maxBet = 10000000000000000000; // 最大投注不可超过10 ether todo: 待确认
      uint public maxProfit = 20000000000000000000; // 玩家最大目标收益不可超过20个ether todo: 待确认
      bool public gamePaused; // true - 游戏暂停,false - 游戏未暂停
      uint32 public gasForOraclize; // 给oraclize回调方法的费用
      address public owner; // contract owner address
      address public treasury; // 财务账户address
      bool public payoutsPaused; // true - 付款暂停,fasle - 付款未暂停
      uint public maxPendingPayouts; // 最大待付金额
      uint public totalBets = 244612; // 初始化合约中断数据 - 总投注次数
      uint public totalWeiWon = 110633844560463069959901; // 初始化合约中断数据 - 用户赢取的总数
      uint public totalWeiWagered = 316486087709317593009320; // 初始化合约中断数据 - 总投注金额

    /*

    • oraclize vars
      */
      // query type constant
      uint8 constant VALIDATECHECK = 0;
      uint8 constant PAYOUTCHECK = 1;

    mapping (bytes32 => uint8) public queryType; // 将queryId和query type绑定
    mapping(string => mapping(uint => closePrice)) closePrices; // 实际收盘价 string代表指数名,一个uint代表收盘日期

    struct closePrice {
    uint price;
    bool valid;
    }

    /*

    • user vars
      */
      //投注状态 INITIAL-初始状态(还未通过有效性检查), PENDING-待开奖, INVALID-非法输入, LOSE-失败, WIN-成功, WIN_FAILED_SEND-成功但转账失败, REFUND-系统或网络原因退款, REFUND_FAILED_SEND-系统或网络原因退款但退款失败
      uint8 constant INITIAL = 0;
      uint8 constant PENDING = 1;
      uint8 constant INVALID = 2;
      uint8 constant LOSE = 3;
      uint8 constant WIN = 4;
      uint8 constant WIN_FAILED_SEND = 5;
      uint8 constant REFUND = 6;
      uint8 constant REFUND_FAILED_SEND = 7;

    address[] addrArray; //用户地址数组 todo: 暂时未用上
    uint breakPoint; // 断点 todo: check later
    mapping (bytes32 => address) public userAddress; // 用户地址
    mapping (bytes32 => address) public userTempAddress; // 暂存用户地址,防止重入攻击
    mapping (bytes32 => bytes32) public userBetId; // 用户投注id
    mapping (bytes32 => uint) public userBetValue; // 用户投注金额
    mapping (bytes32 => uint) public userTempBetValue; // 暂存投注金额,防止重入攻击
    mapping (bytes32 => uint) public userProfit; // 用户目标收益
    mapping (bytes32 => uint) public userTempProfit; // 暂存用户目标收益,防止重入攻击
    mapping (bytes32 => uint) public userMaxProfitLimit; // 本次投注允许的最大投注金额
    mapping (bytes32 => string) public userUnderlyingIndex; // 用户选择的标的指数
    mapping (bytes32 => uint) public userBetDate; // 用户选择的标的指数收盘日期
    mapping (bytes32 => uint) public userIntervalLow; // 用户投注区间下限
    mapping (bytes32 => uint) public userIntervalHigh; // 用户投注区间上限
    mapping (bytes32 => uint) public userBetTimestamp; // 用户投注时间戳 in UTC
    mapping (bytes32 => uint8) public userBetStatus; // 投注状态
    mapping (address => uint) public userPendingWithdrawals; // 待支付给用户的金额

    /*

    • events
      /
      /
      log bets + output to web3 for precise 'payout on win' field in UI */
      event LogBet(bytes32 indexed _userBetId, address indexed _userAddress, uint _userRewardValue, uint _userProfit, uint _userBetValue, uint _userIntervalLow, uint _userIntervalhigh, uint8 _betStatus);

    /* output to web3 UI on bet result*/
    // Status: 0-INITIAL, 1-PENDING, 2-INVALID, 3-LOSE, 4-WIN, 5-WIN_FAILED_SEND, 6-REFUND, 7-REFUND_FAILED_SEND
    event LogResult(bytes32 indexed _userBetId, address indexed _userAddress, uint _userRewardValue, uint _userProfit, uint _userBetValue, uint _userIntervalLow, uint _userIntervalhigh, uint8 _betStatus);
    /* log manual refunds /
    event LogRefund(bytes32 indexed _userBetId, address indexed _userAddress, uint indexed RefundValue);
    /
    log owner transfers /
    event LogOwnerTransfer(address indexed SentToAddress, uint indexed AmountTransferred);
    /
    owner fund contract */
    event LogOwnerFundContract(address _ownerAddress, uint _currentContractBalance, uint _fundAmount, DateTime._DateTime _fundTimestamp);

    //debug @test
    event logUint8(string item, uint8 variable);
    event logUint16(string item, uint16 variable);
    event logUint32(string item, uint32 variable);
    event logUint64(string item, uint64 variable);
    event logUint128(string item, uint128 variable);
    event logUint256(string item, uint256 variable);
    event logUint(string item, uint variable);
    event logInt(string item, int variable);
    event logBool(string item, bool variable);
    event logBytes(string item, bytes variable);
    event logBytes32(string item, bytes32 variable);
    event logAddress(string item, address variable);
    event logString(string item, string variable);
    event trace(string toDisplay);

    /*

    • init
      */
      function Etherindex() public {

      owner = msg.sender;
      treasury = msg.sender;
      //oraclizeLib.oraclize_setNetwork(networkID_auto);
      /* use TLSNotary for oraclize call /
      //oraclizeLib.oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
      /
      init gas for oraclize /
      gasForOraclize = 235000;
      /
      init gas price for callback (default 20 gwei)*/
      oraclizeLib.oraclize_setCustomGasPrice(20000000000 wei);

    }

    /*

    • public function

    • user submit bet

    • only if game is active & bet is valid can query oraclize and set user vars
      */
      function userBet(string _userUnderlyingIndex, uint _userBetDate, uint _userIntervalLow, uint _userIntervalHigh, uint _userProfit, uint _userMaxProfitLimit, uint _userBetTimestamp) public
      payable
      systemIsActive
      {
      // 输入检查:
      // 投注金额 > 0
      require(msg.value > 0);

      // 用户目标收益 < 本次投注允许的最大投注金额
      require(_userProfit < _userMaxProfitLimit);

      // 用户目标收益 > 0
      require(_userProfit > 0);

      // 投注日期合法 todo: 目前仅检查投注日期是否大于0
      require(_userBetDate > 0);

      // 用户投注区间下限 > 0
      require(_userIntervalLow > 0);

      // 用户投注区间上限 > 用户投注区间下限
      require(_userIntervalHigh > _userIntervalLow);

      // todo: api有待确认
      bytes32 queryId = oraclizeLib.oraclize_query("URL", "https://api.iextrading.com/1.0/stock/aapl/price");

      queryType[queryId] = VALIDATECHECK;

      // @test
      emit logBytes32("queryId",queryId);

      // 将用户信息和betId关联
      userAddress[queryId] = msg.sender;
      addrArray.push(msg.sender);
      userBetId[queryId] = queryId;
      userBetValue[queryId] = msg.value;
      userProfit[queryId] = _userProfit;
      userMaxProfitLimit[queryId] = _userMaxProfitLimit;
      userUnderlyingIndex[queryId] = _userUnderlyingIndex;
      userBetDate[queryId] = _userBetDate;
      userIntervalLow[queryId] = _userIntervalLow;
      userIntervalHigh[queryId] = _userIntervalHigh;
      userBetTimestamp[queryId] = _userBetTimestamp;

      // bet状态为初始状态
      userBetStatus[queryId] = INITIAL;

      // 记录投注信息
      emit LogBet(queryId, msg.sender, safeAdd(msg.value, _userProfit), _userProfit, msg.value, _userIntervalLow, _userIntervalHigh, userBetStatus[queryId]);

    }

    //收盘时发起当日收盘价查询,每个指数只查询一次
    function inqueryIndexPrice(string _indexName, uint _date) public onlyOwner returns(bool)

    {
    // 检查本地是否存有查询过的数据,无则调用oraclize查询,且返回true todo:api有待确认
    if (closePrices[_indexName][_date].price == 0){
    bytes32 queryId = oraclizeLib.oraclize_query("URL", "https://api.iextrading.com/1.0/stock/goog/price");
    queryType[queryId] = PAYOUTCHECK;
    //@test
    emit logBool("inquery index price",true);
    emit logBytes32("query id",queryId);
    return true;
    }
    else{
    //@test
    emit logBool("inquery index price",false);
    return false;
    }
    }

    function payoutProcess(bytes32 myid) public{
    //@test
    emit logBytes32("myid",myid);
    emit logString("underlying index",userUnderlyingIndex[myid]);
    emit logUint("user bet date",userBetDate[myid]);
    emit logUint("close price",closePrices[userUnderlyingIndex[myid]][userBetDate[myid]].price);
    emit logBool("close price valid",closePrices[userUnderlyingIndex[myid]][userBetDate[myid]].valid);

     /* get the userAddress for this query id */
     userTempAddress[myid] = userAddress[myid];
     /* delete userAddress for this query id */
     delete userAddress[myid];
    
     /* map the userProfit for this query id */
     userTempProfit[myid] = userProfit[myid];
     /* set  userProfit for this query id to 0 */
     userProfit[myid] = 0; 
    
     /* safely reduce maxPendingPayouts liability */
     maxPendingPayouts = safeSub(maxPendingPayouts, userTempProfit[myid]);         
    
     /* map the userBetValue for this query id */
     userTempBetValue[myid] = userBetValue[myid];
     /* set  userBetValue for this query id to 0 */
     userBetValue[myid] = 0;
    
     // refund
     if (closePrices[userUnderlyingIndex[myid]][userBetDate[myid]].price == 0 || closePrices[userUnderlyingIndex[myid]][userBetDate[myid]].valid == false){
         userBetStatus[myid] = REFUND;
         emit LogResult(userBetId[myid], userAddress[myid], safeAdd(userBetValue[myid], userProfit[myid]), userProfit[myid], userBetValue[myid], userIntervalLow[myid], userIntervalHigh[myid], userBetStatus[myid]);   
    
         if(!userTempAddress[myid].send(userTempBetValue[myid])){
             userBetStatus[myid] = REFUND_FAILED_SEND;
             emit LogResult(userBetId[myid], userAddress[myid], safeAdd(userBetValue[myid], userProfit[myid]), userProfit[myid], userBetValue[myid], userIntervalLow[myid], userIntervalHigh[myid], userBetStatus[myid]);   
             /* if send failed let user withdraw via userWithdrawPendingTransactions */
             userPendingWithdrawals[userTempAddress[myid]] = safeAdd(userPendingWithdrawals[userTempAddress[myid]], userTempBetValue[myid]);                        
         }
    
         return;
     }
    
     /*
     * pay winner
     * update contract balance to calculate new max bet
     * send reward
     * if send of reward fails save value to userPendingWithdrawals        
     */
     if(userIntervalLow[myid] <= closePrices[userUnderlyingIndex[myid]][userBetDate[myid]].price && userIntervalHigh[myid] > closePrices[userUnderlyingIndex[myid]][userBetDate[myid]].price){ 
    
         /* update total wei won */
         totalWeiWon = safeAdd(totalWeiWon, userTempProfit[myid]);              
    
         /* safely calculate payout via profit plus original wager */
         userTempProfit[myid] = safeAdd(userTempProfit[myid], userTempBetValue[myid]); 
    
         // set status to WIN
         userBetStatus[myid] = WIN;
         emit LogResult(userBetId[myid], userAddress[myid], safeAdd(userBetValue[myid], userProfit[myid]), userProfit[myid], userBetValue[myid], userIntervalLow[myid], userIntervalHigh[myid], userBetStatus[myid]);   
    
         //* update maximum profit todo: temp comment
         // setMaxProfit();
         
         /*
         * send win - external call to an untrusted contract
         * if send fails map reward value to userPendingWithdrawals[address]
         * for withdrawal later via userWithdrawPendingTransactions
         */
         if(!userTempAddress[myid].send(userTempProfit[myid])){
             // set status to WIN_FAILED_SEND
             userBetStatus[myid] = WIN_FAILED_SEND;
             emit LogResult(userBetId[myid], userAddress[myid], safeAdd(userBetValue[myid], userProfit[myid]), userProfit[myid], userBetValue[myid], userIntervalLow[myid], userIntervalHigh[myid], userBetStatus[myid]);   
    
             /* if send failed let user withdraw via userWithdrawPendingTransactions */
             userPendingWithdrawals[userTempAddress[myid]] = safeAdd(userPendingWithdrawals[userTempAddress[myid]], userTempProfit[myid]);                               
         }
    
         return;
    
     }
    
     /*
     * no win
     * send 1 wei to a losing bet
     * update contract balance to calculate new max bet
     */
     if(userIntervalLow[myid] > closePrices[userUnderlyingIndex[myid]][userBetDate[myid]].price || userIntervalHigh[myid] <= closePrices[userUnderlyingIndex[myid]][userBetDate[myid]].price){
    
         // set status to WIN_FAILED_SEND
         userBetStatus[myid] = LOSE;
         emit LogResult(userBetId[myid], userAddress[myid], safeAdd(userBetValue[myid], userProfit[myid]), userProfit[myid], userBetValue[myid], userIntervalLow[myid], userIntervalHigh[myid], userBetStatus[myid]);
    
         /*
         * send 1 wei - external call to an untrusted contract                  
         */
         if(!userTempAddress[myid].send(1)){
             /* if send failed let user withdraw via userWithdrawPendingTransactions */                
            userPendingWithdrawals[userTempAddress[myid]] = safeAdd(userPendingWithdrawals[userTempAddress[myid]], 1);                                
         }                                   
    
         return;
    
     }       
    

    }

    function __callback(bytes32 myid, string result, bytes proof) public
    onlyOraclize
    payoutsAreActive
    {
    //@test
    emit trace("callback triggered");

     // __callback的调用必须源自VALIDATECHECK, PAYOUTCHECK
     require (queryType[myid] != VALIDATECHECK || queryType[myid] != PAYOUTCHECK);
     
     if (queryType[myid] == VALIDATECHECK){
         require (userAddress[myid] != 0x0);
         // todo: validate_check() and update bet status 
    
         /* safely increase maxPendingPayouts liability - calc all pending payouts under assumption they win */
         maxPendingPayouts = safeAdd(maxPendingPayouts, safeAdd(userBetValue[myid], userProfit[myid]));
    
         /* check contract can payout on win */
         require (maxPendingPayouts < address(this).balance);
    
         // after validate check update userBetStatus to PENDING
         userBetStatus[myid] = PENDING;
    
         //总投注次数
         totalBets += 1;
    
         //总投注金额
         totalWeiWagered += userBetValue[myid];             
     }
    
     if (queryType[myid] == PAYOUTCHECK){
         // 检查oraclize是否返回结果 todo: 需要加上检查价格,不为零
         require (bytes(result).length != 0 && bytes(proof).length != 0);
    
         // 将收盘价保存 todo: temp comment, 要求接口返回标的指数名和收盘日期
         //closePrices[$indexname][$date].price = result;
         //closePrices[$indexname][$date].valid = true;
    
         // 记录收盘价查询日志,保证要查询到价格 todo: temp comment
         //emit logIndexPrice(myid, $indexname, $date, $price, proof);
    
     }
    

    }

    /*

    • public function
    • in case of a failed refund or win send
      /
      function userWithdrawPendingTransactions() public
      payoutsAreActive
      returns (bool)
      {
      uint withdrawAmount = userPendingWithdrawals[msg.sender];
      userPendingWithdrawals[msg.sender] = 0;
      /
      external call to untrusted contract /
      if (msg.sender.call.value(withdrawAmount)()) {
      return true;
      } else {
      /
      if send failed revert userPendingWithdrawals[msg.sender] = 0; /
      /
      user can try to withdraw again later */
      userPendingWithdrawals[msg.sender] = withdrawAmount;
      return false;
      }
      }

    /* check for pending withdrawals */
    function userGetPendingTxByAddress(address addressToCheck) public constant returns (uint) {
    return userPendingWithdrawals[addressToCheck];
    }

    /*

    • owner/treasury address only functions
      */
      function ()
      payable
      onlyTreasury
      {
      emit LogOwnerFundContract(msg.sender, address(this).balance, msg.value, DateTime.parseTimestamp(now));
      }

    /* set gas price for oraclize callback */
    function ownerSetCallbackGasPrice(uint newCallbackGasPrice) public
    onlyOwner
    {
    oraclizeLib.oraclize_setCustomGasPrice(newCallbackGasPrice);
    }

    /* set gas limit for oraclize query */
    function ownerSetOraclizeSafeGas(uint32 newSafeGasToOraclize) public
    onlyOwner
    {
    gasForOraclize = newSafeGasToOraclize;
    }

    /* only owner address can set minBet */
    function ownerSetMinBet(uint newMinimumBet) public
    onlyOwner
    {
    minBet = newMinimumBet;
    }

    /* only owner address can transfer ether */
    function ownerTransferEther(address sendTo, uint amount) public
    onlyOwner
    {
    sendTo.transfer(amount);
    emit LogOwnerTransfer(sendTo, amount);
    }

    /* only owner address can do manual refund

    • used only if bet placed + oraclize failed to __callback
    • filter LogBet by address and/or userBetId:
    • LogBet(userBetId[rngId], userAddress[rngId], safeAdd(userBetValue[rngId], userProfit[rngId]), userProfit[rngId], userBetValue[rngId], userNumber[rngId]);
    • check the following logs do not exist for userBetId and/or userAddress[rngId] before refunding:
    • LogResult or LogRefund
    • if LogResult exists user should use the withdraw pattern userWithdrawPendingTransactions
      /
      function ownerRefundUser(bytes32 originalUserBetId, address sendTo, uint originalUserProfit, uint originalUserBetValue) public
      onlyOwner
      {
      /
      safely reduce pendingPayouts by userProfit[rngId] /
      maxPendingPayouts = safeSub(maxPendingPayouts, originalUserProfit);
      /
      send refund /
      sendTo.transfer(originalUserBetValue);
      /
      log refunds */
      emit LogRefund(originalUserBetId, sendTo, originalUserBetValue);
      }

    /* only owner address can set emergency pause #1 */
    function ownerPauseGame(bool newStatus) public
    onlyOwner
    {
    gamePaused = newStatus;
    }

    /* only owner address can set emergency pause #2 */
    function ownerPausePayouts(bool newPayoutStatus) public
    onlyOwner
    {
    payoutsPaused = newPayoutStatus;
    }

    /* only owner address can set treasury address */
    function ownerSetTreasury(address newTreasury) public
    onlyOwner
    {
    treasury = newTreasury;
    }

    /* only owner address can set owner address */
    function ownerChangeOwner(address newOwner) public
    onlyOwner
    {
    owner = newOwner;
    }

    /* only owner address can suicide - emergency */
    function ownerkill() public
    onlyOwner
    {
    selfdestruct(owner);
    }

    //@test function
    function getUserInfo(bytes32 queryId) public {
    emit logAddress("userAddress",userAddress[queryId]);
    emit logAddress("userTempAddress",userTempAddress[queryId]);
    emit logUint("userBetValue",userBetValue[queryId]);
    emit logUint("userTempBetValue",userTempBetValue[queryId]);
    emit logUint("userProfit",userProfit[queryId]);
    emit logUint("userTempProfit",userTempProfit[queryId]);
    emit logUint("userMaxProfitLimit",userMaxProfitLimit[queryId]);
    emit logString("userUnderlyingIndex",userUnderlyingIndex[queryId]);
    emit logUint("userBetDate",userBetDate[queryId]);
    emit logUint("userIntervalLow",userIntervalLow[queryId]);
    emit logUint("userIntervalHigh",userIntervalHigh[queryId]);
    emit logUint("userBetTimestamp",userBetTimestamp[queryId]);
    emit logUint8("loguserBetStatus",userBetStatus[queryId]);
    emit logUint("userPendingWithdrawals",userPendingWithdrawals[userAddress[queryId]]);
    emit logUint("userTempPendingWithdrawals",userPendingWithdrawals[userTempAddress[queryId]]);
    }

    //@test function
    function getClosePrice (string _indexName, uint _date) public {
    emit logUint("price",closePrices[_indexName][_date].price);
    }

}

Scheduled/Delayed queries not returning any usable data

I have the following contract (https://gist.github.com/postables/61a2e1e3ae4798af180863a19c2dbd70) which can successfully call the update() function, and have Oraclize return a call by calling the __callback function.

Update call (https://rinkeby.etherscan.io/tx/0x216714c5c01ca86ec9e0f995a14aa873a60381f9ba8e275f5a16bb698a451ba2)

__callback call (https://rinkeby.etherscan.io/tx/0xabfb5f79390700c332005cfb6f7905bf8ac47238ad2e64ff5990db95284191e7)

Unfortunately it doesn't seem like the __callback works properly as the ethUSD value on the contract doesn't get updated and remains at 0.

Extremely high query cost

oraclize_getPrice("URL") is returning 4035500000000000 which is about 0.0040355 ETH = 3.86 USD

Is this correct, or am I missing something.

Unable to receive callback from oraclize on Rinkeby testnet

Hi,

We have developed a MVP on Rinkeby testnet and have used oraclize to access our APIs. It was working perfectly until yesterday, but somehow it is not working today. To dive deep into the problem, we created a sample contract on both Rinkeby and Ropsten networks. We got the desired results on Ropsten but somehow there seems to be no callback on Rinkeby.

The issue is extremely urgent for us. Your kind help would be highly appreciated.

Please find below sample contract code:
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";

contract YourContractName is usingOraclize {

mapping(bytes32=>bool) public myidList;
bytes32 public callapi;
bytes32 public res;
function YourContractName(){
    bytes32 myid=oraclize_query("URL","https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=BTC,USD,EUR,GBP");
    callapi=myid;
}

function __callback(bytes32 myid, string result) {
    if(msg.sender != oraclize_cbAddress()) throw;
    if(myidList[myid]==true) {
      // check if this myid was already processed before
      throw;
    }
    res=myid;
    myidList[myid] = true; // mark this myid (default bool value is false)
    
}

}

Provide a constant method to getPrice() to know how much Oraclize is going to charge

I want to know how much is the fee oraclize is going to charge me before I send a transaction or Oraclize API.
For example I want to know How much Oraclize would charge me for "URL" with specific gasLimit and gasPrice.

getPrice("URL", gasLimit, gasPrice) public constant

If I know this before making the actual request on platform. I can send that specific ETH into my transaction. Also we can charge that much of ETH from our customers.

Decrypted query error

I have a random.org nested query, which was working a couple of weeks ago. Today, when I tried to query a random number, I got:

ERROR HTTP query error
        [
    "datasources.decrypt.access_denied",
    "parsing_helper.wrong_path"

This is really frustrating, as I haven't changed anything in the code.

When I removed the encrypted API key and inserted the decrypted one, the query worked just fine.

What could be the error?

Oraclize returns an empty result

I'm trying to use Open Dota API from oraclize and this query return correct result
oraclize_query("URL", "json(https://api.opendota.com/api/matches/3660633407).players[?(@['hero_id']==92)]", 5000000);
Response:

"checks": [
            {
                "errors": [], 
                "success": true, 
                "timestamp": 1519934419, 
                "results": [
                    "{\"gold\": 1924, \"firstblood_claimed\": null, \"damage_inflictor_received\": null, \"lh_t\": null, \"repicked\": null, \"damage_taken\": null, \"kill_streaks\": null, \"cosmetics\": [], \"rank_tier\": null, \"hero_id\": 92, \"kills_log\": null, \"account_id\": 151074312, \"kills\": 3, \"kills_per_min\": 0.08538899430740038, \"multi_kills\": null, \"isRadiant\": true, \"backpack_1\": 0, \"backpack_0\": 56, \"leaver_status\": 0, \"actions\": null, \"killed\": null, \"stuns\": null, \"gold_per_min\": 289, \"name\": null, \"level\": 19, \"damage_inflictor\": null, \"patch\": 26, \"item_4\": 23, \"item_5\": 46, \"item_2\": 36, \"item_3\": 214, \"item_0\": 0, \"item_1\": 229, \"sen_left_log\": null, \"obs_placed\": null, \"match_id\": 3660633407, \"kda\": 2, \"pings\": null, \"gold_reasons\": null, \"ability_targets\": null, \"total_gold\": 10153, \"item_uses\": null, \"duration\": 2108, \"sen\": null, \"lobby_type\": 7, \"denies\": 4, \"start_time\": 1515093429, \"killed_by\": null, \"permanent_buffs\": null, \"last_login\": null, \"gold_t\": null, \"xp_per_min\": 443, \"ability_uses\": null, \"performance_others\": null, \"lose\": 0, \"abandons\": 0, \"roshans_killed\": null, \"assists\": 10, \"obs_left_log\": null, \"xp_reasons\": null, \"purchase_log\": null, \"region\": 3, \"rune_pickups\": null, \"times\": null, \"pred_vict\": null, \"obs\": null, \"obs_log\": null, \"win\": 1, \"radiant_win\": true, \"runes\": null, \"game_mode\": 22, \"towers_killed\": null, \"ability_upgrades_arr\": [5481, 5480, 5481, 5482, 5481, 5483, 5481, 5482, 5482, 6197, 5482, 5483, 5480, 5480, 6447, 5480, 5483], \"party_size\": null, \"party_id\": null, \"teamfight_participation\": null, \"hero_healing\": 0, \"runes_log\": null, \"life_state\": null, \"xp_t\": null, \"benchmarks\": {\"xp_per_min\": {\"raw\": 443, \"pct\": 0.3888888888888889}, \"kills_per_min\": {\"raw\": 0.08538899430740038, \"pct\": 0.25}, \"hero_damage_per_min\": {\"raw\": 207.32447817836814, \"pct\": 0.1388888888888889}, \"last_hits_per_min\": {\"raw\": 0.6261859582542695, \"pct\": 0}, \"hero_healing_per_min\": {\"raw\": 0, \"pct\": 0.9166666666666666}, \"tower_damage\": {\"raw\": 920, \"pct\": 0.3888888888888889}, \"gold_per_min\": {\"raw\": 289, \"pct\": 0.19444444444444445}}, \"buyback_log\": null, \"additional_units\": null, \"gold_spent\": 8505, \"deaths\": 4, \"cluster\": 134, \"last_hits\": 22, \"total_xp\": 15564, \"player_slot\": 0, \"creeps_stacked\": null, \"camps_stacked\": null, \"damage\": null, \"sen_log\": null, \"hero_hits\": null, \"tower_damage\": 920, \"hero_damage\": 7284, \"personaname\": \"NickLatkovich\", \"max_hero_hit\": null, \"lane_pos\": null, \"purchase\": null, \"randomed\": null, \"backpack_2\": 0, \"sen_placed\": null, \"dn_t\": null}"
                ], 
                "proofs": [
                    null
                ], 
                "match": true
            }
        ], 

But this query doesn't work and return empty result (though the element with this id exists)
oraclize_query("URL", "json(https://api.opendota.com/api/matches/3660633407).players[?(@['account_id']==151074312)]", 5000000);
Response:

"checks": [
            {
                "errors": [], 
                "success": true, 
                "timestamp": 1519934512, 
                "results": [
                    ""
                ], 
                "proofs": [
                    null
                ], 
                "match": true
            }
        ], 

Could you please help me understand why the second query return empty response?

empty response from infura URL endpoint using POST payload

i'm using the Oraclize test query to confirm my oraclize response is empty. Here's a link to the exact test query, which contains the following:

URL  ["json(https://mainnet.infura.io/).result","{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}"]

When this same endpoint is queried with the same POST params from Postman like here I get a correct response. Why isn't Oraclize returning a valid response?

__callback

When using a callback, how do I know which callback was initiated for that transaction's success?

"VM Exception: invalid opcode" when trying exampels in Remix IDE

Hey everybody, when tying your Kraken Price Ticker example, until five minutes ago, it was possible to read string public ETHXBT; when it was not set. once it was set, reading it (with remix IDE) returned "VM Exception: invalid opcode" - but the returned data was propperly displayed in the triggered event.

Now, I cannot create any of the exampe contracts whatsoever, every contract creation attempt results in an "VM Exception: invalid opcode".

Even removing basically everything, only leaving

pragma solidity ^0.4.10;

contract KrakenPriceTicker  {
string public ETHXBT;    
    event newOraclizeQuery(string description);
    event newKrakenPriceTicker(string price);

    function KrakenPriceTicker() {
        ETHXBT = "test";
        // oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
        // update();
    }
} 

results in "VM Exception: invalid opcode", according to the debugger the evildoer is supposed to be the constructor function. Running on the javascript VM.

EDIT: When switching to Edge from Chrome, I can create the example contract once but it still fails to read ETHXBT once set. After doing changes to the code, every contract creation fails again.

Query fee too high on mainnet

I paid 0.02 ETH per query which is much higher than advertised $0.01/query in current ETH prices (~$40 => $0.8/query). See transaction logs of my contracts:
https://etherscan.io/address/0x443dcadf55a41d7caf347b4d925041065fec66f6#internaltx
https://etherscan.io/address/0x0b78438d1b83d529f192729734979c83f0369e56#internaltx

I also tried to call oraclize getPrice and it returns the same price I paid:

> var contractAddress = "0x001a589Dda0D6Be37632925EAf1256986b2c6AD0"
> var oraclize = web3.eth.contract(ABI).at(contractAddress)
> web3.fromWei(oraclize.getPrice.call("URL",1000000))
{ [String: '0.02033266799733865'] s: 1, e: -2, c: [ 2033266799733, 86500000000000 ] }

Error: The contract code couldn't be stored, please check your gas amount.

Greetings,

I have an error deploying contracts using Oraclize through Truffle, getting the following error:

Running migration: 2_deploy_contracts.js
  Deploying PowerEther...
  ... 0x141b74b6b86b31949524624e08c07e77cdecbadcb4771a6f0420af73e4cab8b5
Error encountered, bailing. Network state unknown. Review successful transactions manually.
Error: The contract code couldn't be stored, please check your gas amount.
    at Object.callback (C:\Users\ruham\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\contract.js:147:1)
    at C:\Users\ruham\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\method.js:142:1
    at C:\Users\ruham\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\requestmanager.js:89:1
    at C:\Users\ruham\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\truffle-migrate\index.js:225:1
    at C:\Users\ruham\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\truffle-provider\wrapper.js:134:1
    at XMLHttpRequest.request.onreadystatechange (C:\Users\ruham\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\httpprovider.js:128:1)
    at XMLHttpRequestEventTarget.dispatchEvent (C:\Users\ruham\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:64:1)
    at XMLHttpRequest._setReadyState (C:\Users\ruham\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:354:1)
    at XMLHttpRequest._onHttpResponseEnd (C:\Users\ruham\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:509:1)
    at IncomingMessage.<anonymous> (C:\Users\ruham\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:469:1)
    at IncomingMessage.emit (events.js:165:20)
    at endReadableNT (_stream_readable.js:1101:12)
    at process._tickCallback (internal/process/next_tick.js:152:19)

I opened the issue here, since this error is most probably dealing with abstract functions that Oraclize contract uses. When removing Oraclize from the contract, the migration proceeded without errors. Note, that this issue is with Truffle, since things work when deploying through Remix IDE. Is there a way to somehow fix/change the abstractions?

compile error, oraclize library not support oraclize_setNetwork and oraclize_setProof method

by using the lib-experimental,https://github.com/oraclize/ethereum-api/blob/master/lib-experimental/oraclizeAPI_lib.sol, deploy cost reduce 60%...very good!...but, it's with the price to comment two rows:
image

why it's not support oraclize_setNetwork and oraclize_setProof method?
image

I am looking forward it:

In the future, we will look to provide an already deployed library, which you may link your contracts to.

What the actual price for the URL request?

Hi,

From the manual we can learn that the base price for the URL request is 0.01$
But I've got 0.0040336 Ether (for this days) for this contact code:

  function getTokens(address beneficiary) public payable {
        require(beneficiary != address(0));
        uint256 price =  oraclize_getPrice("URL");
        if (price > msg.value) {
            LogNewOraclizeQuery("Oraclize query was NOT sent");
        } else {
            LogNewOraclizeQuery("Oraclize query was sent, standing by for the answer..");
            // TODO creating query with address parameter
            bytes32 queryId =
                oraclize_query("URL", "xml(https://example.com/balances).tokenBalance");
            tokenHolders[queryId] = beneficiary;
        }
    }

    function __callback(bytes32 myid, string result) public{
        require(msg.sender == oraclize_cbAddress());

        uint tokenBalance = parseInt(result, 2);
        address beneficiary = tokenHolders[myid];

        token.mint(beneficiary, tokenBalance);
    }

https://ropsten.etherscan.io/tx/0x8c2168ce411f175b999ec362f8f9ac06a42b84175a46dc796448dfa3c6833a55

0.0040336 Ether - 0.004 (200 000 gas limit * 20Gwei) = 0.0000366 Ether = 0.03$

So, what the actual price for the URL request and how to know it?

Thank you.

Huge count of warnings on 0.4.18

like

Warning: No visibility specified. Defaulting to "public".
Warning: "throw" is deprecated in favour of "revert()", "require()" and "assert()".
Warning: "sha3" has been deprecated in favour of "keccak256"
...

Oraclize not working on Kovan testnet

Hi,
We have been using Oraclize on Kovan for quite some time. Off late, oraclize is not working on Kovan. We also tried to test it separately using the code provided in your documentation.
`pragma solidity ^0.4.11;
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";

contract ExampleContract is usingOraclize {

string public EURGBP;
event updatedPrice(string price);
event newOraclizeQuery(string description);

function ExampleContract() payable {
    updatePrice();
}

function __callback(bytes32 myid, string result) {
    if (msg.sender != oraclize_cbAddress()) throw;
    EURGBP = result;
    updatedPrice(result);
}

function updatePrice() payable {
    if (oraclize_getPrice("URL") > this.balance) {
        newOraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee");
    } else {
        newOraclizeQuery("Oraclize query was sent, standing by for the answer..");
        oraclize_query("URL", "json(http://api.fixer.io/latest?symbols=USD,GBP).rates.GBP");
    }
}

}`

We get the log as "Oraclize query was sent, standing by for the answer.." in the transaction sent but do not receive the callback event. Can you please help.

Truffle Compiler Warning: This function only accepts a single "bytes" argument.

I'm getting this error using OraclizeAPI_0.5.sol, I've tried solidity versions 0.4.18 to 0.4.20, Can you please help me out?

truffle/contracts/OraclizeAPI_0.5.sol:962:50: Warning: This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data. oraclize_randomDS_setCommitment(queryId, keccak256(delay_bytes8_left, args[1], sha256(args[0]), args[2]));

Error when importing the library oraclizeAPI.sol

Hello, if anyone can help me out on this error when importing oraclizeAPI , very much appreciated!
the Remix version :Current version:0.4.19-nightly.2017.11.30+commit.f5a2508e.Emscripten.clang

pragma solidity ^0.4.19;
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";

Error: github.com/oraclize/ethereum-api/oraclizeAPI.sol:39:53: ParserError: Expected token Comma got 'Identifier'
function query(uint _timestamp, string calldata _datasource, string calldata _arg) external payable returns (bytes32 _id);
^

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.