使用 chainlink 从外部 api 获取十进制数

get decimal number in solidity from external api with chainlink

我想从外部获取 Soldity 价格 api,我为此使用了 Chainlink :

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;
import "https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/ChainlinkClient.sol";

contract Fiat is ChainlinkClient {
    
    using Chainlink for Chainlink.Request;

    uint256 public price;
    
    bytes32 private jobId;
    uint256 private fee;
    
    constructor() {
        setPublicChainlinkToken();
        jobId = "83ba9ddc927946198fbd0bf1bd8a8c25";
        fee = 0.1 * 10 ** 18; // (Varies by network and job)
    }
    
    /**
     * Create a Chainlink request to retrieve API response, find the target price
     * data, then multiply by 100 (to remove decimal places from price).
     */
    function findExhangeRateFiatToBaseFiat(string memory _url
     , address _oracle) public returns (bytes32 requestId) 
    {
        Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
        
        // Set the URL to perform the GET request on
        // NOTE: If this oracle gets more than 5 requests from this job at a time, it will not return. 
        request.add("get", _url);
        
        string[] memory path = new string[](2);
        path[0] = "Realtime Currency Exchange Rate";
        path[1] = "5. Exchange Rate";
        request.addStringArray("path", path);
        
        // Multiply the result by 10000000000 to remove decimals
        request.addInt("times", 10000000000);
        
        // Sends the request
        return sendChainlinkRequestTo(_oracle, request, fee);
    }
    
    /**
     * Receive the response in the form of uint256
     */ 
    function fulfill(bytes32 _requestId, uint256 _price) public recordChainlinkFulfillment(_requestId)
    {
        price = _price;
    }

}

现在我有一个问题:

当我向这个 Api 发送请求时: https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency=IRR&to_currency=USD&apikey=K41HVINGOVEW3HHR

它告诉我这个结果:

{
    "Realtime Currency Exchange Rate": {
        "1. From_Currency Code": "IRR",
        "2. From_Currency Name": "Iranian Rial",
        "3. To_Currency Code": "USD",
        "4. To_Currency Name": "United States Dollar",
        "5. Exchange Rate": "0.00002381",
        "6. Last Refreshed": "2022-02-09 11:45:08",
        "7. Time Zone": "UTC",
        "8. Bid Price": "0.00002381",
        "9. Ask Price": "0.00002381"
    }
}

我想要这个结果:"5. Exchange Rate": "0.00002381"

但是当我在 Remix 中调用 Api 和调用 price 时,它显示了这个结果 238100 实际上它应该显示这个结果 0.00002381.

有什么问题?如何获取当前价格?

Kovan 测试网 甲骨文:0x58bbdbfb6fca3129b91f0dbe372098123b38b5e9 URL:https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency=IRR&to_currency=USD&apikey=K41HVINGOVEW3HHR

floats 或 double 在 solidity 中不存在,所以为了将它转换为数字,它去掉了小数点,我不太确定在这种情况下小数点是如何管理的,但你可以检查一下那么你可以用与处理 eth、gwei、wei 时类似的方式工作,你还应该检查这行代码如何影响响​​应 request.addInt("times", 10000000000);,因为它可以帮助你更改响应的格式