Как сделать асинхронный вызов оракула прочности ChainLink?

Мне нужно ввести uint в мой контракт Ethereum. Я тестирую этот код в Коване на основе этого примера: https://docs.chain.link/docs/make-a-http-get-request/

pragma solidity ^0.6.0;

import "https://raw.githubusercontent.com/smartcontractkit/chainlink/develop/evm-contracts/src/v0.6/ChainlinkClient.sol";

// SPDX-License-Identifier: UNLICENSED

contract ChainlinkExample is ChainlinkClient {
  
    uint256 public price;
    
    address private oracle;
    bytes32 private jobId;
    uint256 private fee;
    
    constructor() public {
        setPublicChainlinkToken();
        oracle = 0x2f90A6D021db21e1B2A077c5a37B3C7E75D15b7e;
        jobId = "29fa9aa13bf1468788b7cc4a500a45b8";
        fee = 0.1 * 10 ** 18; // 0.1 LINK
    }

    function requestEthereumPrice() public returns (bytes32 requestId){
        Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
            req.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD");//{"USD":1797.12}
            req.add("path", "USD");
            req.addInt("times", 100);
        return sendChainlinkRequestTo(oracle, request, fee);
    }

    function fulfill(bytes32 _requestId, uint256 _price) public recordChainlinkFulfillment(_requestId){
        price = _price;
    }

}

Все работает корректно, но функции "requestEthereumPrice()" требуется несколько секунд, чтобы сохранить переменную "цена".

Как я мог вызвать запрос, дождаться ответа и продолжить мои следующие вычисления кода?

Например, как я могу запросить цену API и выполнить операцию и вернуть результат в том же вызове функции?

Пожалуйста, не добавляйте другой вопрос к тому же вопросу в stackoverflow. Не могли бы вы создать новый вопрос под названием «Как вернуть вызов API Chainlink в другой контракт»?

Ответы (1)

В данном случае вы захотите поместить всю свою логику в функцию обратного вызова fulfill.

Например, если вы хотите отчеканить какой-либо токен на основе возврата вызова API, вы должны сделать что-то вроде:

function fulfill(bytes32 _requestId, uint256 _price) public recordChainlinkFulfillment(_requestId){
        price = _price;
        mint(price);
        // any other logic here
    }

Вызовы API Chainlink по своей природе асинхронны, поэтому вы не выполняете вызов API и не получаете ответ в одном и том же блоке.

Мне нужно вызвать функцию requestEthereumPrice() из другого контракта. Как вернуть "цену" в родительский контракт?
Вы бы хотели, чтобы адрес обратного вызова был другим контрактом. buildChainlinkRequest(jobId, address(this), this.fulfill.selector);заменить address(this)на любой адрес, на который вы хотите, чтобы он вернулся.
Привет, Патрик, я пытаюсь, но не могу заставить это работать простым способом. Не могли бы вы направить меня? Спасибо. (Смотрите раздел РЕДАКТИРОВАТЬ)