繁体   English   中英

如何使用 Chainlink api 调用从 api 返回的 json 检索字符串值

[英]How do I use a Chainlink api call to retrieve a string value from json returne by api

我正在尝试使用 chainlink 请求进行 api 调用,然后使用 api 调用的结果更新 volume 变量。

api 调用应检索一个字符串。 在部署智能合约并为其提供资金后,我似乎能够成功拨打 api 电话(尽管我对此不确定)。 问题是 volume 变量没有更新。

我改编了chainlink 教程中的代码。 原始教程代码有效,在我看来我所做的更改也应该有效。 有人能帮忙吗?

 // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol"; /** * Request tes.net LINK and ETH here: https://faucets.chain.link/ * Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/ */ /** * THIS IS AN EXAMPLE CONTRACT WHICH USES HARDCODED VALUES FOR CLARITY. * PLEASE DO NOT USE THIS CODE IN PRODUCTION. */ contract APIConsumer is ChainlinkClient { using Chainlink for Chainlink.Request; string public volume; address private oracle; bytes32 private jobId; uint256 private fee; /** * Network: Kovan * Oracle: 0xc57B33452b4F7BB189bB5AfaE9cc4aBa1f7a4FD8 (Chainlink Devrel * Node) * Job ID: d5270d1c311941d0b08bead21fea7747 * Fee: 0.1 LINK */ constructor() { setPublicChainlinkToken(); oracle = 0xF405B99ACa8578B9eb989ee2b69D518aaDb90c1F; jobId = "c51694e71fa94217b0f4a71b2a6b565a"; fee = 0.1 * 10 ** 18; // (Varies by.network and job) } /** * Create a Chainlink request to retrieve API response, find the target * data, then multiply by 1000000000000000000 (to remove decimal places from data). */ function requestVolumeData() public returns (bytes32 requestId) { Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfill.selector); // Set the URL to perform the GET request on request.add("get", "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD"); // Set the path to find the desired data in the API response, where the response format is: // {"RAW": // {"ETH": // {"USD": // { // "VOLUME24HOUR": xxx.xxx, // } // } // } // } request.add("path", "RAW.ETH.USD.MARKET"); // // Multiply the result by 1000000000000000000 to remove decimals // int timesAmount = 10**18; // request.addInt("times", timesAmount); // Sends the request return sendChainlinkRequestTo(oracle, request, fee); } /** * Receive the response in the form of uint256 */ function fulfill(bytes32 _requestId, bytes32 _volume) public recordChainlinkFulfillment(_requestId) { volume = bytes32ToString(_volume); } function bytes32ToString(bytes32 _bytes32) public pure returns (string memory) { uint8 i = 0; while(i < 32 && _bytes32[i];= 0) { i++; } bytes memory bytesArray = new bytes(i); for (i = 0; i < 32 && _bytes32[i];= 0; i++) { bytesArray[i] = _bytes32[i]; } return string(bytesArray); } // function withdrawLink() external {} - Implement a withdraw function to avoid locking your LINK in the contract }

要返回一个字符串,您实际上必须返回一个bytes32并将其转换为链上的字符串。

您可以使用类似这样的方法将 bytes32 转换为字符串:

function bytes32ToString(bytes32 _bytes32) public pure returns (string memory) {
        uint8 i = 0;
        while(i < 32 && _bytes32[i] != 0) {
            i++;
        }
        bytes memory bytesArray = new bytes(i);
        for (i = 0; i < 32 && _bytes32[i] != 0; i++) {
            bytesArray[i] = _bytes32[i];
        }
        return string(bytesArray);
    }

这是 AviationStack 的一个工作示例。 在 API URL 中将<access_key>替换为您的 access_key。

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import '@chainlink/contracts/src/v0.8/ChainlinkClient.sol';
import '@chainlink/contracts/src/v0.8/ConfirmedOwner.sol';

/**
 * Request testnet LINK and ETH here: https://faucets.chain.link/
 * Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
 */

/**
 * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY.
 * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
 * DO NOT USE THIS CODE IN PRODUCTION.
 */

contract AviationGenericLargeResponse is ChainlinkClient, ConfirmedOwner {
    using Chainlink for Chainlink.Request;

    // variable bytes(arbitrary-length raw byte data) returned in a single oracle response
    bytes public data;
    string public flightStatus;

    bytes32 private jobId;
    uint256 private fee;

    event RequestFulfilled(bytes32 indexed requestId, bytes indexed data);
    /**
     * @notice Initialize the link token and target oracle
     * @dev The oracle address must be an Operator contract for multiword response
     *
     *
     * Goerli Testnet details:
     * Link Token: 0x326C977E6efc84E512bB9C30f76E30c160eD06FB
     * Oracle: 0xCC79157eb46F5624204f47AB42b3906cAA40eaB7 (Chainlink DevRel)
     * jobId: 7da2702f37fd48e5b1b9a5715e3509b6
     *
     */
    constructor() ConfirmedOwner(msg.sender) {
        setChainlinkToken(0x326C977E6efc84E512bB9C30f76E30c160eD06FB);
        setChainlinkOracle(0xCC79157eb46F5624204f47AB42b3906cAA40eaB7);
        jobId = '7da2702f37fd48e5b1b9a5715e3509b6';
        fee = (1 * LINK_DIVISIBILITY) / 10; // 0,1 * 10**18 (Varies by network and job)
    }

    /**
     * @notice Request variable bytes from the oracle
     */
    function requestBytes() public {
        Chainlink.Request memory req = buildChainlinkRequest(jobId, address(this), this.fulfillBytes.selector);
        req.add(
            'get',
            'http://api.aviationstack.com/v1/flights?access_key=a6656fabf7fbe4fde6e4061f5be7042a&flight_number=611&airline_name=Qantas&flight_status=landed&limit=1'
        );
        req.add('path', 'data,0,flight_status');
        sendChainlinkRequest(req, fee);
    }


    /**
     * @notice Fulfillment function for variable bytes
     * @dev This is called by the oracle. recordChainlinkFulfillment must be used.
     */
    function fulfillBytes(bytes32 requestId, bytes memory bytesData) public recordChainlinkFulfillment(requestId) {
        emit RequestFulfilled(requestId, bytesData);
        data = bytesData;
        flightStatus = string(data);
    }

    /**
     * Allow withdraw of Link tokens from the contract
     */
    function withdrawLink() public onlyOwner {
        LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
        require(link.transfer(msg.sender, link.balanceOf(address(this))), 'Unable to transfer');
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM