0

I have a bytes32 object in memory or storage and I want to parse it into little chunks, for example into one uint8, followed by a bool, followed by uint10, followed by address. How can one do that? I have tried two options:

// option 1
function parseBytes32_op1(bytes32 _data) pure public returns (byte fist, byte second, bytes10 third, bytes20 fourth) {
    assembly {
        let freemem_pointer := mload(0x40)
        mstore(add(freemem_pointer,0x00), _data)
        _first := mload(add(freemem_pointer,0x00))
        _second := mload(add(freemem_pointer,0x01))
        _third := mload(add(freemem_pointer,0x02))
        _fourth := mload(add(freemem_pointer,0x0b))
      }
   // and then convert somehow into the respective types

}

// option2 function parseBytes32_op2(bytes32 _data) pure public returns (byte fist, byte second, bytes10 third, bytes20 fourth) {

    first = uint8(bytes1(_data));
    second = bool(uint8(bytes1(_data << 8)));
    third = uint10(bytes9(_data << 8 * 2));
    fourth = address(bytes9(_data << 8 * 12));

}

However, in the first option I am feeling uncomfortable about the memory stack. I fear that I might use the wrong pointer if there is something atop the stack that is not the data.

In the second option I am feeling uncomfortable with the shift operation. Where do those bytes shift? In fact when I ran some similar code on remix I got a compiler error saying:

CompilerError: Stack too deep, try removing local variables.

What is the best option?

Marlo
  • 329
  • 4
  • 14

1 Answers1

1

It could be implemented without memory access, just with shifts

function parseBytes32_op1(bytes32 _data) pure public returns (bytes1 first, bytes1 second, bytes10 third, bytes20 fourth) {
    assembly {
        first := _data
        second := shl(8, _data)
        third := shl(add(8, 8), _data)
        fourth := shl(add(16, 80), _data)
    }
}

It could be implemented in solidity and it will be almost identical to your solution

function parseBytes32_op2(bytes32 _data) pure public returns (bytes1 fist, bytes2 second, bytes10 third, bytes20 fourth) {
first = bytes1(_data);
second = bytes1(_data << 8);
third = bytes10(_data << 8 * 2);
fourth = bytes20(_data << 8 * 12);

}

The EVM is stack based so simple operations like shift are implemented using the machine stack.


The error message

CompilerError: Stack too deep, try removing local variables.

means you are using too many local variables + return values + input parameters + temporary operations.

Try simplifying the function, dividing in two parts, use {} to limit variables scope. For other recommendations see this Error while compiling: Stack too deep.

Ismael
  • 30,570
  • 21
  • 53
  • 96