We have been trying to use a mapping to store multiple Oraclize queries and their results but it does not seem to be working properly. What is the ideal way to store multiple Oraclize queries by their query ID's?

We have a Oraclize query in which we modify the middle by changing the ID number and need to store these by their number so we can get them later.

mapping(bytes32 => OraclizeQueries) public validIDs;

function fetchMatchResults(uint _matchID) payable onlyOwner {
    bytes32 queryId = oraclize_query("URL",  strConcat(firstHalfQuery, 
          uint2str(_matchID), secondHalfQuery));
    validIDs[queryId] = OraclizeQueries("");
    pickWinner(_matchID, validIDs[queryId].result);

function __callback(bytes32 oracleID, string result){
    if(msg.sender != oraclize_cbAddress()) revert();
    require(bytes(validIDs[oracleID].result).length == 0);
    validIDs[oracleID].result = result;
  • Hi there. The best way is to use a mapping, with the bytes32 ID as the key, and whatever you require as the value. (e.g. A struct containing any details from the first transaction that you'll require in the callback.) If you post your code someone might be able to help with why it's not working. – Richard Horrocks Oct 10 '18 at 15:54
  • Hey Richard i have uploaded the code if you could please take a look – Icey Oct 11 '18 at 14:17
  • Hi again. What does the pickWinner() function do? When you say the code doesn't work, what are the symptoms? What behaviour are you expecting, compared with what's actually happening? – Richard Horrocks Oct 11 '18 at 17:14

When saving an oraclize query, you might be interested in creating a final mapping between the input paramters of the oraclize_query and the results from the Oracle.

You can achieve this using 2 mappings:

mapping(string => string) public InputToResult;
mapping(bytes32 => string) internal QueryIdToQuery;

Note that the specific types here may change for your scenario, but you should be able to follow along and modify this code for your needs.

The Oraclize process is a two step, asynchronous process. The first step is sending out the query:

function oraclizeQuery(string _postId) public payable {
    // Check if we have enough remaining funds
    require(oraclize_getPrice("URL") > address(this).balance);

    string memory query = /*your query here*/;
    bytes32 queryId = oraclize_query("URL", query);
    QueryIdToQuery[queryId] = query;

Here we generate a query url, send out the oraclize_query call, and save the queryId that gets generated as a result, mapping it to the specific query url we sent out.

Then the second part is the oracle calling our __calback function:

function __callback(bytes32 _id, string _result, bytes _proof) public {
    require(msg.sender == oraclize_cbAddress());
    // stringNotEmpty is a custom function to check that the string has length greater than 0

    bytes32 Input = QueryIdToQuery[_id];
    InputToResult[Input] = _result;

Here we get our resulting data along with the queryId we stored before. First we check that the caller of this function is the oraclize oracle, then we check that the _id returned matches a queryId we sent out (sanity check). Finally, we use our QueryIdToQuery mapping to retrieve the original query that was used to generate the result, and create a final object containing a mapping from input to output.

Now you will be able to store the results of multiple oraclize queries, while being able to correctly associate the returned data with the input data you sent to the oracle.

The code above is modified from an actual working contract which fetches twitter posts:


The specific implementation in the Twitter Oracle is more tuned, rather than the pseudo code above.

|improve this answer|||||
  • This worked for us! Thank you so much for explaining how to do this, you're the best! – Icey Oct 12 '18 at 17:06

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.