Please explain how `address(uint160(bytes20(b)))` works differently than `address(uint160(uint256(b)))` when converting a type that uses a larger byte size then `address`, for example `bytes32`, then the `address` is truncated.

• What is `b`? a number, bytes, or ...? Jun 8, 2020 at 10:20
• @Alireza number Jun 8, 2020 at 10:41

when converting a type that uses a larger byte size then `address`

Well, the behavior of these two methods depends on that type, for example:

• For `uint256 b`, they both return the same result, which is the 160 least-significant bits of `b`
• But for `bytes32 b`, the first method returns the 160 most-significant bits of `b`

Testing method (Truffle 4.x):

``````pragma solidity 0.4.25;

contract MyContract {
function func1(bytes32 b) public pure returns (address) {
}
function func2(bytes32 b) public pure returns (address) {
}
function func3(uint256 b) public pure returns (address) {
}
function func4(uint256 b) public pure returns (address) {
}
}

contract("MyContract", accounts => {
const b = "0x8888888877777777666666665555555544444444333333332222222211111111";
it("test", async () => {
const myContract = await artifacts.require("MyContract").new();
console.log(await myContract.func1(b));
console.log(await myContract.func2(b));
console.log(await myContract.func3(b));
console.log(await myContract.func4(b));
});
});
``````

Note that some would argue that `func1` and `func2` have essentially received a different input value than `func3` and `func4`, hence the difference is in the input value rather than the method.

The difference is:

``````bytes20(some_bytes32_value)
``````

is capturing top (left) 20 bytes, while:

``````uint160(uint256(some_bytes32_value))
``````

Is capturing lowest (right) 20 bytes.