事件参数的局限性是什么?
What are limitations of Event arguments?
事件中可以发送的参数数量是否有任何限制?
我有一个函数,我想在其中触发具有 12 个参数的事件,其中 6 个参数是数组。我的 Stack 太深了,尝试使用更少的变量。没有事件功能正常工作。
我猜测事件参数有一些限制或计入 solidity 函数中的最大参数,但我找不到任何相关文档。
谁能澄清一下?
编辑:
合同看起来像这样:
我正在使用安全数学,_getAddressSubArrayTo 是一个内部纯函数,它从一个索引到另一个索引获取一个子数组。
event LogTemp(address a,
address b,
address[] c,
uint256[] d,
address[] e,
uint256[] f,
address[] g,
uint256[] h,
uint256 i,
uint256 j,
uint256 k,
bytes32 l);
function test(address[] _addresses,
uint256[] _uints,
uint8 _v,
bytes32 _r,
bytes32 _s,
bool test)
public
returns (bool)
{
Temp memory temp = Temp({
a: _addresses[0],
b: _addresses[1],
c: _getAddressSubArrayTo(_addresses, 2, _uints[3].add(2)),
d: _getUintSubArrayTo(_uints, 5, _uints[3].add(5)),
e: _getAddressSubArrayTo(_addresses, _uints[3].add(2), (_uints[3].add(2)).add(_uints[4])),
f: _getUintSubArrayTo(_uints, _uints[3].add(5), (_uints[3].add(5)).add(_uints[4])),
g: _getAddressSubArrayTo(_addresses, (_uints[3].add(2)).add(_uints[4]), _addresses.length),
h: _getUintSubArrayTo(_uints,(_uints[3].add(5)).add(_uints[4]), _uints.length),
i: _uints[0],
j: _uints[1],
k: _uints[2],
l: hash(
_addresses,
_uints
)
});
LogTemp(
temp.a,
temp.b,
temp.c,
temp.d,
temp.e,
temp.f,
temp.g,
temp.h,
temp.i,
temp.j,
temp.k,
temp.l
);
}
是的,有限制。您的事件中最多可以有三个索引参数。 Non-indexed arguments 的限制较少,因为它不受事件数据结构本身的限制,但受存储的块 gas 大小限制(日志中存储的每字节数据的成本为 8 gas)。
我找到了答案:
如果您查看 ContractCompiler.cpp 声明 FunctionDefinition 的地方,您会发现堆栈上有 17 个元素的限制;
if (stackLayout.size() > 17)
BOOST_THROW_EXCEPTION(
CompilerError() <<
errinfo_sourceLocation(_function.location()) <<
errinfo_comment("Stack too deep, try removing local variables.")
);
事件被定义为函数,在ExpressionCompiler.cpp.
中可以看出
简单地说,事件被视为函数,因此它们有 17 个参数的限制。数组算作 2,所以在我的示例中,我有 6 个数组 + 6 个普通参数,这等于 18,我将堆栈减 1。
事件中可以发送的参数数量是否有任何限制?
我有一个函数,我想在其中触发具有 12 个参数的事件,其中 6 个参数是数组。我的 Stack 太深了,尝试使用更少的变量。没有事件功能正常工作。
我猜测事件参数有一些限制或计入 solidity 函数中的最大参数,但我找不到任何相关文档。
谁能澄清一下?
编辑:
合同看起来像这样: 我正在使用安全数学,_getAddressSubArrayTo 是一个内部纯函数,它从一个索引到另一个索引获取一个子数组。
event LogTemp(address a,
address b,
address[] c,
uint256[] d,
address[] e,
uint256[] f,
address[] g,
uint256[] h,
uint256 i,
uint256 j,
uint256 k,
bytes32 l);
function test(address[] _addresses,
uint256[] _uints,
uint8 _v,
bytes32 _r,
bytes32 _s,
bool test)
public
returns (bool)
{
Temp memory temp = Temp({
a: _addresses[0],
b: _addresses[1],
c: _getAddressSubArrayTo(_addresses, 2, _uints[3].add(2)),
d: _getUintSubArrayTo(_uints, 5, _uints[3].add(5)),
e: _getAddressSubArrayTo(_addresses, _uints[3].add(2), (_uints[3].add(2)).add(_uints[4])),
f: _getUintSubArrayTo(_uints, _uints[3].add(5), (_uints[3].add(5)).add(_uints[4])),
g: _getAddressSubArrayTo(_addresses, (_uints[3].add(2)).add(_uints[4]), _addresses.length),
h: _getUintSubArrayTo(_uints,(_uints[3].add(5)).add(_uints[4]), _uints.length),
i: _uints[0],
j: _uints[1],
k: _uints[2],
l: hash(
_addresses,
_uints
)
});
LogTemp(
temp.a,
temp.b,
temp.c,
temp.d,
temp.e,
temp.f,
temp.g,
temp.h,
temp.i,
temp.j,
temp.k,
temp.l
);
}
是的,有限制。您的事件中最多可以有三个索引参数。 Non-indexed arguments 的限制较少,因为它不受事件数据结构本身的限制,但受存储的块 gas 大小限制(日志中存储的每字节数据的成本为 8 gas)。
我找到了答案:
如果您查看 ContractCompiler.cpp 声明 FunctionDefinition 的地方,您会发现堆栈上有 17 个元素的限制;
if (stackLayout.size() > 17)
BOOST_THROW_EXCEPTION(
CompilerError() <<
errinfo_sourceLocation(_function.location()) <<
errinfo_comment("Stack too deep, try removing local variables.")
);
事件被定义为函数,在ExpressionCompiler.cpp.
中可以看出简单地说,事件被视为函数,因此它们有 17 个参数的限制。数组算作 2,所以在我的示例中,我有 6 个数组 + 6 个普通参数,这等于 18,我将堆栈减 1。