如何将bytes3转换为实心的十六进制字符串 [英] How to convert bytes3 to HEX string in Solidity
问题描述
我之前问过converting uint to hex string。现在,我希望将十六进制值0x00ff08
存储在bytes3
变量中,并能够将其转换为稳健智能合约中的string
。随后,我打算将其部署在RSK上,并至少使用0.8.0版的固态编译器。
我尝试了string(abi.encodePacked(bytes3(
0x00ff08
)))
但它引发运行时错误
无法解码输出:NULL:偏移量1处的代码点无效;代码点前缀错误(参数=";bytes";,值={";0";:0,";1";:255,";2";:8},code=INVALID_ARGUMENT,VERSION=STRINGS/5.4.0)
不同的参数string(abi.encodePacked(bytes3(
0x443322
)))
不会导致错误,但会返回非常奇怪的D3"
结果。这可能是什么问题呢?如何将bytes3
转换为具有相同字符的string
?
推荐答案
您观察到的行为的原因
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
作为参数的函数。
请注意,这纯粹是为了方便起见,因为它实际上所做的只是类型转换。bytes3
和uint24
可以简单地看作是以不同的方式查看/解释的24位。
function bytes3tohexstr(bytes3 i) public pure returns (string memory) {
uint24 n = uint24(i);
return uint24tohexstr(n);
}
这篇关于如何将bytes3转换为实心的十六进制字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!