16

Hey is there a way to convert bytes to uint in Solidity?

1
  • Could you explain what conversion you would like? Best if you can give an example of a bytes value and the corresponding uint value you would like to see.
    – user19510
    Commented Jun 14, 2018 at 14:52

5 Answers 5

11

You can use this function to convert bytes to uint:

pragma solidity ^0.4.23;

contract mycontract {

    function bytesToUint(bytes b) public returns (uint256){
        uint256 number;
        for(uint i=0;i<b.length;i++){
            number = number + uint(b[i])*(2**(8*(b.length-(i+1))));
        }
        return number;
    }
}

Updated function for solidity ^0.8.11

function bytesToUint(bytes memory b) internal pure returns (uint256){
        uint256 number;
        for(uint i=0;i<b.length;i++){
            number = number + uint(uint8(b[i]))*(2**(8*(b.length-(i+1))));
        }
    return number;
}

The amount of gas used depends on the length of your bytes variable, but this is cheap. Converting a bytes variable of length 20 uses about 420 gas.

Hope this helps

3
  • Getting an error in Remix: TypeError: Return argument type bytes memory is not implicitly convertible to expected type uint256
    – arete
    Commented Jun 14, 2018 at 15:02
  • Can you show me your code?, this works for me well in remix, I put the whole code so you can just copy and paste it. Let me know
    – Jaime
    Commented Jun 14, 2018 at 15:13
  • Oh there you go. I think your first post had the return value as "b". This works. Thanks!
    – arete
    Commented Jun 14, 2018 at 15:25
12

Slicing an uint out of bytes using inline assembly

function sliceUint(bytes bs, uint start)
    internal pure
    returns (uint)
{
    require(bs.length >= start + 32, "slicing out of range");
    uint x;
    assembly {
        x := mload(add(bs, add(0x20, start)))
    }
    return x;
}
1
  • 2
    Gas efficient solution here
    – LampShade
    Commented Oct 29, 2020 at 19:45
6

A fully working modern solution can be found in this repository, authored by ConsenSys:

function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
    require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
    uint256 tempUint;

    assembly {
        tempUint := mload(add(add(_bytes, 0x20), _start))
    }

    return tempUint;
}

The accepted answer is not working in Solidity ^0.5 anymore; it produces a type conversion error.

1
  • nice nice nice!!!!
    – Howard
    Commented Sep 11, 2022 at 4:59
1

If you know the bytes length(for instance address has 20 bytes), you can convert by casting

uint256 time = uint160(bytes20(0x2E4e72EDC83053F8ADE4a525191Ba7aBA086c067));

2
  • Any risk for this?
    – Howard
    Commented Sep 11, 2022 at 4:58
  • I don't see any risk. uint160 is 20 bytes long. And uint256 fits uint160.
    – tonisives
    Commented Sep 12, 2022 at 5:52
1

Don't use byte-wise computation! it's very inefficient! The latest solidity allow you to do this:

To convert a general byte memory to uint:

function bytesToUint(bytes memory b) internal pure virtual returns (uint256) {
    require(b.length <= 32, "Bytes length exceeds 32.");
    return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));
}

If you're unpacking a big bytes calldata (you know exactly how many bytes each slice has), you can also just cast it through bytesX as follow:

function decodeCompressedCalldata(bytes calldata compressed) internal {
    // convert to uint
    uint64 expiry = uint64(bytes8(compressed[0:8]));

    // convert to uint -> int
    int a = int80(uint80(bytes10(compressed[8:18])));
}

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.