In Solidity, how can I convert the sender address to a string?

The comments in How to convert an address to bytes in Solidity? did not provide a working solution

``````function toString(address x) returns (string) {
bytes memory b = new bytes(20);
for (uint i = 0; i < 20; i++)
b[i] = byte(uint8(uint(x) / (2**(8*(19 - i)))));
return string(b);
}
``````

You can quickly test and see that the returned string is ABI encoded.

Here is an example of converting `msg.sender` to a string:

``````contract C {
string public senderString;

function toString(address x) returns (string) {
bytes memory b = new bytes(20);
for (uint i = 0; i < 20; i++)
b[i] = byte(uint8(uint(x) / (2**(8*(19 - i)))));
return string(b);
}

function test() {
senderString = toString(msg.sender);
}
}
``````
• Does not work tested in Remix with Solidity 0.4.15 – Viktor Nov 22 '17 at 3:21
• Hi. I'm trying to convert this to C# and I'm struggling. Am I right in assuming that the argument x is of type "address" and address is an array of bytes? Also, is it correct to assume that uint(x) is a cast to uint? This is the part I don't understand. How do you cast an array of bytes to a single uint? What am I missing here? – Melbourne Developer Dec 28 '17 at 22:38
• @MelbourneDeveloper One way to consider is that x is 20 bytes (not array) big-endian left-padded to 32 bytes. There is no need to cast if you read the bytes in big-endian: it's just to make Solidity's type checker happy. It looks like BigInteger may be helpful msdn.microsoft.com/en-us/library/dd268207.aspx, you'll need to be careful since it uses little-endian, but shouldn't need to cast and can divide like given in the answer. – eth Dec 30 '17 at 15:09
• It works, but the result is not a human-readable string. For a human-readable string, see `toAsciiString` example in the other answer. – rustyx Apr 9 '18 at 13:22
• None of these codes work. – Radeg90 Jul 8 at 9:10

I was not able to read the ABI-encoded string with web3.js. Therefore I added some conversion to the ascii-characters:

``````function toAsciiString(address x) returns (string) {
bytes memory s = new bytes(40);
for (uint i = 0; i < 20; i++) {
byte b = byte(uint8(uint(x) / (2**(8*(19 - i)))));
byte hi = byte(uint8(b) / 16);
byte lo = byte(uint8(b) - 16 * uint8(hi));
s[2*i] = char(hi);
s[2*i+1] = char(lo);
}
return string(s);
}

function char(byte b) returns (byte c) {
if (b < 10) return byte(uint8(b) + 0x30);
else return byte(uint8(b) + 0x57);
}
``````
• There was a problem with the function char(byte b). "TypeError: Operator < not compatible with types bytes1 and int_const 10" I suppose this comparison does work anyway since you probably meant if b is a number then add 0x30 to it. But how do you know if a byte is less than 10 or not anyways? – Billie Jan 16 at 12:25

This is method to convert `address` to hex `string`:

``````function addressToString(address _addr) public pure returns(string) {
bytes memory alphabet = "0123456789abcdef";

bytes memory str = new bytes(42);
str = '0';
str = 'x';
for (uint i = 0; i < 20; i++) {
str[2+i*2] = alphabet[uint(uint8(value[i + 12] >> 4))];
str[3+i*2] = alphabet[uint(uint8(value[i + 12] & 0x0f))];
}
return string(str);
}
``````

```function toString(address x) internal pure returns (string) { bytes memory b = new bytes(20); for (uint i = 0; i < 20; i++) b[i] = byte(uint8(uint(x) / (2**(8*(19 - i))))); return string(b); }```

Use `internal pure` keyword, otherwise you will get a warning. For more information about pure function.