Analizar JSON en Solidity

¿Cómo puedo analizar JSON en solidez?

La idea es tener una función o similar que pueda analizar JSON dentro de un contrato de Solidity.

Con un objeto JSON simple (solo cadenas de valores clave, como {'A': 'a', 'B': 'b'}), la solución debería poder transformarlo en una asignación (cadena => cadena).

Respuestas (3)

Asumiré que desea llamar a una fuente externa sobre la cual no puede tener control y que usa la fuente de datos json() Oraclize para obtener solo la parte correcta del servicio json que se devuelve cuando llama a su URL como se indica en la documentación de fuentes de datos disponibles de Oracle .

Por ahora, creo que no tiene forma de hacer que Oraclize devuelva algo más que una cadena. Eso significa que debe obtener el Json devuelto como un parámetro de cadena de su __callbackfunción oraclize.

Pero luego, como pregunta, necesita analizar el json en una matriz. Esto sería muy costoso incluso si encuentra una manera de hacerlo.

Entonces, la respuesta corta sería que lo que pides no es posible.

Sin embargo, permítanme sugerir las siguientes soluciones alternativas, no totalmente satisfactorias. Sé que son solo soluciones alternativas que probablemente no se ajusten a sus necesidades, pero creo que lo que quiere hacer no es posible por ahora, así que tratemos de acercarnos lo más posible a la meta.

Soluciones alternativas:

  1. use un sitio web proxy que pueda solicitar su servicio original, el que no controla, y analice el json resultante usando lo que pueda usar como lenguaje del lado del servidor. haga que formatee el resultado como una cadena de una sola línea con separador (es decir, una coma). Luego dígale a Oraclize que consulte este proxy en lugar del servicio original. Luego, su contrato obtendrá la cadena que será más fácil y rentable de analizar y dividir. Puede crear una función de división basada en esta cadena de Solidity utils lib . Tenga en cuenta que no encontrará una función de división para dividir su cadena en más de 2 segmentos en esta biblioteca, pero este es un buen punto de partida.
  2. Con la función URL de Oracle Json(), puede usar XPath para apuntar a un valor en el resultado JSON. Puede comparar el costo de dividir una cadena de resultados con el costo de llamar a Oraclize varias veces para orientar cada elemento de resultado por separado. No puedo decir cuál es más barato, incluso si supongo que realmente depende de la longitud de las cadenas de elementos de resultado.
  3. Si usa su contrato solo desde un Dapp, le sugiero que llame al servicio original directamente con el JS del lado del cliente y olvide Oraclize, extraiga valores de él y luego llame a un método en el que pueda pasar cada valor como un parámetro. Pero supongo que si usas Oraclize es probable que quieras que tu contrato sea autónomo.
Gracias por las soluciones, tal vez debería cambiar la arquitectura de mi contrato, porque en este momento no puedo resolverlo así.

El análisis de cadenas probablemente será prohibitivamente costoso dentro del EVM. ¿Por qué desea realizar un análisis dentro del EVM cuando podría hacerlo trivialmente desde el exterior y pasar los datos ya en el formato correcto?

En su ejemplo específico, si solo desea cargar una cadena-> mapeo de cadenas, puede pasar dos matrices de cadenas como parámetros, una de las cuales son las claves y la segunda los valores. Un ciclo for simple podría cargarlo en un mapeo de Solidity sin ninguna sobrecarga de análisis.

Necesito recibir una respuesta de Oraclize.it y es un JSON, por lo que ingresar el JSON en partes debería costar 2 consultas a Oraclize

Sé que esta pregunta es bastante antigua, sin embargo, agregaré mi opinión de todos modos.

Si su JSON es lo suficientemente pequeño, podría valer la pena analizarlo en cadena para evitar la molestia y el costo de dos o más llamadas orquestadas a un oráculo. Acabo de publicar la primera versión de un analizador JSON para Solidity en github: https://github.com/chrisdotn/jsmnSol

Si quieres usarlo debes:

  1. Asegúrese de que el JSON sea pequeño. La mejor manera de hacerlo (si está utilizando oraclize.it) es encontrar un JSONPath adecuado para que el JSON contenga solo los elementos que le interesan.
  2. Analice el JSON más pequeño en cadena con el analizador. Después de eso, tiene metainformación en la cadena JSON que permite ubicar los elementos y obtener sus contenidos.

Una introducción más completa está en medio: https://medium.com/@chrisdotn/a-json-parser-for-solidity-9cc73b4b42

Entonces, en esencia, lo que hace esta respuesta es proporcionar una forma de usar la opción (2) de la respuesta de Nicolás.