Remix: CompilerError: Stack too deep when compiling inline assembly: Variable value0 is 1 slot(s) too deep inside the stack.
问题描述
在 Remix 0.6.12 版本上报错:
CompilerError: Stack too deep when compiling inline assembly:
Variable value0 is 1 slot(s) too deep inside the stack.
在 Remix 0.8.17 版本上报错
CompilerError: Stack too deep.
Try compiling with `--via-ir` (cli) or the equivalent `viaIR: true` (standard JSON) while enabling the optimizer.
Otherwise, try removing local variables.
When compiling inline assembly: Variable value0 is 1 slot(s) too deep inside the stack. Stack too deep.
Try compiling with `--via-ir` (cli) or the equivalent `viaIR: true` (standard JSON) while enabling the optimizer.
Otherwise, try removing local variables.
测试的合约代码
// SPDX-License-Identifier: GPL-3.0
// pragma solidity 0.6.12;
pragma solidity 0.8.17;
pragma experimental ABIEncoderV2;
contract Demo {
struct UserInfo {
// 账单属性
bool isLocked; // 是否为锁定账单
uint256 billType; // 账单类型的ID(Actived Bill 的type永远为 0)
// 核心
uint256 amount; // 用户在池子内的最新余额
uint256 flyRewardDebt; // 用户已经收到的 FLY 奖励数量
uint256 fiboRewardDebt; // 用户已经收到的 FIBO 奖励数量
uint256 lockStartTime; // Locked Bill: 开始时间戳
uint256 lockEndTime; // Locked Bill: 结束时间戳
// 用户历史账单相关的信息:供前端显示
uint256 historyBillId; // 当前的账单ID
uint256 timestamp; // block.timestamp
bool isDeposit; // 是否为取款
address lpToken; // LP Token 地址
uint256 pId; // LP Token Pool Id
uint256 singleAmount; // 最新一次操作金额
}
mapping(address => UserInfo[]) public userHistoryBill;
}
问题的原因
数据结构 mapping(address => UserInfo[]) public userHistoryBill;
,此时只需要把 UserInfo
内的数量,减少到不超过 12 个就可以。
上面 UserInfo 内有 13 个元素。我们去掉一个,比如把 bool isLocked; // 是否为锁定账单
注释掉。此时就不会报错了。
正确的代码演示
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.6.12;
// pragma solidity 0.8.17;
pragma experimental ABIEncoderV2;
contract Demo {
struct UserInfo {
// 账单属性
// bool isLocked; // 是否为锁定账单 ✅ struct 内不超过12个元素即可
uint256 billType; // 账单类型的ID(Actived Bill 的type永远为 0)
// 核心
uint256 amount; // 用户在池子内的最新余额
uint256 flyRewardDebt; // 用户已经收到的 FLY 奖励数量
uint256 fiboRewardDebt; // 用户已经收到的 FIBO 奖励数量
uint256 lockStartTime; // Locked Bill: 开始时间戳
uint256 lockEndTime; // Locked Bill: 结束时间戳
// 用户历史账单相关的信息:供前端显示
uint256 historyBillId; // 当前的账单ID
uint256 timestamp; // block.timestamp
bool isDeposit; // 是否为取款
address lpToken; // LP Token 地址
uint256 pId; // LP Token Pool Id
uint256 singleAmount; // 最新一次操作金额
}
mapping(address => UserInfo[]) public userHistoryBill;
}
问题备注
⚠️ 注意:这是 Remix 的问题,如果我们使用类似 Hardhat 脚手架,编译和部署的时候不会收到此警告。