# How could I convert uint type to bytes type in solidity?

function toBytes(uint256 x) public pure returns (bytes memory b) {
b = new bytes(32);
assembly { mstore(add(b, 32), x) }
}


But this doesn't work like what I thought. For example, if I put 0x0000000000000000000000000000000000000000000000000000000000000abc to the input value, I expected to have a return value which looks like this 0xabc0000000000000000000000000000000000000000000000000000000000000. But this function returns same as input value which is 0x0000000000000000000000000000000000000000000000000000000000000abc. How could I convert 0x0000000000000000000000000000000000000000000000000000000000000abc this to 0xabc0000000000000000000000000000000000000000000000000000000000000 this in solidity?

• Could you elaborate a bit more on what exactly you are trying to achieve? In your example byte boundaries are not preserved. Original uint has bytes 0a and bc, while resulting bytes has ab and c0. – Mikhail Vladimirov Dec 24 '19 at 6:39
• @MikhailVladimirov I meant if I put the uint256 input value 0x0000000000000000000000000000000000000000000000000000000000000abc to a function, I want to receive 0xabc. – Jung Chun Dec 24 '19 at 6:50
• 0xabc is not a valid bytes value, as it is 12 bit long, while each byte is 8 bits. So it is fractional number of bytes. – Mikhail Vladimirov Dec 24 '19 at 7:09
• @MikhailVladimirov Oh OK, then I'll change my example to 0x000000000000000000000000000000000000000000000000000000000000abcd. I want to receive 0xabcd when I give an input value 0x000000000000000000000000000000000000000000000000000000000000abcd. But that function returns same as input value. – Jung Chun Dec 24 '19 at 7:38
• But what would be correct output for the original example? I need this to understand the general rule. – Mikhail Vladimirov Dec 24 '19 at 9:00

What you are looking to do is called bit shifting. Solidity allows bit shifting using the << and >> operators.

For your example, the non-zero portion of 0x000000000000000000000000000000000000000000000000000000000000abcd is abcd which occupies 16 bits. Because a bytes32 is 256 bits long, you must shift 240 bits to return the desired value:

function toBytes(uint256 x) public pure returns (bytes32) {
return bytes32(a) << 240;
}


Note that the above example only works when the initial value is 2 bytes long. If you are not certain of the length of your initial value, you can determine it using a for loop and some division:

function toBytes(uint256 a) public pure returns (bytes32) {
uint i;
for (i = 0; i < 33; i++) {
if (a / 256**i == 0) break;
}
return bytes32(a) << (32-i)*8;
}


• OP wants to convert to bytes not to bytes32. – Mikhail Vladimirov Dec 24 '19 at 14:58

function toBytes(uint256 x) public pure returns (bytes memory b) {
uint l = 32;

if (x < 0x100000000000000000000000000000000) { x <<= 128; l -= 16; }
if (x < 0x1000000000000000000000000000000000000000000000000) { x <<= 64; l -= 8; }
if (x < 0x100000000000000000000000000000000000000000000000000000000) { x <<= 32; l -= 4; }
if (x < 0x1000000000000000000000000000000000000000000000000000000000000) { x <<= 16; l -= 2; }
if (x < 0x100000000000000000000000000000000000000000000000000000000000000) { x <<= 8; l -= 1; }
if (x < 0x100000000000000000000000000000000000000000000000000000000000000) { x <<= 8; l -= 1; }

b = new bytes (l);

assembly { mstore(add(b, 32), x) }
}


For me it does:

0x0 -> 0x        (zero bytes)
0x1 -> 0x01      (1 byte)
0xFF -> 0xFF     (1 byte)
0x100 -> 0x0100  (2 bytes)
0xFFFF -> 0xFFFF (2 bytes)
etc.