Получение отдельных элементов массива из данных, возвращаемых внешним адаптером chainlink

#chainlink

Вопрос:

В задании, которое я добавляю для своего внешнего адаптера, я хочу получать результаты для первых 3 элементов в Results массиве по одному.(см. Данные, возвращенные с моего внешнего адаптера ниже)

Итак, я добавляю «позицию» к своему запросу chainlink в потребительском контракте и хочу использовать это в приведенном jsonparse ниже примере, а не передавать его внешнему адаптеру. Однако я получаю эту ошибку JSONParse task error: $(decode_cbor.position) is not a valid array index

 parse        [type=jsonparse path="data,MRData,RaceTable,Races,0,Results,$(decode_cbor.position),number" data="$(fetch)"]```
 

в моем потребительском контракте

 Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
request.add("position", "1");
 

Данные, возвращаемые внешним адаптером, выглядят следующим образом.

 {
    "MRData": {
        "xmlns": "http://ergast.com/mrd/1.4",
        "series": "f1",
        "url": "http://ergast.com/api/f1/current/last/results.json",
        "limit": "30",
        "offset": "0",
        "total": "20",
                
        "RaceTable": {
            "season": "2021",
            "round": "17",
        
          "Races": [{
                "season": "2021",
                "round": "17",
                "url": "http://en.wikipedia.org/wiki/2021_United_States_Grand_Prix",
                "raceName": "United States Grand Prix",
                "Circuit": {
                    "circuitId": "americas",
                    "url": "http://en.wikipedia.org/wiki/Circuit_of_the_Americas",
                    "circuitName": "Circuit of the Americas",
                    "Location": {
                        "lat": "30.1328",
                        "long": "-97.6411",
                        "locality": "Austin",
                        "country": "USA"
                    }
                },
                "date": "2021-10-24",
                "time": "19:00:00Z",
        
                "Results": [{
                    "number": "33",
                    "position": "1",
                    "positionText": "1",
                    "points": "25",
                    "Driver": {
                        "driverId": "max_verstappen",
                        "permanentNumber": "33",
                        "code": "VER",
                        "url": "http://en.wikipedia.org/wiki/Max_Verstappen",
                        "givenName": "Max",
                        "familyName": "Verstappen",
                        "dateOfBirth": "1997-09-30",
                        "nationality": "Dutch"
                    },.....
 

Полные результаты можно найти здесь . http://ergast.com/api/f1/current/last/results.json

Должен ли я быть в состоянии сделать что-то подобное? Есть ли лучший способ сделать это? Должен ли я вместо этого отредактировать адаптер?

 schemaVersion = 1
name = "f1latestresults2"
contractAddress = "0x765aCc258f3a7b2D8d103D1A9310fc51b07D5425"
maxTaskDuration = "0s"
observationSource = """
    decode_log   [type=ethabidecodelog
                  abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)"
                  data="$(jobRun.logData)"
                  topics="$(jobRun.logTopics)"]

    decode_cbor  [type=cborparse data="$(decode_log.data)"]

    fetch        [type=bridge name="raceresults" requestData="{\"id\":$(jobSpec.externalJobID),\"data\":{\"position\":\"0\"}}"]
    

    parse        [type=jsonparse path="data,MRData,RaceTable,Races,0,Results,$(decode_cbor.position),number" data="$(fetch)"]

    encode_data  [type=ethabiencode abi="(uint256 value)" data="{ \"value\": $(parse) }"]
    encode_tx    [type=ethabiencode
                  abi="fulfillOracleRequest(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes32 data)"
                  data="{\"requestId\": $(decode_log.requestId), \"payment\": $(decode_log.payment), \"callbackAddress\": $(decode_log.callbackAddr), \"callbackFunctionId\": $(decode_log.callbackFunctionId), \"expiration\": $(decode_log.cancelExpiration), \"data\": $(encode_data)}"
                 ]
    submit_tx    [type=ethtx to="0x765aCc258f3a7b2D8d103D1A9310fc51b07D5425" data="$(encode_tx)"]

    decode_log -> decode_cbor -> fetch -> parse -> encode_data -> encode_tx -> submit_tx
"""
externalJobID = "cfa059b4-a31d-4c30-99e4-3a2fd4c57739"
 

Комментарии:

1. Можете ли вы добавить полную спецификацию задания TOML?

2. Добавлено выше благодаря. обратите внимание, что я передаю позицию внешнему адаптеру, даже если он в этом не нуждается, потому что я не разобрался, как выполнить выборку без передачи некоторых данных, поскольку при ее удалении возникают ошибки.

Ответ №1:

Используемый вами синтаксис выглядит для меня правильным, поэтому я не уверен на 100%, могут ли задания TOML поддерживать наличие такого параметра в строке?

Если остальная часть пути JSON является статической, предложите просто использовать ее как встроенную строку в вашем потребительском контракте и просто отправить ее как полную строку в запросе, а затем использовать ее в вашей спецификации TOML, аналогично примеру в документах

 req.add("path", "data,MRData,RaceTable,Races,0,Results,0");
 

Затем в вашей спецификации задания TOML:

 parse        [type=jsonparse path="$(decode_cbor.path)" data="$(fetch)"]
 

Комментарии:

1. Спасибо, это должно сделать его приятным и простым.