Solidity≥0.8.0版本下uint/bytes类型转十六进制字符串的实现方法
Solidity ≥0.8.0 十六进制值转字符串实现方案
原代码不兼容的核心问题
- 函数修饰符
constant已废弃,0.8+版本纯计算无状态操作的函数需使用pure修饰 byte类型已弃用,需替换为bytes1类型- 0.8默认开启算术溢出检查,原代码处理0值时会触发
length - 1的下溢错误,直接回滚交易 - 针对颜色值场景的额外问题:原逻辑会自动截断前导0,
0x00ff08会被转换为"ff08",不符合6位颜色字符串的要求
适配方案
方案1:通用uint转十六进制字符串(兼容任意长度数值)
修复了上述兼容性问题,同时保留原逻辑的动态长度计算能力:
pragma solidity ^0.8.0; contract HexConverter { function uint2hexstr(uint256 i) public pure returns (string memory) { if (i == 0) return "0"; uint256 j = i; uint256 length; while (j != 0) { length++; j = j >> 4; } uint256 mask = 15; bytes memory bstr = new bytes(length); uint256 k = length; unchecked { // 关闭溢出检查,避免k--时的溢出报错 while (i != 0) { uint256 curr = (i & mask); bstr[--k] = curr > 9 ? bytes1(uint8(55 + curr)) : bytes1(uint8(48 + curr)); i = i >> 4; } } return string(bstr); } }
方案2:bytes3颜色值专用转换函数(推荐用于你的场景)
由于你存储的是固定3字节的RGB颜色值,转换后固定为6位十六进制字符串,该版本会自动补全前导0,且gas成本更低:
pragma solidity ^0.8.0; contract ColorConverter { // 输入bytes3类型的颜色值,输出6位小写十六进制字符串 function color2str(bytes3 color) public pure returns (string memory) { bytes memory alphabet = "0123456789abcdef"; bytes memory str = new bytes(6); for (uint256 i = 0; i < 3; i++) { str[i*2] = alphabet[uint8(color[i] >> 4)]; str[1 + i*2] = alphabet[uint8(color[i] & 0x0f)]; } return string(str); } // 如果你的颜色值存在uint24类型变量中,可使用这个重载版本 function color2str(uint24 color) public pure returns (string memory) { return color2str(bytes3(color)); } }
效果验证
- 输入
bytes3(0xff0000)输出"ff0000" - 输入
bytes3(0x00ff08)输出"00ff08" - 输入
uint24(0x0000ff)输出"0000ff"
内容的提问来源于stack exchange,提问作者Aleks Shenshin
相关产品推荐
相关产品推荐

