As the title says, I want to convert address to bytes32. I'm aware that in recent versions it is no longer directly convertible. I've seen a number of different ways such as:
1
bytes32(bytes20(address))
2.
bytes32(uint256(uint160(address))
No idea how accurate of efficient any of these might be however.
ethereum - How to convert address type to bytes32 via web3? - Stack Overflow
Return bytes32 or address in one or two functions? - Feedback - Solidity Forum
solidity - Can you convert my address (bytes20) type to a bytes32 string? - Ethereum Stack Exchange
solidity - Can I pass address type to bytes32 type? - Ethereum Stack Exchange
Ethereum addresses are 20 bytes, so you convert hex address to bytes and then pad it to 32 bytes from left.
web3.utils.padLeft(web3.utils.hexToBytes(yourAddressString), 32);
If you read the PadLeft documentation, you'd see that you don't need to do any conversion. You simply should do a web3.utils.padLeft(address, 64). Given that you want bytes32, that is a total of 64 hex digits, you just need to fill the difference in 0s for in order to have 64 digits.
Fixed, answer is use padding
example -> 0x0000000000000000000000000D81d9E21BD7C5bB095535624DcB0759E64B3899
Sometimes the simplest answers are right infront of you
Here's a Solidity answer to it:
function addressToBytes32(address _addr) internal pure returns (bytes32) {
return bytes32(uint256(uint160(_addr)));
}
Source: https://github.com/LayerZero-Labs/LayerZero-v2/blob/bf4318b/oapp/contracts/oft/libs/OFTComposeMsgCodec.sol
To be even more efficient:
function toBytes(address a) public pure returns (bytes memory b){
assembly {
let m := mload(0x40)
a := and(a, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
mstore(add(m, 20), xor(0x140000000000000000000000000000000000000000, a))
mstore(0x40, add(m, 52))
b := m
}
}
Takes just 695 gas vs 2500 for Gokulnath's answer and 5000 for Eth's
Edit for solidity ^0.5.0:
This is almost as efficient and much more readable:
function toBytes(address a) public pure returns (bytes memory) {
return abi.encodePacked(a);
}
Here is my tiny one-liner for address to bytes32 conversion:
bytes32(bytes20(uint160(addr)))
If you need bytes instead of bytes32:
abi.encodePacked(addr)
This works fine. Perhaps you were actually including single quotes in your code? If so, remove them.
pragma solidity ^0.4.24;
contract Test {
function test(bytes32 data) external pure returns (address) {
return address(data);
}
}
For solidity 0.5.x you can use
pragma solidity ^0.5.0;
contract Test {
function test(bytes32 data) external pure returns (address) {
return address(uint160(uint256(data)));
}
}
First convert the bytes32 to a uint256, later to uint160(20 bytes) and finaly to addres, this use big endian.
If you want use little endian you should use address(uint160(bytes20(b)))
For more information: solidity doc
If your goal is to convert your bytes to a bytes32[], maybe you can try something like:
function bytesToBytes32Array(bytes memory data)
public
pure
returns (bytes32[] memory)
{
// Find 32 bytes segments nb
uint256 dataNb = data.length / 32;
// Create an array of dataNb elements
bytes32[] memory dataList = new bytes32;
// Start array index at 0
uint256 index = 0;
// Loop all 32 bytes segments
for (uint256 i = 32; i <= data.length; i = i + 32) {
bytes32 temp;
// Get 32 bytes from data
assembly {
temp := mload(add(data, i))
}
// Add extracted 32 bytes to list
dataList[index] = temp;
index++;
}
// Return data list
return (dataList);
}
The data 0x793e39cd00000000000000000000000064a436ae831c1672ae81f674cab8b6775df3475c0000000000000000000000004a6bc4e803c62081ffebcc8d227b5a87a58f1f8f000000000000000000000000c4375b7de8af5a38a93548eb8453a498222c4ff20000000000000000000000000000000000000000000000001b9de674df070000
is 132 bytes long, and bytes32 can only hold 32 bytes of data. The code you found is working correctly, but it discards all the data after the first 32 bytes because it's impossible to fit that in a bytes32.
If you're looking for converting into an array (bytes32[]), then Phoax's code may be helpful; if you really need it to be bytes32 you might want to look at the data closely, as it looks like it's a couple of different pieces of data packed together and padded mostly to 32 or 64 bytes. From the context, you might only need one of them to be passed as a bytes32.