uint256 value2;
return a.value1+a.value2+b.value1+b.value2+c.value1+c.value2+d.value1+d.value2+e;
pragma solidity 0.7.1;
function addUints(
不外请安心,,这不是你的错。假如你正在为这个错误而苦苦挣扎,那么你不是独一的一个。
pragma solidity 0.7.1;
1.利用内部函数
uint256 a,uint256 b,uint256 c,uint256 d,uint256 e,uint256 f,uint256 g,uint256 h,uint256 i
uint256 result = 0;
// SPDX-License-Identifier: MIT
}
function addUints(
}
4.理会msg.data
}
) external pure returns(uint256) {
然而,你确看到以下错误动静:
contract StackTooDeepTest2 {
}
uint256 value1;
return a+b+c+d+e+f+g+h+i;
可怕的三个词
result = result+f+g+h+i;
}
InternalCompilerError:Stack Too Deep, try removing local variables.(仓库太深,请实验删除一些局部变量。)可是我不想先容太多让你厌倦的理论。这是一篇实用的博客文章。
struct UintPair {
uint256 value2;
value := add(value1, value2)
3. 通过通报布局体
result = a+b+c+d+e;
}
uint256 a,uint256 b,uint256 c,uint256 d,uint256 e,uint256 f,uint256 g,uint256 h,uint256 i
}
{
uint256 a,uint256 b,uint256 c,uint256 d,uint256 e,uint256 f,uint256 g,uint256 h,uint256 i
}
// SPDX-License-Identifier: MIT
}
pragma solidity 0.7.1;
return a+b+c;
}
}
Stack Too Deep 的例子
contract StackTooDeepTest1 {
也许此刻的仓库对你来说足够了。:) 此刻到底有什么通用要领可以办理此问题?让我们看一下处理惩罚错误的五种要领:
1. 利用更少的变量这种要领的最初想法来自用户Stackexchange的k06a[4],这需要点黑能力,所以我凡是不发起这样做。可是假如你实验了所有其他实验都没有乐成?可以实验一下:
这是如何事情的,就是通过理会msg.data。所有发送到合约的数据都存储此变量,因此我们可以注释掉变量a和b,但仍吸收它们的值。msg.data的前4个字节是函数选择器[5]数据。之后是我们的前两个uint256,每个32位。
}
· 操作布局体
) external pure returns(uint256) {
) external pure returns(uint256) {
// SPDX-License-Identifier: MIT
{
pragma experimental ABIEncoderV2;
function _addThreeUints(uint256 a, uint256 b, uint256 c) private pure returns(uint256) {
) external pure returns(uint256) {
· 一些黑能力
}
function addUints(
uint256 value1;
你只需要在合约中添加一个微小的变动即可。你认为这只需要几秒钟。没错,添加代码只花了不到一分钟的时间。你很兴奋你快速办理了这个问题,你输入了compile呼吁。这么小的变动,你确信代码是正确的。
}
是的,利用内部函数将使错误消失。譬喻,我们可以将其分为三个函数挪用,每个函数挪用加起来会包括三个uint。神奇的是,仓库太深的错误会迫使我们编写更好的代码。
看看最近的观测,您最讨厌Solidity[3]哪个方面: UintPair memory a, UintPair memory b, UintPair memory c, UintPair memory d, uint256 e
· 操作函数
return result;
function addUints(
value2 := mload(add(data, 68))
contract StackTooDeepTest3 {
如何办理
对付其他四个,我们来看一个仓库太深的示例代码以及四种修复它的要领。
[受Uniswap开导] (https://github.com/Uniswap/uniswap-v2-periphery/blob/69617118cda519dab608898d62aaa79877a61004/contracts/UniswapV2Router02.sol#L327-L333),你也可以利用块浸染域。只需将大括号括在部门代码中:
assembly {
return _fromUint(msg.data)+c+d+e+f+g+h+i;
contract StackTooDeepTest1 {
function addUints(
// SPDX-License-Identifier: MIT
function _fromUint(bytes memory data) internal pure returns(uint256 value) {
这是只利用较少变量的一种要领。将数据放入布局中。出于可读性原因,也是一个好主意。
}
原因是在EVM仓库中如何引用变量方面存在限制。尽量个中可以包括16个以上的变量,可是一旦实验引用16或更高槽位中的变量,将失败。因此,并非老是很清楚为什么某些代码会失败,然后举办一些随机变动好像可以办理问题。
pragma solidity 0.7.1;
· 代码块浸染域范畴
return _addThreeUints(a,b,c) + _addThreeUints(d,e,f) + _addThreeUints(g,h,i);
// SPDX-License-Identifier: MIT
2.操作块浸染域
利用 msg.data 的要领仅合用于外部函数。一种变通要领是将其与民众函数一起利用, 要领是通过this.myPublicFunction()挪用那些民众函数。
) external pure returns(uint256) {
uint256 /*a*/,uint256 /*b*/,uint256 c,uint256 d,uint256 e,uint256 f,uint256 g,uint256 h,uint256 i
哎哟。这里产生了什么?假如你之前写过智能合约,这很大概是一个很是熟悉的错误动静,而且在不行预测的时间呈现。可是凡是在你时间紧要的时候。
pragma solidity 0.7.1;让我们看下面的代码。它将抛出困扰我们的仓库太深的错误动静。我们可以对它可以做些什么呢?
contract StackTooDeepTest4 {
为什么会呈现此错误?
value1 := mload(add(data, 36))好吧,第一个显而易见。假如可以,请实验重构代码以利用更少的变量。步伐很直接,让我们继承前进看看其他 4 个要领。
}
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。