英文:
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,
"This function is restricted to the contract's owner"
);
_;
}
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
}
My truffle config.js file
const path = require("path");
module.exports = {
// See <http://truffleframework.com/docs/advanced/configuration>
// to customize your Truffle configuration!
contracts_build_directory: path.join(__dirname, "/build"),
networks: {
development: {
host: "127.0.0.1",
port: 8545,
network_id: "*" //Match any network id
}
},
plugins: ["truffle-contract-size"],
compilers: {
solc: {
version: "^0.8.0"
}
},
solidity: {
version: "0.8.3",
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配置指示您连接到
- 在您的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已被告知不输出它。
- 在您的Truffle配置文件中更新
参考链接:
汇编器:从“上海”开始的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
solcversion in your solidity files:pragma solidity 0.8.19;
- Since your truffle config indicates that you are connecting to
- Change the
solcversion in your truffle config file:version: "0.8.19"- If the underlying cause of your error was indeed the
PUSH0opcode, this will solve your problem assolcversion 0.8.19 does not output this.
- If the underlying cause of your error was indeed the
- Continue using the latest
solcversion, but specify a non-latest target EVM version- Update the
solcsection in your truffle config file to add a new property:settings: { evmVersion: 'london' } - Note that 0.8.20 targets
evmVersion: 'shanghai'by default, which means it can outputPUSH0 - But if you override it to target
evmVersion: 'london'instead, which is the 2nd most recent target EVM version (as of June 2023), you're essentially tellingsolcto avoid outputtingPUSH0. - If the underlying cause of your error was indeed the
PUSH0opcode, this will solve your problem assolchas been told not output this.
- Update the
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 <VERSION> contract.sol
> evmVersion: <string> // Default: "istanbul"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论