Solidity JSON Parsing – How to Parse JSON in Solidity

contract-developmentsolidity

How can I parse JSON in solidity?

The idea is to have a function or similar which is able to parse JSON inside a Solidity contract.

With a simple JSON object (only key value strings, like {'A': 'a', 'B': 'b'}) the solution should be able to transform it to a mapping(string => string).

Best Answer

I'll assume that you want to call an external source on which you can't have control and that you use the json() Oraclize datasource in order to get only the right part of the service json that is returned when you call it's URL as indicated in Oraclize Available Datasources documentation.

For now I think you have no way to make Oraclize return anything else than a string. That means that you have to get the returned Json as a string parameter of your oraclize __callback function.

But then, as you ask, you need to parse the json to an array. This would be very costly even if you find a way to do it.

So the short answer would be that what you ask is not possible.

However, let me suggest the following, not totally satisfactory, workarounds. I know it's just workarounds that probably won't fit your needs but I think that what you want to do is not possible for now, so let's just try to go closest as possible from the goal.

Workarounds:

  1. use a proxy website that would be able to request you original service, the one you don't control, and parse the resulting json using whatever your can use as server side language. make it format the result as a single line string with separator (ie. a comma). Then tell Oraclize to query this proxy instead of the original service. Your contract will then get the string that will be more easy and cost efficient to parse and split. You can create a split function based on this Solidity string utils lib. Note that you won't find a split function to split your string in more than 2 slices in this lib but this is a good starting point.
  2. With the Oraclize Json() URL function, you can use XPath to target a value in the JSON result. You could compare the cost of splitting a result string to the cost of calling Oraclize multiple times to target each result item separately. I can't say which is cheaper even if I guess that it really depends of the length of your result items strings.
  3. If you use your contract from a Dapp only, I suggest you to call the original service directly with the client side JS and forget Oraclize, extract values from it and then call a method in which you could pass each value as a parameter. But I guess that if you use Oraclize it's probably that you want your contract to be autonomous.
Related Topic