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?
Best Answer
It could be implemented without memory access, just with shifts
It could be implemented in solidity and it will be almost identical to your solution
The EVM is stack based so simple operations like shift are implemented using the machine stack.
The error message
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.