1

I am trying to make a simple betting game using Oraclize in solidity. This code will ask Oraclize to provide a random number between 2 and 12. If this random number is same as the number guessed by user he will get 1 ether as prize, else he will loose his bet amount.

The problem I am facing is that Oraclize takes a while to mine and respond back with values in the callback function but in the meantime I believe the solidity code control moves ahead. Due to this the value returned by Oraclize never reaches the logic wherein I compare it against the user value and this in turn always leads to loosing the bet.

Please help me how can I handle this. In case I have done any mistake kindly highlight that, will be really grateful.

Please note that I am creating and running this code in Oraclize Remix app.

Thanks

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

        /*
         * @title Testing Oraclize
         * Test contract to understand the basics of leveraging the Oraclize service.
         */

        contract Betting is usingOraclize{
            address public player_;
            uint256 public betamount_;
            uint public winningamount_;
            uint private balance_;
            uint public betnumber_;
            uint public winningnumber_;
            uint public result_;
            string private question_;

        event LogNewOraclizeQuery(string description);
        event WinningNumber(uint winningnumber_);
        event BetResult(string result_);
        event Log( string mystring_);

        mapping (address => uint256) public balances;

        /*
        * Constructor
        * @dev Set the proof type and storage location.
        * NOTE if you wish to make several queries it may be a good idea to make your
        * constructor payable and deploy the contract with an endowment so that many
        * queries may be made without having to send ether with each. Only the first
        * query is free.
        * ie. function TestingOraclize() payable {} and deployer.deploy(TestingOraclize, { value: 10e18 })
        */
        /*
        function Betting(){
            OAR = OraclizeAddrResolverI(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475);
            oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
        }
        */

        /* Function to check balances of player and the bet host */
        function checkBalance (address player_, uint betamount_) private returns (bool isSuccess) {

        /* Check if account putting bet has sufficient amount to put bet */
            Log ("Checking players balance");
            require(player_.balance >= betamount_);

        /* Check if account putting bet has sufficient amount to put bet and ask question to Oraclize */
            Log ("Checking host's balance");
            require (msg.sender.balance >= 10*(betamount_));    

            Log ("Validation pass");
            return true;

        }

        function executeBetting (address player_, uint betamount_, uint betnumber_ ) public payable
             returns(uint answer_, string result_) {

        /* Call function to check if player and the host have sufficient balances*/
            checkBalance(player_, betamount_);
            require (true); 

        /* Get Random number from Oraclize */
             question_ = "random number between 2 and 12";
             askOraclize (question_);


        /* Compare the Random number sent from Oraclize with the user's bet*/

                if (betnumber_ ==  winningnumber_){
                    winningamount_ = 10e18;
                    player_.transfer(winningamount_);
                    result_ = 'You are lucky and have Won 1 Ether';
                }else
                if (betnumber_ !=  winningnumber_){ 
                    balances[player_] -= betamount_;
                    balances[msg.sender] += betamount_;
                    result_ = 'You lost';
                   }
                WinningNumber(winningnumber_);
                BetResult(result_);
                answer_ = winningnumber_;
        }


        /*
        * Query Wolfram to retrieve the answer to question sent.
        * Method is payable as only the first query is free! msg.value > oraclize fee for each
        * following query if the contract itself has an insiffucient balance.
        */
          /*function askOraclize(string question_ ,string answer_) public payable{*/
            function askOraclize(string question_) public payable{
             if (oraclize_getPrice("WolframAlpha") > this.balance) {
                 LogNewOraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee");
                }else{
                 LogNewOraclizeQuery("Oraclize query was sent, standing by for the answer..");    
                 oraclize_query("WolframAlpha", question_);
                }
            }    



            /**
            * Oraclize callback.
            * @param _myid The query id.
            * @param _result The result of the query.
            * @param _proof Oraclie generated proof. Stored in ipfs in this case.
            * Therefore is the ipfs multihash.
            */
              function __callback(
                bytes32 _myid,
                string _result,
                bytes _proof
              ) public
                  {
                    require(msg.sender == oraclize_cbAddress());
                    winningnumber_ = parseInt(_result); 
            }

        }
2

Since Orachlize is asynchronous, you have to put the logic that depends on the response in the callback itself. The oraclize_query function returns the id of the call (see here). You would store this query id along with the rest of the info regarding the bet in the state. Then when Oraclize calls your callback function with the query id, you would lookup the bet with the query id and process the information in the callback function. Alternatively, you could store the response from the Oraclize call along with the rest of the bet info and have the user call a finishBet function to then process/finalize the bet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.