11

What is the recommended way to convert an address to bytes in Solidity?

17

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);
}
  • That's awesome! – Eamorr Mar 31 '17 at 21:24
  • Does this still work in solidity ^0.5.0? – Barrard Mar 15 at 12:12
  • With some minor syntax tweaks, yes – Tjaden Hess Mar 15 at 14:04
6

There are no current shortcuts and you need to write your own function.

Here's the function suggested by Solidity's author, chriseth:

function toBytes(address x) returns (bytes b) {
    b = new bytes(20);
    for (uint i = 0; i < 20; i++)
        b[i] = byte(uint8(uint(x) / (2**(8*(19 - i)))));
}
  • 1
    If you want to convert an address to a string, you can then convert the bytes to a string just using explicit conversion, as string(b) – MrChico Mar 22 '16 at 15:14
  • Getting this error in browser solidity: Error: Type string memory is not implicitly convertible to expected type string storage pointer. – nick carraway Aug 26 '16 at 23:27
  • 1
    @koampapapa I looked into it and answered your question ethereum.stackexchange.com/questions/8346/… If really needed, consider doing conversions in the UI/frontend/Javascript instead of Solidity to save gas. – eth Aug 27 '16 at 2:01
  • Later can we convert bytes(b) to bytes32 to store it in bytes32 format? @eth – alper Mar 1 at 7:54
  • @alper It would be better to directly cast the address to a bytes20, which will work wherever you wanted to use bytes32. – eth Mar 1 at 8:41
4

Here is my tiny one-liner for address to bytes32 conversion:

bytes32(uint256(addr) << 96);
  • This answers a different question because bytes is different from bytes32. – eth Mar 11 '18 at 9:45
  • Also, note that this will pad the bytes32 to the right. Normally, in Ethereum, we pad to the left. Just omit the << 96 to do that. – Paul Berg Feb 27 at 16:27
2

Here is an one-line solution.

abi.encodePacked(addr)

It's simple and costs little

  • 1
    Welcome to the Ethereum Stack Exchange! It is tempting to write a short answer, but too short is not helpful. For example, what does "costs little" mean? Is there a comparison of gas compared to the accepted answer? Which versions of Solidity can this be used for? – eth Nov 10 '18 at 23:46
0

This is similar to the answer given above but is more gas efficient as it is in assembly.

  function addressToBytes(address i)  returns (bytes by) { 
    by = new bytes(20); 
    assembly { 
      let count := 0 
      let byptr := add(by, 32) 
      loop: 
          jumpi(end, eq(count, 20)) 
          mstore8(byptr, byte(add(count,12), i)) 
          byptr := add(byptr, 1) 
          count := add(count, 1) 
          jump(loop) 
      end: 
    } 
    return by; 
  }
  • 2
    There's really no need for a loop at all, since we're dealing with < 32 bytes – Tjaden Hess Mar 29 '17 at 5:09
  • Yes, there is no need of loop. Good one. – ygnr Mar 29 '17 at 7:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.