Solidity将十六进制数转换为十六进制字符串

7

我需要在Solidity智能合约中存储这样的值0xff00000x00ff08 (十六进制颜色表示),并能够将其转换为带有相同文本字符 "ff0000" 的字符串。我打算在RSK上部署该智能合约。

我的想法是将这些值存储在一个bytes3或简单的uint变量中,并拥有一个纯函数将bytes3uint转换为相应的字符串。我找到了一个可以完成工作并在Solidity 0.4.9上运行的函数。

pragma solidity 0.4.9;

contract UintToString {
    function uint2hexstr(uint i) public constant returns (string) {
        if (i == 0) return "0";
        uint j = i;
        uint length;
        while (j != 0) {
            length++;
            j = j >> 4;
        }
        uint mask = 15;
        bytes memory bstr = new bytes(length);
        uint k = length - 1;
        while (i != 0){
            uint curr = (i & mask);
            bstr[k--] = curr > 9 ? byte(55 + curr ) : byte(48 + curr); // 55 = 65 - 10
            i = i >> 4;
        }
        return string(bstr);
    }
}

但是我需要更高版本的编译器(至少0.8.0)。上面的函数在新版本上无法使用。

在Solidity >= 0.8.0上如何将bytesuint转换为十六进制字符串(1->'1',f->'f')?

1个回答

4
以下代码已经编译并使用solc 0.8.7进行了测试,与原始版本相同,但进行了以下修改:
  • constant --> pure
  • returns (string) --> returns (string memory)
  • byte(...) --> bytes1(uint8(...))
以上更改解决了原始函数中的所有编译时差异。 ...但是仍然存在运行时错误导致此函数恢复到初始状态:
在调试过程中,bstr[k--] = curr > 9 ?一行在其所处的循环的最后一次迭代中触发了还原。这是因为while循环设置为在其最终迭代中k为0。
尽管确定问题比较棘手,但修复方法很简单:将减量操作符从后缀改为前缀-bstr[--k] = curr > 9 ?

附言:

问: 为什么在solc 0.4.9编译时没有回滚,但是在同样的代码在solc 0.8.7编译时回滚了?

答: solc 0.8.0引入了一个破坏性变化,编译器插入了uint溢出和下溢检查。在此之前,需要使用SafeMath或类似工具来实现相同的功能。 请参阅solc 0.8版本发布说明中的“语义的静默更改”部分

pragma solidity >=0.8;

contract TypeConversion {
    function uint2hexstr(uint i) public pure returns (string memory) {
        if (i == 0) return "0";
        uint j = i;
        uint length;
        while (j != 0) {
            length++;
            j = j >> 4;
        }
        uint mask = 15;
        bytes memory bstr = new bytes(length);
        uint k = length;
        while (i != 0) {
            uint curr = (i & mask);
            bstr[--k] = curr > 9 ?
                bytes1(uint8(55 + curr)) :
                bytes1(uint8(48 + curr)); // 55 = 65 - 10
            i = i >> 4;
        }
        return string(bstr);
    }
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接