4

I know how to convert bytes to uint8[8] using mload but mstore seemed like it could be more gas efficient.

Is something like this possible?

function bytesToUintArray(bytes input) returns (uint8[8])) { 
    uint8[8] result;
    assembly {
        mstore(result, add(input, 32))
    }
    return result;
}
  • Do you want to copy the first 8 bytes from input to the uint8[8] array? – Ismael Mar 8 '18 at 4:41
0

This seems to work, but arrays in memory are not tightly packed so you need multiple mstore

From https://solidity.readthedocs.io/en/v0.4.20/assembly.html#conventions-in-solidity

Elements in memory arrays in Solidity always occupy multiples of 32 bytes (yes, this is even true for byte[], but not for bytes and string).

function foo(bytes input) internal pure returns (uint8[8]) {
    uint8[8] memory result;
    assembly {
        let w := mload(add(input, 0x20))
        for { let i:= 0 } lt(i, 8) { i := add(i, 1) } {
            mstore(add(result, mul(i, 0x20)), byte(i, w))
        }
    }
    return result;
}

And the gas consumption is just slightly better than the obvious solution

function foo2(bytes input) internal pure returns (uint8[8]) {
    uint8[8] memory result;
    for (uint i=0; i<8 && i<input.length; ++i) {
        result[i] = uint8(input[i]);
    }
    return result;
}
| improve this answer | |
0

You can find a whole library about the topic:

https://github.com/pouladzade/Seriality

| improve this answer | |
0

You expected this trick to work:

function bytesToUintArray2(bytes memory input) public view returns (uint8[8] memory result) { 
    assembly {
        result := add(input, 32)
    }
}

But this would not work due to bytes is stored packed with length prefix like this:

0000000000000000000000000000000000000000000000000000000000000008
1122334455667788000000000000000000000000000000000000000000000000

But uint8[8] is stored non-packed and without length prefix like this:

0000000000000000000000000000000000000000000000000000000000000011
0000000000000000000000000000000000000000000000000000000000000022
0000000000000000000000000000000000000000000000000000000000000033
0000000000000000000000000000000000000000000000000000000000000044
0000000000000000000000000000000000000000000000000000000000000055
0000000000000000000000000000000000000000000000000000000000000066
0000000000000000000000000000000000000000000000000000000000000077
0000000000000000000000000000000000000000000000000000000000000088
| improve this answer | |

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.