如何修复 Solidity 中的“部署时迁移遇到无效操作码”错误?

kar*_*mte 2 javascript blockchain ethereum solidity

“迁移”在部署时遇到无效的操作码。尝试:

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

我的migration.sol代码

    // 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,
          "This function is restricted to the contract's owner"
        );
        _;
      }

      function setCompleted(uint completed) public restricted {
        last_completed_migration = completed;
      }
    }
Run Code Online (Sandbox Code Playgroud)

我的松露 config.js 文件

    // 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,
          "This function is restricted to the contract's owner"
        );
        _;
      }

      function setCompleted(uint completed) public restricted {
        last_completed_migration = completed;
      }
    }
Run Code Online (Sandbox Code Playgroud)

bgu*_*uiz 6

这可能是由于最近PUSH0在 0.8.20 版本中引入了新的操作码solc

有关完整列表,请参阅“每个操作码何时添加到 EVM?”

本质上,您的 Solidity 编译器版本“领先于”您尝试部署到的网络。换句话说,solc输出包含操作码的字节码,但网络尚未包含。

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

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

参考:

汇编器:用于push0放置0从“上海”开始的 EVM 版本的堆栈。这降低了部署和运行时成本。

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

evmVersion: <string> // Default: "istanbul"