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?

1 Answer 1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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