# Can anyone explain how bytes memory can be converted to address type in solidity

when I am using below function to convert bytes memory to address, this is working fine.

Suppose input to the function is 0X0000000000000000000000004af3246b4fff356261136f113411cb187134D675

I am getting the output 0x4af3246b4fff356261136f113411cb187134D675

``````    function bytesToAddress(bytes memory bys) public pure returns (address addr) {

assembly {
addr := mload(add(add(bys, 32), 0))
}
}
``````

Can, anyone explain me, what actually happening ?

## 2 Answers

The expression `add(bys, 32)`:

Returns a pointer to the actual data, which starts after the first 32 bytes in the `bys` array (those first 32 bytes contain the length of the `bys` array).

The expression `mload(x)`:

Loads the data pointed to by `x`, so you can just as well use `mload(add(bys, 32))`, because there is no added value in doing `x + 0`.

The expression `addr := y`:

Stores the value of `y` into the variable `addr` (in your case, since the value of `y` is 32-byte long and the type of `addr` is 20-byte long, only the 20 least significant bytes are stored).

• Okay ,but when I am giving 32 bytes (64 characters) input to the function having first 24 characters zeros ,, how I am getting 20 bytes (40 characters) as output. – Pardeep Thakur May 4 '20 at 13:07
• @PardeepThakur: Just as you would whenever you assign a larger-type variable into a smaller-type variable, for example, `uint16 x = 0x1234;` and then `uint8 y = x;`. The value of `y` would be the value of the 8 lower bits of `x`, i.e., `0x34`. The only thing is, that in pure Solidity, the compiler would ask you to explicitly cast `x` to the type of `y`, i.e., `uint8 y = uint8(x);`. And in assembly, the compiler performs the down-cast implicitly. – goodvibration May 4 '20 at 13:19
• Thank you, I got it – Pardeep Thakur May 4 '20 at 14:59
• @goodvibration forgive me for this noob question, but what does `bys` refer to exactly in `add(bys, 32)`? You can't really add a bytes array type to the number `32` right. – rlyx31 yesterday

You may meet the following code in many projects:

``````contract A {

event Log(address addr);

function() external {
emit Log(bytesToAddress(msg.data));
}

function bytesToAddress(bytes memory source) public pure returns(address addr) {
assembly {
addr := mload(add(source, 0x14))
}
}
}
``````

Actually `source` when meet in assembly refers to 52 bytes:

``````0000000000000000000000000000000000000000000000000000000000000020
4af3246b4fff356261136f113411cb187134D675
``````

So shifting 0x14 bytes (20 bytes) means capturing this value:

``````                                        V
0000000000000000000000000000000000000000000000000000000000000020
4af3246b4fff356261136f113411cb187134D675
^
``````

This:

``````0000000000000000000000204af3246b4fff356261136f113411cb187134D675
``````

But since return type is address Solidity compiler inserts code to erase top-12 bytes of address:

``````addr = addr & ((1 << 160) - 1)
``````

Which leads to:

``````0000000000000000000000204af3246b4fff356261136f113411cb187134D675
&
000000000000000000000000ffffffffffffffffffffffffffffffffffffffff
=
0000000000000000000000004af3246b4fff356261136f113411cb187134D675
^
``````
• Shouldn't the bytes type (in this case `source`) have a size that's a multiple of 32 bytes? Instead of the 52 bytes, `source` should be 64 bytes, with 0s appended at the end of the address? – rlyx31 yesterday