部署至Ganache时出现Opcode错误如何解决?
已完成Ganache运行配置,但执行命令 truffle migrate --network development --reset 时持续报错,以下是相关日志与代码:
Ganache运行日志
[8:17:47 AM] (node:19312) MaxListenersExceededWarning: 检测到可能的EventEmitter内存泄漏。已向[Server]添加11个close监听器。使用emitter.setMaxListeners()增加限制
[8:17:47 AM] 使用初始配置启动服务器:{"gasLimit":6721975,"gasPrice":20000000000,"hardfork":"merge","hostname":"127.0.0.1","port":8545,"network_id":5777,"default_balance_ether":1000000000000000,"total_accounts":10,"unlocked_accounts":[],"locked":false,"vmErrorsOnRPCResponse":true,"verbose":true,"flavor":"ethereum","db_path":"C:\Users**\AppData\Roaming\Ganache\ui\workspaces\wide-leaf\chaindata","mnemonic":"","logDirectory":"C:\Users*\Logs"}
[8:17:47 AM] Ganache启动成功! [8:17:47 AM] 等待请求...
[8:17:47 AM] (node:19312) MaxListenersExceededWarning: 检测到可能的EventEmitter内存泄漏。已向[Server]添加11个close监听器。使用emitter.setMaxListeners()增加限制
Truffle报错信息
编译合约中...编译 .\contracts\IERC20.solsolc-bin. 尝试第1次
编译 .\contracts\Migrations.sol
编译 .\contracts\TestToken.sol
编译 .\contracts\SafeMath.sol
编译产物已写入 C:\Users*\TestToken\build\contracts
编译成功,使用版本:
- solc: 0.8.20+commit.a1b79de6.Emscripten.clang
⠇ 从solc-bin获取solc版本列表。尝试第1次
网络名称: 'development'
网络ID: 5777
区块gas限制: 6721975 (0x6691b7)
⠏ 从solc-bin获取solc版本列表。尝试第1次
部署 'TestToken'
*** 部署失败 ***st from solc-bin. 尝试第1次
"TestToken" 部署时触发无效操作码。请尝试:
- 验证构造函数参数是否满足所有assert条件。
- 验证构造函数代码是否存在数组越界访问。
- 为assert语句添加原因描述。
退出:请通过在Etherscan上检查上述交易哈希手动查看成功的交易。
错误: *** 部署失败 ***
"TestToken" 部署时触发无效操作码。请尝试:
- 验证构造函数参数是否满足所有assert条件。
- 验证构造函数代码是否存在数组越界访问。
- 为assert语句添加原因描述。
at C:\Users\*\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\deployer\src\deployment.js:330:1
Truffle v5.9.0 (核心: 5.9.0)
Node v18.16.0
合约构造函数代码
uint128 private constant _initialSupply = 1_000_000_000_000_000 ether; uint128 private constant _yearlySupplyIncrease = 10_000_000_000 ether; uint128 private constant _reflectionFeePercentage = 1; uint128 private constant _burnFeePercentage = 2; constructor() { _totalSupply = _initialSupply; _balances[msg.sender] = _initialSupply; emit Transfer(address(0), msg.sender, _initialSupply); require(_totalSupply >= 0, "Error: Invalid total supply"); require(_balances[msg.sender] == _initialSupply, "Error: Initial supply not assigned correctly"); }
排查与修复建议
- 检查变量类型匹配:确认合约中
_totalSupply和_balances的类型是否与_initialSupply的uint128兼容。如果_totalSupply是更小的无符号整数类型(如uint64),会导致数值溢出触发无效操作码。 - 移除冗余校验:
require(_totalSupply >= 0)完全多余——无符号整数类型本身不可能为负,移除该语句后重新编译部署,排除编译器优化导致的异常。 - 缩小初始供应量测试:临时将
_initialSupply改为1000 ether这类较小值,测试是否能正常部署,排除超大数值引发的隐性问题。 - 对齐网络配置:检查
truffle-config.js中development网络的port、network_id、gasLimit是否与Ganache配置完全一致,确保gas限制不低于Ganache设置的6721975。 - 解决solc下载异常:Truffle反复提示“获取solc版本列表”,可能是网络问题导致solc未正确下载。可手动下载对应版本solc,或在truffle配置中指定本地solc路径。
内容的提问来源于stack exchange,提问作者zendek

