英文:
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
solc
version in your solidity files:pragma solidity 0.8.19;
- Since your truffle config indicates that you are connecting to
- Change the
solc
version in your truffle config file:version: "0.8.19"
- If the underlying cause of your error was indeed the
PUSH0
opcode, this will solve your problem assolc
version 0.8.19 does not output this.
- If the underlying cause of your error was indeed the
- 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: '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 tellingsolc
to avoid outputtingPUSH0
. - If the underlying cause of your error was indeed the
PUSH0
opcode, this will solve your problem assolc
has 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"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论