如何修复 Solidity 中的 ‘Migrations hit an invalid opcode while deploying’ 错误?

huangapple go评论82阅读模式
英文:

How do I fix 'Migrations hit an invalid opcode while deploying' error in Solidity?

问题

"Migrations" 在部署时触发了无效的操作码。尝试:

  • 验证您的构造函数参数是否满足所有断言条件。
  • 验证您的构造函数代码是否访问了数组越界。
  • 在您的断言语句中添加原因字符串。 如何解决此错误

我的 migration.sol 代码

    // SPDX-License-Identifier: UNLICENSED

    // 兼容的 Solidity 版本

    pragma solidity ^0.8.0;
    contract Migrations {
      address public owner = msg.sender;
      uint public last_completed_migration;

      modifier restricted() {
        require(
          msg.sender == owner,
          "此函数受限于合同所有者"
        );
        _;
      }

      function setCompleted(uint completed) public restricted {
        last_completed_migration = completed;
      }
    }

我的 truffle config.js 文件

    const path = require("path");

    module.exports = {
      // 有关自定义 Truffle 配置的详细信息,请参见:<http://truffleframework.com/docs/advanced/configuration>
      contracts_build_directory: path.join(__dirname, "/build"),
   
      networks: {
        development: {
          host: "127.0.0.1",
          port: 8545,
          network_id: "*" // 匹配任何网络 id
        }
      },
    
      plugins: ["truffle-contract-size"],
      compilers: {
        solc: {
          version: "^0.8.0"
        }
      },
      solidity: {
        version: "0.8.3",
        settings: {
          optimizer: {
            enabled: true,
            runs: 1000,
          },
        },
      },
    };
英文:

"Migrations" hit an invalid opcode while deploying. Try:

  • Verifying that your constructor params satisfy all assert conditions.
  • Verifying your constructor code doesn't access an array out of bounds.
  • Adding reason strings to your assert statements. getting this error how to solve

My migration.sol code

    // SPDX-License-Identifier: UNLICENSED

    //the version of solidity that is compatible

    pragma solidity ^0.8.0;
    contract Migrations {
      address public owner = msg.sender;
      uint public last_completed_migration;

      modifier restricted() {
        require(
          msg.sender == owner,
          &quot;This function is restricted to the contract&#39;s owner&quot;
        );
        _;
      }

      function setCompleted(uint completed) public restricted {
        last_completed_migration = completed;
      }
    }

My truffle config.js file

    const path = require(&quot;path&quot;);

    module.exports = {
      // See &lt;http://truffleframework.com/docs/advanced/configuration&gt;
      // to customize your Truffle configuration!
      contracts_build_directory: path.join(__dirname, &quot;/build&quot;),
  
   
      networks: {
        development: {
        host: &quot;127.0.0.1&quot;,
      port: 8545,
      network_id: &quot;*&quot; //Match any network id
     }
    },
    
    plugins: [&quot;truffle-contract-size&quot;],
    compilers: {
    solc: {
      version: &quot;^0.8.0&quot;
    }
    },
    solidity: {
    version: &quot;0.8.3&quot;,
    settings: {
      optimizer: {
        enabled: true,
        runs: 1000,
      },
    },
  },
   };

答案1

得分: 4

这很可能是由于最近引入了一个新的操作码PUSH0,从solc版本0.8.20开始。

有关完整列表,请参见"每个操作码是什么时候添加到EVM的?"

实质上,您的Solidity编译器版本超前于您尝试部署到的网络。换句话说,solc输出的字节码包含一个操作码,但网络还没有支持这个操作码。

您有3个潜在的解决方案:

  • 等待您的目标网络支持新的操作码,或者使用不同的网络。
    • 由于您的Truffle配置指示您连接到127.0.0.1:8545,这意味着您可以升级到本地运行的最新版本的网络(例如Ganache),也许这将解决问题。
    • 降级到solc的早期版本。
    • 在您的Solidity文件中更改solc版本:pragma solidity 0.8.19;
  • 在您的Truffle配置文件中更改solc版本:version: "0.8.19"
    • 如果您的错误的根本原因确实是PUSH0操作码,这将解决您的问题,因为solc版本0.8.19不会输出这个操作码。
  • 继续使用最新的solc版本,但指定一个不是最新的目标EVM版本。
    • 在您的Truffle配置文件中更新solc部分以添加一个新属性:settings: { evmVersion: 'london' }
    • 请注意,0.8.20版本默认目标evmVersion: 'shanghai',这意味着它可以输出PUSH0操作码。
    • 但如果您覆盖它以目标evmVersion: 'london',这是截止到2023年6月的第二新的目标EVM版本,您实际上是在告诉solc不要输出PUSH0
    • 如果您的错误的根本原因确实是PUSH0操作码,这将解决您的问题,因为solc已被告知不输出它。

参考链接:

汇编器:从“上海”开始的EVM版本使用push0来将0放入堆栈,从而降低部署和运行成本。

solc --evm-version <VERSION> contract.sol

evmVersion: <string> // 默认值:"istanbul"

英文:

This is likely due to the recent introduction of a new opcode, PUSH0, as of solc version 0.8.20.

For a full list, see "When did each opcode get added to the EVM?".

Essentially, your version of the solidity compiler is "ahead" of the network that you are attempting to deploy to. In other words, solc outputs bytecode that contains an opcode, but the network does not yet.

You have 3 potential solutions:

  • Wait for your target network to support the new opcode, or use a different network.
    • Since your truffle config indicates that you are connecting to 127.0.0.1:8545, this means that you can upgrade to the latest version of your network running locally (e.g. Ganache) and perhaps that will solve the problem
    • Downgrade to an earlier version of solc.
    • Change the solc version in your solidity files: pragma solidity 0.8.19;
  • Change the solc version in your truffle config file: version: &quot;0.8.19&quot;
    • If the underlying cause of your error was indeed the PUSH0 opcode, this will solve your problem as solc version 0.8.19 does not output this.
  • Continue using the latest solc version, but specify a non-latest target EVM version
    • Update the solc section in your truffle config file to add a new property: settings: { evmVersion: &#39;london&#39; }
    • Note that 0.8.20 targets evmVersion: &#39;shanghai&#39; by default, which means it can output PUSH0
    • But if you override it to target evmVersion: &#39;london&#39; instead, which is the 2nd most recent target EVM version (as of June 2023), you're essentially telling solc to avoid outputting PUSH0.
    • If the underlying cause of your error was indeed the PUSH0 opcode, this will solve your problem as solc has been told not output this.

References:

> Assembler: Use push0 for placing 0 on the stack for EVM versions starting from "Shanghai". This decreases the deployment and runtime costs.

> solc --evm-version &lt;VERSION&gt; contract.sol

> evmVersion: &lt;string&gt; // Default: &quot;istanbul&quot;

huangapple
  • 本文由 发表于 2023年6月1日 22:25:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76382953.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定