Hey is there a way to convert bytes
to uint
in Solidity?
5 Answers
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
-
Getting an error in Remix: TypeError: Return argument type bytes memory is not implicitly convertible to expected type uint256– areteCommented 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– JaimeCommented Jun 14, 2018 at 15:13
-
Oh there you go. I think your first post had the return value as "b". This works. Thanks!– areteCommented Jun 14, 2018 at 15:25
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;
}
-
2
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.
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])));
}
If you know the bytes length(for instance address has 20 bytes), you can convert by casting
uint256 time = uint160(bytes20(0x2E4e72EDC83053F8ADE4a525191Ba7aBA086c067));
-
-
I don't see any risk. uint160 is 20 bytes long. And uint256 fits uint160. Commented Sep 12, 2022 at 5:52
bytes
value and the correspondinguint
value you would like to see.