5

I try to convert hex string to bytes.

function MyContract() public {
    string memory str = "A76A95918C39eE40d4a43CFAF19C35050E32E271";
    array1 = bytes(str);


    bytes memory  str1 = hex"A76A95918C39eE40d4a43CFAF19C35050E32E271";
    array2 = str1; 
}

In array1 I have only unicode from str like array1[0] - 41. In array 2 I have what I want array2[0] - a7. But I can't use hex with variable.

I want to use function arguments for conversion to bytes like:

function (string str) {
  return bytes(hex(str))
}

Question: Is there any way to do the conversion in Solidity?

Thanks so much in advance.

2 Answers 2

5

This are very inefficient but should work

// Convert an hexadecimal character to their value
function fromHexChar(uint8 c) public pure returns (uint8) {
    if (bytes1(c) >= bytes1('0') && bytes1(c) <= bytes1('9')) {
        return c - uint8(bytes1('0'));
    }
    if (bytes1(c) >= bytes1('a') && bytes1(c) <= bytes1('f')) {
        return 10 + c - uint8(bytes1('a'));
    }
    if (bytes1(c) >= bytes1('A') && bytes1(c) <= bytes1('F')) {
        return 10 + c - uint8(bytes1('A'));
    }
    revert("fail");
}

// Convert an hexadecimal string to raw bytes
function fromHex(string memory s) public pure returns (bytes memory) {
    bytes memory ss = bytes(s);
    require(ss.length%2 == 0); // length must be even
    bytes memory r = new bytes(ss.length/2);
    for (uint i=0; i<ss.length/2; ++i) {
        r[i] = bytes1(fromHexChar(uint8(ss[2*i])) * 16 +
                    fromHexChar(uint8(ss[2*i+1])));
    }
    return r;
}

In any case I'd recommend to try to convert your hexadecimal data outside solidity.

9
  • Thanks for the answer, the bottom is what I need, but it returns bytes. This may be a stupid question, but how do I get it as bytes32?
    – thefett
    Apr 27, 2018 at 14:10
  • @thefett It should be possible, declare bytes32 r instead of bytes memory r = new bytes(..). The problem is that it is not easy to modify indivual bytes of bytes32, but casting to uint and using shifts you can achieve that.
    – Ismael
    Apr 29, 2018 at 6:47
  • this doesn't work sadly...
    – Jim
    May 19, 2022 at 0:59
  • @Jim I tried and the functions worked from solc 0.5. It had a warning with solc 0.8 but it was easy to fix, it should have worked anyway.
    – Ismael
    May 19, 2022 at 4:18
  • when I call fromHex("FF") I want it to return the unit 255, not the raw bytes. Isn't this what OP is asking?
    – Jim
    May 19, 2022 at 5:09
2

abi.encodePacked can be used now.

bytes memory b = abi.encodePacked(hex"A76A95918C39eE40d4a43CFAF19C35050E32E271")

Your Answer

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

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