Convertir bytes a uint256[]

Estoy escribiendo una implementación de ERC777TokensRecipient. Entonces eso significa una función

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

El datacampo contiene 14 uint256variables.

0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e

¿Cómo podría acceder a estas variables?

Sé que puedo conseguirlos así:

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))
    }
}

Pero solo puedo obtener 7 de las 14 variables antes de encontrarme con un

CompilerError: Stack too deep, try removing local variables.

De acuerdo con Error al compilar: pila demasiado profunda , la solución consiste en colocar los uintcorreos electrónicos locales en una matriz. Pero no sé cómo hacer eso.

¿Alguien sabe cómo podría escribir una función como esta:

function convertToArrayOfLength14(bytes memory data) internal pure returns (uint[]) {
    // TODO
}

Respuestas (1)

Podrías hacerlo en un bucle como este:

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))) }
    }
}