0

I am writing an implementation of ERC777TokensRecipient. So that means a function

function tokensReceived(address operator, address from, address to, uint256 amount, bytes data, bytes operatorData) external;

The data field contains 14 uint256 variables

0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e

How would I be able to access these variables?

I know I can get them like this:

function tokensReceived(address _operator, address _from, address _to, uint256 _amount, bytes _data, bytes _operatorData) external {
    uint arg1;
    uint arg2;
    uint arg3;
    uint arg4;
    uint arg5;
    uint arg6;
    uint arg7;
    uint arg8;
    uint arg9;
    uint arg10;
    uint arg11;
    uint arg12;
    uint arg13;
    uint arg14;

    bytes memory tmp = _data;
    assembly {
        arg1  := mload(add(0x020, tmp))
        arg2  := mload(add(0x040, tmp))
        arg3  := mload(add(0x060, tmp))
        arg4  := mload(add(0x080, tmp))
        arg5  := mload(add(0x0A0, tmp))
        arg6  := mload(add(0x0C0, tmp))
        arg7  := mload(add(0x0E0, tmp))
        arg8  := mload(add(0x100, tmp))
        arg9  := mload(add(0x120, tmp))
        arg10 := mload(add(0x140, tmp))
        arg11 := mload(add(0x160, tmp))
        arg12 := mload(add(0x180, tmp))
        arg13 := mload(add(0x1A0, tmp))
        arg14 := mload(add(0x1C0, tmp))
    }
}

But I can only get 7 of the 14 variables before I run into a

CompilerError: Stack too deep, try removing local variables.

According to Error while compiling: Stack too deep, the workaround is to put the local uints into an array. But I do not know how to do that.

Does anyone know how I could write a function like this:

function convertToArrayOfLength14(bytes memory data) internal pure returns (uint[]) {
    // TODO
}
  • Please accept my answer if it's satisfactory – Jesse Busman Dec 12 '18 at 20:17
2

You could do it in a loop like this:

function convertToArrayOfLength14(bytes memory data) public pure returns (uint256[] memory output)
{
    output = new uint256[](14);
    for (uint256 i=32; i<=output.length*32; i+=32)
    {
        assembly { mstore(add(output, i), mload(add(data, i))) }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.