Ethereum Chainlink HTTP Get 不 ping 我的 HTTP 端点
Ethereum Chainlink HTTP Get not pinging my HTTP endpoint
我正在尝试使用 Chainlink 将我的以太坊智能合约连接到外部 HTTP 端点。按照 Chainlink 的文档 (https://docs.chain.link/docs/advanced-tutorial/),我将该合约部署到 Rinkeby 测试网上。
pragma solidity ^0.8.7;
import "github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/ChainlinkClient.sol";
// MyContract inherits the ChainlinkClient contract to gain the
// functionality of creating Chainlink requests
contract getHTTP is ChainlinkClient {
using Chainlink for Chainlink.Request;
bytes32 private thisDoesNotWork;
address private owner;
address private ORACLE_ADDRESS = 0x718Cc73722a2621De5F2f0Cb47A5180875f62D60;
bytes32 private JOBID = stringToBytes32("86b489ec4d84439c96181a8df7b22223");
string private url = "<myHTTPAddressAsString>";
// This endpoint URL is hard coded in my contract, and stored as a string (as in the example code).
// I control it and can have it reply with whatever I want, which might be an issue, returning data in a format that the oracle rejects
uint256 constant private ORACLE_PAYMENT = 100000000000000000;
constructor() public {
// Set the address for the LINK token for the network
setPublicChainlinkToken();
owner = msg.sender;
}
function requestBytes()
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(JOBID, address(this), this.fulfill.selector);
req.add("get", url);
sendChainlinkRequestTo(ORACLE_ADDRESS, req, ORACLE_PAYMENT);
}
function fulfill(bytes32 _requestId, bytes32 recVal)
public
recordChainlinkFulfillment(_requestId)
{
thisDoesNotWork = recVal;
}
function cancelRequest(
bytes32 _requestId,
uint256 _payment,
bytes4 _callbackFunctionId,
uint256 _expiration
)
public
onlyOwner
{
cancelChainlinkRequest(_requestId, _payment, _callbackFunctionId, _expiration);
}
// withdrawLink allows the owner to withdraw any extra LINK on the contract
function withdrawLink()
public
onlyOwner
{
LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
require(link.transfer(msg.sender, link.balanceOf(address(this))), "Unable to transfer");
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
// A helper funciton to make the string a bytes32
function stringToBytes32(string memory source) private pure returns (bytes32 result) {
bytes memory tempEmptyStringTest = bytes(source);
if (tempEmptyStringTest.length == 0) {
return 0x0;
}
assembly { // solhint-disable-line no-inline-assembly
result := mload(add(source, 32))
}
}
}
我在 Chainlink 市场 (https://market.link/jobs/529c7194-c665-4b30-8d25-5321ea49d9cc) 上发现了一个当前在 rinkeby 上活跃的节点(根据 Etherscan,它在过去 3 天内一直处于活跃状态并且可能仍在工作)。
我使用 LINK 部署合约并为合约提供资金。我通过 remix 调用 requestBytes() 函数,一切都按预期进行。 Metamask 支付 gas,LINK 从我的合约中删除,我得到一个交易哈希,没有错误。
但是,我的端点从不记录请求尝试,预言机从不在其 Etherscan 页面上列出交易,并且我的数据不存在。
我尝试使用来自 Chainlink 市场的其他工作得到类似的结果。
我也曾尝试使用其他 HTTP 端点,例如 Chainlink 示例中的端点,得到类似的结果,但我怀疑这是问题所在,因为似乎 HTTP 请求从未被调用(由事实上我的 HTTP 端点没有记录请求)
没有错误消息,而且是 Web3 开发新手,我不知道从哪里开始调试。我在 Github 上找到了这条评论:https://github.com/smartcontractkit/documentation/issues/513 并不幸地实施了这里的建议。
我也发现了这个:Chainlink - Job not being fulfilled 但这也没有帮助。
我目前对错误可能出处的考虑:
神谕被列入白名单并直接拒绝我的请求。考虑过创建我自己的节点,但在这个阶段希望尽可能避免。
我在合同中格式化请求时遇到类型错误,就像我在上面找到并引用的 GitHub 交换中的示例一样。
编辑:如果有人有任何建议,我也愿意接受除 Chainlink 之外的其他选项,将我的合约连接到 HTTP GET 端点。谢谢!
我最近一直在做类似的事情,建议你尝试使用 kovan 网络和 chainlink 的预言机。更具体地说,我认为确认您可以使用您正在关注的该页面上示例中列出的 api、oracle 和 jobid 使其正常工作是个好主意……这里:
https://docs.chain.link/docs/advanced-tutorial/#contract-example
一旦您使该示例正常工作,您就可以根据自己的使用情况对其进行修改。该教程中的 jobid 用于 return 一个(相乘的)uint256...对于您的 API,我认为这不是您想要的,因为您想要的是 bytes32,这听起来像...所以当您尝试将它与 API 一起使用时,returns bytes32 jobid 将是:7401f318127148a894c00c292e486ffd,如下所示:
https://docs.chain.link/docs/decentralized-oracles-ethereum-mainnet/
可能是您的问题的另一件事是您的 api。你说你控制它 returns...我认为它可能必须 return 字节格式的响应,就像帕特里克在他的回复(以及他对他的回复的评论)中所说:
Get a string from any API using Chainlink Large Response Example
希望这对您有所帮助。如果您无法使 chainlink 文档中的示例正常工作,请告诉我。
我正在尝试使用 Chainlink 将我的以太坊智能合约连接到外部 HTTP 端点。按照 Chainlink 的文档 (https://docs.chain.link/docs/advanced-tutorial/),我将该合约部署到 Rinkeby 测试网上。
pragma solidity ^0.8.7;
import "github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/ChainlinkClient.sol";
// MyContract inherits the ChainlinkClient contract to gain the
// functionality of creating Chainlink requests
contract getHTTP is ChainlinkClient {
using Chainlink for Chainlink.Request;
bytes32 private thisDoesNotWork;
address private owner;
address private ORACLE_ADDRESS = 0x718Cc73722a2621De5F2f0Cb47A5180875f62D60;
bytes32 private JOBID = stringToBytes32("86b489ec4d84439c96181a8df7b22223");
string private url = "<myHTTPAddressAsString>";
// This endpoint URL is hard coded in my contract, and stored as a string (as in the example code).
// I control it and can have it reply with whatever I want, which might be an issue, returning data in a format that the oracle rejects
uint256 constant private ORACLE_PAYMENT = 100000000000000000;
constructor() public {
// Set the address for the LINK token for the network
setPublicChainlinkToken();
owner = msg.sender;
}
function requestBytes()
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(JOBID, address(this), this.fulfill.selector);
req.add("get", url);
sendChainlinkRequestTo(ORACLE_ADDRESS, req, ORACLE_PAYMENT);
}
function fulfill(bytes32 _requestId, bytes32 recVal)
public
recordChainlinkFulfillment(_requestId)
{
thisDoesNotWork = recVal;
}
function cancelRequest(
bytes32 _requestId,
uint256 _payment,
bytes4 _callbackFunctionId,
uint256 _expiration
)
public
onlyOwner
{
cancelChainlinkRequest(_requestId, _payment, _callbackFunctionId, _expiration);
}
// withdrawLink allows the owner to withdraw any extra LINK on the contract
function withdrawLink()
public
onlyOwner
{
LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
require(link.transfer(msg.sender, link.balanceOf(address(this))), "Unable to transfer");
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
// A helper funciton to make the string a bytes32
function stringToBytes32(string memory source) private pure returns (bytes32 result) {
bytes memory tempEmptyStringTest = bytes(source);
if (tempEmptyStringTest.length == 0) {
return 0x0;
}
assembly { // solhint-disable-line no-inline-assembly
result := mload(add(source, 32))
}
}
}
我在 Chainlink 市场 (https://market.link/jobs/529c7194-c665-4b30-8d25-5321ea49d9cc) 上发现了一个当前在 rinkeby 上活跃的节点(根据 Etherscan,它在过去 3 天内一直处于活跃状态并且可能仍在工作)。
我使用 LINK 部署合约并为合约提供资金。我通过 remix 调用 requestBytes() 函数,一切都按预期进行。 Metamask 支付 gas,LINK 从我的合约中删除,我得到一个交易哈希,没有错误。
但是,我的端点从不记录请求尝试,预言机从不在其 Etherscan 页面上列出交易,并且我的数据不存在。
我尝试使用来自 Chainlink 市场的其他工作得到类似的结果。
我也曾尝试使用其他 HTTP 端点,例如 Chainlink 示例中的端点,得到类似的结果,但我怀疑这是问题所在,因为似乎 HTTP 请求从未被调用(由事实上我的 HTTP 端点没有记录请求)
没有错误消息,而且是 Web3 开发新手,我不知道从哪里开始调试。我在 Github 上找到了这条评论:https://github.com/smartcontractkit/documentation/issues/513 并不幸地实施了这里的建议。
我也发现了这个:Chainlink - Job not being fulfilled 但这也没有帮助。
我目前对错误可能出处的考虑:
神谕被列入白名单并直接拒绝我的请求。考虑过创建我自己的节点,但在这个阶段希望尽可能避免。
我在合同中格式化请求时遇到类型错误,就像我在上面找到并引用的 GitHub 交换中的示例一样。
编辑:如果有人有任何建议,我也愿意接受除 Chainlink 之外的其他选项,将我的合约连接到 HTTP GET 端点。谢谢!
我最近一直在做类似的事情,建议你尝试使用 kovan 网络和 chainlink 的预言机。更具体地说,我认为确认您可以使用您正在关注的该页面上示例中列出的 api、oracle 和 jobid 使其正常工作是个好主意……这里:
https://docs.chain.link/docs/advanced-tutorial/#contract-example
一旦您使该示例正常工作,您就可以根据自己的使用情况对其进行修改。该教程中的 jobid 用于 return 一个(相乘的)uint256...对于您的 API,我认为这不是您想要的,因为您想要的是 bytes32,这听起来像...所以当您尝试将它与 API 一起使用时,returns bytes32 jobid 将是:7401f318127148a894c00c292e486ffd,如下所示:
https://docs.chain.link/docs/decentralized-oracles-ethereum-mainnet/
可能是您的问题的另一件事是您的 api。你说你控制它 returns...我认为它可能必须 return 字节格式的响应,就像帕特里克在他的回复(以及他对他的回复的评论)中所说:
Get a string from any API using Chainlink Large Response Example
希望这对您有所帮助。如果您无法使 chainlink 文档中的示例正常工作,请告诉我。