【问题标题】:How to convert bytes3 to HEX string in Solidity如何在 Solidity 中将 bytes3 转换为 HEX 字符串
【发布时间】:2021-11-17 13:51:01
【问题描述】:

我之前询问过converting uint to hex string。现在我想将一个十六进制值 0x00ff08 存储在一个 bytes3 变量中,并能够将其转换为 Solidity 智能合约中的 string。随后我打算将其部署在 RSK 上,Solidity 编译器版本至少为 0.8.0 。

我试过这个string(abi.encodePacked(bytes3(0x00ff08))),但它会引发运行时错误

解码输出失败:null:偏移量 1 处的代码点无效;错误的代码点前缀(argument="bytes", value={"0":0,"1":255,"2":8}, code=INVALID_ARGUMENT, version=strings/5.4.0) p>

不同的参数string(abi.encodePacked(bytes3(0x443322))) 不会导致错误,但会返回一个非常奇怪的D3" 结果。这里可能是什么问题?如何将bytes3 转换为具有相同字符的string

【问题讨论】:

    标签: bit-manipulation solidity rsk


    【解决方案1】:

    您观察到的行为的原因

    abi.encodePacked(myBytes3) 产生 3 个字节,因为每 2 个十六进制字符产生 1 个字节。因此,当您将其包装在 string(..) 中时,您确实会得到一个每 1 个字节有 1 个字符的字符串,在这种情况下,会产生一个包含 3 个字符的字符串。对于某些输入,这会产生一个 可以 呈现为人类可读字符串的字符串。在其他情况下,它会导致字符串不能,因此会出现解析错误。

    解决方案

    在这种情况下,您不能使用 abi.encodePacked(..),因为“打包”与您要完成的操作相反相反 - 将 bytes3 呈现为十六进制 string - 一个那是人类可读的,ASCII编码的——你需要做类似的事情 my answer to your previous question,您可以结合使用位移和位掩码来每半字节提取一个字符。

    代码

    将单个uint8 转换为以十六进制表示它的ASCII 字符的实用函数:

        function uint8tohexchar(uint8 i) public pure returns (uint8) {
            return (i > 9) ?
                (i + 87) : // ascii a-f
                (i + 48); // ascii 0-9
        }
    

    uint24 转换为6 个字符的十六进制string 的函数。

    请注意,由于这次您不是在寻找“通用”解决方案,而是特定于 bytes3 的解决方案,因此不需要任何循环,而是一组顺序语句就可以了.可能也节省了一些气体。(有待确认!)

        function uint24tohexstr(uint24 i) public pure returns (string memory) {
            bytes memory o = new bytes(6);
            uint24 mask = 0x00000f;
            o[5] = bytes1(uint8tohexchar(uint8(i & mask)));
            i = i >> 4;
            o[4] = bytes1(uint8tohexchar(uint8(i & mask)));
            i = i >> 4;
            o[3] = bytes1(uint8tohexchar(uint8(i & mask)));
            i = i >> 4;
            o[2] = bytes1(uint8tohexchar(uint8(i & mask)));
            i = i >> 4;
            o[1] = bytes1(uint8tohexchar(uint8(i & mask)));
            i = i >> 4;
            o[0] = bytes1(uint8tohexchar(uint8(i & mask)));
            return string(o);
        }
    

    最后,您可能需要一个明确接受bytes3 作为参数的函数。

    请注意,这纯粹是为了方便,因为它所做的只是类型转换。 bytes3uint24 可以简单地视为以不同方式查看/解释的“24 位”。

        function bytes3tohexstr(bytes3 i) public pure returns (string memory) {
            uint24 n = uint24(i);
            return uint24tohexstr(n);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-13
      • 2018-03-20
      • 2016-08-28
      • 2019-12-27
      • 1970-01-01
      • 2019-12-30
      • 1970-01-01
      相关资源
      最近更新 更多