3

After solidity 0.5.x release none of conversions from address to string appear to be working. I've tested all of them on remix and got errors like converting bytes to uint or something like this.

This one reverts remix:

function toString(address x) 
    external pure 
    returns (string memory) 
{
    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);
}

This one shows me that something is not allowed from bytes1 to uint256

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

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

Is there any proper way to convert address to string? Even if through bytes or bytes32.

The reason why I need this is I have a privileges contract with string => PrivilegeData mapping and Im' calling global privileges from that string like "voting_time_limit". For specific addresses I would like to use calling by address parsed to string like "0x252f...".

1
  • Watch out from truncation in (2**(8*(19 - i))). Jul 8, 2019 at 10:05

1 Answer 1

2

Try this out.

pragma solidity > 0.5.1;

contract Test 
{
    
    function test() 
        public 
        view    
        returns (string memory) 
    {
        return addressToString(address(this));
    }

    function addressToString(address _addr) public pure returns(string memory) 
    {
        bytes32 value = bytes32(uint256(uint160(_addr)));
        bytes memory alphabet = "0123456789abcdef";
    
        bytes memory str = new bytes(51);
        str[0] = '0';
        str[1] = 'x';
        for (uint256 i = 0; i < 20; i++) {
            str[2+i*2] = alphabet[uint8(value[i + 12] >> 4)];
            str[3+i*2] = alphabet[uint8(value[i + 12] & 0x0f)];
        }
        return string(str);
    }
}
4
  • 1
    So why 51 bytes and not 43? Jul 8, 2019 at 10:07
  • 51 just because that's the code provided, but if we look into that, 42 will fit the 40 characters + 2 the 0x. Jul 8, 2019 at 10:10
  • 43, since I believe you also need to allocate for the null-character. Jul 8, 2019 at 10:11
  • 1
    what null character ? are you talking about the null byte in "empty strings" ? or the null byte used by c++ ? solidity does not have that as far as i'm aware, it just stores the string length in an uint256 in the first 32 bytes where the variable points to, and does pointer plus 32 to where it stores the actual string array Jul 8, 2019 at 10:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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