This function works correctly but will consume a lot of gas. You can use the fact that string and bytes are identical in terms of storage; it's only at the 'entry' and 'exit' points of the EVM that the values are treated differently.
You can use assembly to copy the data in 32 byte blocks like this:
function bytesToString(bytes memory byteCode) public pure returns(string memory stringData)
{
uint256 blank = 0; //blank 32 byte value
uint256 length = byteCode.length;
uint cycles = byteCode.length / 0x20;
uint requiredAlloc = length;
if (length % 0x20 > 0) //optimise copying the final part of the bytes - to avoid looping with single byte writes
{
cycles++;
requiredAlloc += 0x20; //expand memory to allow end blank, so we don't smack the next stack entry
}
stringData = new string(requiredAlloc);
//copy data in 32 byte blocks
assembly {
let cycle := 0
for
{
let mc := add(stringData, 0x20) //pointer into bytes we're writing to
let cc := add(byteCode, 0x20) //pointer to where we're reading from
} lt(cycle, cycles) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
cycle := add(cycle, 0x01)
} {
mstore(mc, mload(cc))
}
}
//finally blank final bytes and shrink size (part of the optimisation to avoid looping adding blank bytes1)
if (length % 0x20 > 0)
{
uint offsetStart = 0x20 + length;
assembly
{
let mc := add(stringData, offsetStart)
mstore(mc, mload(add(blank, 0x20)))
//now shrink the memory back so the returned object is the correct size
mstore(stringData, length)
}
}
}
If you specifically need bytes32ToString the code is even simpler; I can post it as a reply but it's probably not very useful. OP wanted bytes to string.
char
values for that? or can use justA
,B
,C
?