What are limitations of Event arguments?
Asked Answered
L

2

5

Are there any limitation on the amount of arguments that can be send in an event?

I have a function in which I want to trigger event that has 12 arguments of which 6 arguments are arrays. I get Stack too deep, try using less variables. Without the event the function works normally.

I am guessing event arguments have some limitations or count towards max arguments in a solidity function but I cannot find any documentation around it.

Can anyone clarify this?

Edit:

The contract looks something like this: I'm using safe math and the _getAddressSubArrayTo is an internal pure function that gets a sub array from index to index.

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
);
}
Lactose answered 21/3, 2018 at 14:37 Comment(0)
L
5

I was able to find an answer:

If you look at the ContractCompiler.cpp where FunctionDefinition is declared, you see there is a limit of 17 elements on the stack ;

if (stackLayout.size() > 17)           
  BOOST_THROW_EXCEPTION(   
        CompilerError() <<     
    errinfo_sourceLocation(_function.location()) <<     
    errinfo_comment("Stack too deep, try removing local variables.")     
);      

Events are defined as functions, as can be seen in ExpressionCompiler.cpp.

Simply put Events are treated as functions so they have a limit of 17 arguments. Array counts as 2 so in my example where I have 6 arrays + 6 normal arguments this equals 18 and I'm breaking the stack by 1.

Lactose answered 22/3, 2018 at 15:48 Comment(0)
T
5

Yes, there are limits. You can have up to three indexed arguments in your event. Non-indexed arguments are less restrictive as it’s not limited by the event data structure itself, but is limited by the block gas size for storage (at a cost of 8 gas per byte of data stored in the log).

Solidity event documentation

Tackle answered 21/3, 2018 at 14:54 Comment(3)
I know about the indexed arguments but I'm getting Stack too deep even when I comment out all the major processing in the function. I added a code sample above of my problematic event.Lactose
That has nothing to do with events. There is a limit to the number of local variables you can have in a function (see github.com/ethereum/solidity/issues/2693). If you remove the Temp structure from you function and just send the same data to your event directly, you won't hit that error.Tackle
I don't think that is the problem. Because I otherwise have about 80 lines of code that operates with structured data and calls other functions and everything works fine if I comment out the event... But if I only leave the event and the structure it still fails..Lactose
L
5

I was able to find an answer:

If you look at the ContractCompiler.cpp where FunctionDefinition is declared, you see there is a limit of 17 elements on the stack ;

if (stackLayout.size() > 17)           
  BOOST_THROW_EXCEPTION(   
        CompilerError() <<     
    errinfo_sourceLocation(_function.location()) <<     
    errinfo_comment("Stack too deep, try removing local variables.")     
);      

Events are defined as functions, as can be seen in ExpressionCompiler.cpp.

Simply put Events are treated as functions so they have a limit of 17 arguments. Array counts as 2 so in my example where I have 6 arrays + 6 normal arguments this equals 18 and I'm breaking the stack by 1.

Lactose answered 22/3, 2018 at 15:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.