![](/img/trans.png)
[英]Chainlink Large Responses trying to return a String from any Api
[英]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.