混音:返回错误:{“jsonrpc”:“2.0”,“错误”:“无效操作码:PUSH0”,“id”:2405507186007008}

Kei*_*ke1 6 solidity go-ethereum chainlink

在我的 Ubuntu 中运行 geth 中的私有链节点和 Chainlink 节点后,我想测试 Chainlink Any API 的功能(https://docs.chain.link/any-api/get-request/examples/single-word -响应,单字响应)。

我运行这些命令来运行节点:

## SHELL1
cd ~/myChain/localChain/node1 && geth --datadir data --gcmode "archive" --syncmode=full --networkid 4190 --http --http.addr 0.0.0.0 --http.port 6789 --http.corsdomain "*" --ws --port 30305 --allow-insecure-unlock --unlock edd96278959aA8B27DdC14FD70ACb31f7e7beC2F --keystore ./keystore console

## SHELL2
cd ~/myChain/chainlink/.chainlink && docker run --net host -u=root  -p 6688:6688 -v ~/.chainlink:/chainlink -it --env-file=.env smartcontract/chainlink:1.11.0 local n
Run Code Online (Sandbox Code Playgroud)

我成功部署了我的LinkToken合约,operator并在我的 Chainlink 节点 UI Operator 中创建了一个新作业(GET>uint256)。它们如下:

链克.sol

pragma solidity ^0.4.11;

import "https://github.com/smartcontractkit/chainlink/contracts/src/v0.4/ERC677Token.sol";
import { StandardToken as linkStandardToken } from "https://github.com/smartcontractkit/chainlink/contracts/src/v0.4/vendor/StandardToken.sol";


contract LinkToken is linkStandardToken, ERC677Token {

  uint public constant totalSupply = 10**27;
  string public constant name = "ChainLink Token";
  uint8 public constant decimals = 18;
  string public constant symbol = "LINK";

  function LinkToken()
    public
  {
    balances[msg.sender] = totalSupply;
  }

  /**
  * @dev transfer token to a specified address with additional data if the recipient is a contract.
  * @param _to The address to transfer to.
  * @param _value The amount to be transferred.
  * @param _data The extra data to be passed to the receiving contract.
  */
  function transferAndCall(address _to, uint _value, bytes _data)
    public
    validRecipient(_to)
    returns (bool success)
  {
    return super.transferAndCall(_to, _value, _data);
  }

  /**
  * @dev transfer token to a specified address.
  * @param _to The address to transfer to.
  * @param _value The amount to be transferred.
  */
  function transfer(address _to, uint _value)
    public
    validRecipient(_to)
    returns (bool success)
  {
    return super.transfer(_to, _value);
  }

  /**
   * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
   * @param _spender The address which will spend the funds.
   * @param _value The amount of tokens to be spent.
   */
  function approve(address _spender, uint256 _value)
    public
    validRecipient(_spender)
    returns (bool)
  {
    return super.approve(_spender,  _value);
  }

  /**
   * @dev Transfer tokens from one address to another
   * @param _from address The address which you want to send tokens from
   * @param _to address The address which you want to transfer to
   * @param _value uint256 the amount of tokens to be transferred
   */
  function transferFrom(address _from, address _to, uint256 _value)
    public
    validRecipient(_to)
    returns (bool)
  {
    return super.transferFrom(_from, _to, _value);
  }


  // MODIFIERS

  modifier validRecipient(address _recipient) {
    require(_recipient != address(0) && _recipient != address(this));
    _;
  }

}
Run Code Online (Sandbox Code Playgroud)

操作符.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
import "@chainlink/contracts/src/v0.7/Operator.sol";
Run Code Online (Sandbox Code Playgroud)

job GET>uint256 (我已经用我的operator合约地址更改了“YOUR_ORACLE_CONTRACT_ADDRESS”)

type = "directrequest"
schemaVersion = 1
name = "Get > Uint256 - (TOML)"
maxTaskDuration = "0s"
contractAddress = "YOUR_ORACLE_CONTRACT_ADDRESS"
minIncomingConfirmations = 0
observationSource = """
    decode_log   [type="ethabidecodelog"
                  abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)"
                  data="$(jobRun.logData)"
                  topics="$(jobRun.logTopics)"]

    decode_cbor  [type="cborparse" data="$(decode_log.data)"]
    fetch        [type="http" method=GET url="$(decode_cbor.get)" allowUnrestrictedNetworkAccess="true"]
    parse        [type="jsonparse" path="$(decode_cbor.path)" data="$(fetch)"]

    multiply     [type="multiply" input="$(parse)" times="$(decode_cbor.times)"]

    encode_data  [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"]
    encode_tx    [type="ethabiencode"
                  abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)"
                  data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\":   $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}"
                  ]
    submit_tx    [type="ethtx" to="YOUR_ORACLE_CONTRACT_ADDRESS" data="$(encode_tx)"]

    decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx
"""
Run Code Online (Sandbox Code Playgroud)

LinkToken合约用于将 LINK 代币转移到其他地址,Operator合约用于与我的 Chainlink 节点交互。按照Chainlink的文档,我将部署ATestnetConsumer合约然后请求API数据。

但是,我在 Remix 中遇到这样的错误:

Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending? Returned error: {"jsonrpc":"2.0","error":"invalid opcode: PUSH0", "id":2405507186007008}
Run Code Online (Sandbox Code Playgroud)

Remix 中的 PUSH0 错误 我的 geth 控制台也出现此错误:Geth 中的 PUSH0 错误

我尝试重置我的 geth 节点和 Chainlink 节点并重做所有相同的步骤。然而,它们没有意义。

小智 12

对于 Solc version 0.8.20,默认 EVM 版本设置为“上海”。PUSHO在上海升级中,以太坊虚拟机添加了一个新的操作码。这意味着PUSH0操作码现在可以成为合约字节码的一部分。如果您的私有链不支持它,则会出现“无效操作码”错误。

解决方案是手动将 EVM 版本设置为某个以前的版本,例如“Paris”(之前的版本,也称为 The Merge),而不是现在默认的“上海”。

混音:

  • 转到编译选项卡
  • 切换“高级配置”下拉菜单
  • 切换“EVM VERSION”下拉菜单并选择“paris”而不是“default”

索尔克:

  • 跑步solc --evm-version <VERSION> <CONTRACT>
  • 例如solc --evm-version paris contract.sol

安全帽:

  • 像这样调整安全帽配置文件
// hardhat.config.ts
solidity: {
    compilers: [
        {
            version: '0.8.20',
            settings: {
                evmVersion: 'paris'
            }
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

铸造厂:

  • foundry.toml像这样调整文件
evm_version = 'paris'
Run Code Online (Sandbox Code Playgroud)