bit-manipulation - 如何在 Solidity 中将 bytes3 转换为 HEX 字符串
问题描述
我之前询问过将 uint 转换为 hex string。现在我想将一个 HEX 值存储0x00ff08
在一个bytes3
变量中,并能够将其转换为string
Solidity 智能合约。随后,我打算将其部署在具有 Solidity 编译器版本至少为 0.8.0 的 RSK 上。
我试过了,但它会引发运行时错误string(abi.encodePacked(bytes3(
0x00ff08
)))
解码输出失败:null:偏移量 1 处的代码点无效;错误的代码点前缀 (argument="bytes", value={"0":0,"1":255,"2":8}, code=INVALID_ARGUMENT, version=strings/5.4.0)
不同的参数不会导致错误,但会返回一个非常奇怪的结果。这里可能是什么问题?如何转换为具有相同字符的 a?string(abi.encodePacked(bytes3(
0x443322
)))
D3"
bytes3
string
解决方案
您观察到的行为的原因
abi.encodePacked(myBytes3)
产生 3 个字节,因为每 2 个十六进制字符产生 1 个字节。所以当你把它包装进去时,string(..)
你会得到一个每 1 个字节有 1 个字符的字符串,在这种情况下,这会产生一个有 3 个字符的字符串。对于某些输入,这会产生一个可以呈现为人类可读字符串的字符串。在其他情况下,它会导致字符串不能,因此会出现解析错误。
解决方案
在这种情况下您不能使用abi.encodePacked(..)
,因为“打包”与您尝试完成的相反bytes3
- 将 a 呈现为十六进制string
- 一种人类可读的 ASCII 编码 - 您需要做一些类似于
我的回答你之前的问题,你使用位移位和位掩码的组合来每半字节提取一个字符。
代码
将单个uint8
转换为 ASCII 字符的实用函数,该 ASCII 字符将用十六进制表示它:
function uint8tohexchar(uint8 i) public pure returns (uint8) {
return (i > 9) ?
(i + 87) : // ascii a-f
(i + 48); // ascii 0-9
}
uint24
将 a 转换为 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
作为参数的函数。
请注意,这纯粹是为了方便,因为它所做的只是类型转换。和可以简单地认为是“24 位”以不同的方式查看/解释bytes3
。uint24
function bytes3tohexstr(bytes3 i) public pure returns (string memory) {
uint24 n = uint24(i);
return uint24tohexstr(n);
}
推荐阅读
- python - Python中的while循环用于多个条件
- javascript - 刷新Django html 模板中的元素
- python - iIfix Import "yfinance" 怎么解决不了
- node.js - HapiJS 用户会话管理
- ios - 如何向 UIAlert 添加功能
- c# - 如何在一个视图中传递两个模型
- laravel - 使用 OR 子句与多个字段的 Laravel 关系
- c - 位移超出允许范围
- python - 将 Paho 用于 MQTT TLS 时出现错误 [SSL] PEM lib (_ssl.c:4022)
- swift - 如何使用 RxSwift 设置要在 collectionView 中显示的单元格数量?