4

How to convert bytes or string (eg: 0xf2bd5de8b57ebfc45dcee97524a7a08fccc80aef) to address in solidity?

4

I feel like there might be a more efficient way to do this but here's my naive solution:

function bytesToAddress (bytes b) constant returns (address) {
    uint result = 0;
    for (uint i = 0; i < b.length; i++) {
        uint c = uint(b[i]);
        if (c >= 48 && c <= 57) {
            result = result * 16 + (c - 48);
        }
        if(c >= 65 && c<= 90) {
            result = result * 16 + (c - 55);
        }
        if(c >= 97 && c<= 122) {
            result = result * 16 + (c - 87);
        }
    }
    return address(result);
}
  • Can you explain how this works? – Miguel Mota Oct 26 '17 at 1:03
  • For sure! Assume our address is: 0x1A3b4 which you will give to the function as "1A3b4". What happens is: 1) We enter in the for loop 2) Grab the first character ("1") and cast it to a uint. In this case the ASCII corresponding to "1" is 49. 3) Since "1" = 49, we fall into the 1st "if" clause. It subtracts 48 to get integer 1. Then we take result, multiply it by 16 because address is base 16, and add it to the result. – erkt Nov 6 '17 at 9:12
  • We repeat with the next character in the byte ("A"). We cast that to a uint which gives us "A" == 65. We fall into the 2nd "if". We then take result which equals 1 multiply it by 16 and add 65-55 = 10, which is what A is in hex. – erkt Nov 6 '17 at 9:12
  • It also helps to think what happens in the case of base 10 strings. Because what were essentially doing in this function is taking the string representation of a number and converting it to a number type. Hope that helps @MiguelMota – erkt Nov 6 '17 at 9:13
1

Converting from bytes (or string) to address:

  function bytesToAddress(bytes _address) public returns (address) {
    uint160 m = 0;
    uint160 b = 0;

    for (uint8 i = 0; i < 20; i++) {
      m *= 256;
      b = uint160(_address[i]);
      m += (b);
    }

    return address(m);
  }

Usage

address addr = bytesToAddress("0xa462d983B4b8C855e1876e8c24889CBa466A67EB");

If calling from Remix IDE, pass bytes like this:

["0xa4", "0x62", "0xd9", "0x83", "0xB4", "0xb8", "0xC8", "0x55", "0xe1", "0x87", "0x6e", "0x8c", "0x24", "0x88", "0x9C", "0xBa", "0x46", "0x6A", "0x67", "0xEB"]
1

erkt's answer didn't work for me this is the solution I wrote based on it. It converts the hex bytes to uint and sums them all up then converts the uint sum to an address:

function bytesToAddr (bytes b) constant returns (address) {
  uint result = 0;
  for (uint i = b.length-1; i+1 > 0; i--) {
    uint c = uint(b[i]);
    uint to_inc = c * ( 16 ** ((b.length - i-1) * 2));
    result += to_inc;
  }
  return address(result);
}
  • Likewise for me: the accepted answer (erkt) did not work. Your answer has worked for me though, at least for the inputs I have tried. Thanks! – Travis Jacobs Jan 5 '18 at 19:31
  • Hey, I just tested my solution on Remix. Could you tell me what is wrong with my solution? Does it not compile? Or is the output wrong? If wrong output, I suspect it is because you are prefixing with "0x". So instead of doing "0xabc", just pass in "abc". – erkt Jan 5 '18 at 23:42
1

If the bytes argument is of length 20, that is, the length of an address, this assembly one-liner works for me:

function bytesToAddress(bytes bys) private pure returns (address addr) { assembly { addr := mload(add(bys,20)) } }

0

STRING to ADDRESS:

You can use Oraclize's own helper method:

contract usingOraclize { function parseAddr(string _a) internal returns (address); ... }

There https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_pre0.4.sol#L149

    function parseAddr(string _a) internal returns (address){
     bytes memory tmp = bytes(_a);
     uint160 iaddr = 0;
     uint160 b1;
     uint160 b2;
     for (uint i=2; i<2+2*20; i+=2){
         iaddr *= 256;
         b1 = uint160(tmp[i]);
         b2 = uint160(tmp[i+1]);
         if ((b1 >= 97)&&(b1 <= 102)) b1 -= 87;
         else if ((b1 >= 48)&&(b1 <= 57)) b1 -= 48;
         if ((b2 >= 97)&&(b2 <= 102)) b2 -= 87;
         else if ((b2 >= 48)&&(b2 <= 57)) b2 -= 48;
         iaddr += (b1*16+b2);
     }
     return address(iaddr);
    }
-1

Not sure if this is what you mean:

Use mapping. Try something like this:

mapping (string => address) variable;

then assign: variable["hello"] = address;

variable["hello"]; // should return an address

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.