Solidity合约报CompilerError: Stack Too Deep错误如何修复
Solidity「Stack too deep」错误修复方案
- 优先无侵入修复:开启编译器栈优化
使用Solidity 0.8.13及以上版本时,开启viaIR编译管道即可让编译器自动优化栈分配逻辑,绝大多数场景下无需修改业务代码就能解决问题。Hardhat配置参考如下:
module.exports = { solidity: { version: "0.8.19", settings: { viaIR: true, optimizer: { enabled: true, runs: 200 } } } }
- 方案1:使用结构体封装返回值
将8个返回值打包为内存结构体,结构体仅占用1个栈槽存储内存指针,可大幅降低栈压力。修改代码示例:
// 合约层面定义返回值结构体 struct ValueSet { uint256 rAmount; uint256 rTransferAmount; uint256 rFee; uint256 tTransferAmount; uint256 tFee; uint256 tLiquidity; uint256 tMarketing; uint256 tBurn; } function _getValues(uint256 tAmount) private view returns (ValueSet memory values) { (uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity, uint256 tMarketing, uint256 tBurn) = _getTValues(tAmount); (values.rAmount, values.rTransferAmount, values.rFee) = _getRValues(tAmount, tFee, tLiquidity, tMarketing, tBurn, _getRate()); values.tTransferAmount = tTransferAmount; values.tFee = tFee; values.tLiquidity = tLiquidity; values.tMarketing = tMarketing; values.tBurn = tBurn; }
调用方直接接收ValueSet结构体变量即可读取所有返回值,无需调整原有业务逻辑。
- 方案2:拆分单函数为多个子函数
如果不想引入结构体,可将原本返回8个值的函数拆分为两个独立函数,分别返回r系列和t系列值,单个函数的栈占用直接减半:
// 单独查询r系列值 function _getRValuesSet(uint256 tAmount) private view returns (uint256, uint256, uint256) { (, uint256 tFee, uint256 tLiquidity, uint256 tMarketing, uint256 tBurn) = _getTValues(tAmount); return _getRValues(tAmount, tFee, tLiquidity, tMarketing, tBurn, _getRate()); } // 单独查询t系列值 function _getTValuesSet(uint256 tAmount) private view returns (uint256, uint256, uint256, uint256, uint256) { return _getTValues(tAmount); }
调用方按需分别调用两个函数获取对应值即可。
内容的提问来源于stack exchange,提问作者Dimitri
相关产品推荐
相关产品推荐

