blockchain - “VM Exception while processing transaction: revert”,当运行chainlink节点并尝试部署TestnetConsumer合约时?
问题描述
场景是通过 Remix 在 mathchain 上部署ATestnetConsumer.sol时,按照官方教程在 mathchain 上运行一个节点,这是一个兼容 EVM 的公共链。我完成了 Oracle 合约和 LINKToken 合约的部署,并在 mathchain 上成功运行了节点,但是在尝试部署 TestnetConsumer 合约时,它显示:
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
Internal JSON-RPC error. { "code": -32603, "message": "VM Exception while processing transaction: revert", "data": "" }
有人知道为什么吗?
TestnetConsumer 合约列表如下:
pragma solidity 0.4.24;
import "https://github.com/smartcontractkit/chainlink/evm-contracts/src/v0.4/ChainlinkClient.sol";
import "https://github.com/smartcontractkit/chainlink/evm-contracts/src/v0.4/vendor/Ownable.sol";
contract ATestnetConsumer is ChainlinkClient, Ownable {
uint256 constant private ORACLE_PAYMENT = 1 * LINK;
uint256 public currentPrice;
int256 public changeDay;
bytes32 public lastMarket;
event RequestEthereumPriceFulfilled(
bytes32 indexed requestId,
uint256 indexed price
);
event RequestEthereumChangeFulfilled(
bytes32 indexed requestId,
int256 indexed change
);
event RequestEthereumLastMarket(
bytes32 indexed requestId,
bytes32 indexed market
);
constructor() public Ownable() {
setPublicChainlinkToken();
}
function requestEthereumPrice(address _oracle, string _jobId)
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), this, this.fulfillEthereumPrice.selector);
req.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD");
req.add("path", "USD");
req.addInt("times", 100);
sendChainlinkRequestTo(_oracle, req, ORACLE_PAYMENT);
}
function requestEthereumChange(address _oracle, string _jobId)
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), this, this.fulfillEthereumChange.selector);
req.add("get", "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD");
req.add("path", "RAW.ETH.USD.CHANGEPCTDAY");
req.addInt("times", 1000000000);
sendChainlinkRequestTo(_oracle, req, ORACLE_PAYMENT);
}
function requestEthereumLastMarket(address _oracle, string _jobId)
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), this, this.fulfillEthereumLastMarket.selector);
req.add("get", "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD");
string[] memory path = new string[](4);
path[0] = "RAW";
path[1] = "ETH";
path[2] = "USD";
path[3] = "LASTMARKET";
req.addStringArray("path", path);
sendChainlinkRequestTo(_oracle, req, ORACLE_PAYMENT);
}
function fulfillEthereumPrice(bytes32 _requestId, uint256 _price)
public
recordChainlinkFulfillment(_requestId)
{
emit RequestEthereumPriceFulfilled(_requestId, _price);
currentPrice = _price;
}
function fulfillEthereumChange(bytes32 _requestId, int256 _change)
public
recordChainlinkFulfillment(_requestId)
{
emit RequestEthereumChangeFulfilled(_requestId, _change);
changeDay = _change;
}
function fulfillEthereumLastMarket(bytes32 _requestId, bytes32 _market)
public
recordChainlinkFulfillment(_requestId)
{
emit RequestEthereumLastMarket(_requestId, _market);
lastMarket = _market;
}
function getChainlinkToken() public view returns (address) {
return chainlinkTokenAddress();
}
function withdrawLink() public onlyOwner {
LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
require(link.transfer(msg.sender, link.balanceOf(address(this))), "Unable to transfer");
}
function cancelRequest(
bytes32 _requestId,
uint256 _payment,
bytes4 _callbackFunctionId,
uint256 _expiration
)
public
onlyOwner
{
cancelChainlinkRequest(_requestId, _payment, _callbackFunctionId, _expiration);
}
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))
}
}
}
解决方案
问题出在构造函数上:
constructor() public Ownable() {
setPublicChainlinkToken();
}
当您在公链上运行一个节点,并部署一个全新的 LINKToken 合约作为transferAndCall
您自己节点提供的服务的方式时,请记住将以下行替换 setPublicChainlinkToken()
为:
// set the Oracle contract address
setChainlinkOracle(YOUR_ORACLE_CONTRACT_ADDRESS);
// set LINKToken contract address
setChainlinkToken(YOUR_LINKTOKEN_CONTRACT_ADDRESS);
那么你应该很高兴。请记住,在调用该函数以从您的 Chainlink 节点获取服务之前,您应该存入一些 LINK 令牌!
推荐阅读
- angular - 子模块的角度合并路线
- c++ - 类类型的“不允许不完整类型”数组
- java - 将 Json.jar 导入一个简单的 Java 项目
- reactjs - 使用 Github Pages 创建主页
- excel - 使用 VBA 清理 Excel 表格而不影响整个表格和格式
- ruby - 使用 Shrine 提取背景中的图像尺寸
- angular-cli - Angular 应用程序安装错误:在“...//registry.npmjs.org/”附近解析时 JSON 输入意外结束
- ios - 如何在没有导航栏的应用程序的 Xamarin 上使状态栏不透明
- haskell - 哈斯克尔。如何在 GHCi 中测试 BTree?
- selenium - else if 语句未在 Switch 中执行