如何在Solidity中比较ASCII字符串与uint8数组?
解决uint8数组与string的比较问题
问题说明
你遇到的哈希对比失败,本质是固定大小uint8数组与string转成的动态bytes数组在abi.encodePacked中的编码逻辑存在隐性差异。虽然abi.encodePacked不会给uint8元素添加填充位,但固定数组的整体编码逻辑和动态字节数组仍有区别,导致哈希值不匹配。
正确实现方式
方式1:转成bytes后对比哈希
把固定长度的uint8数组手动转换为bytes类型,再与string转成的bytes计算哈希做对比:
uint8[3] memory foo = [98, 97, 122]; // baz string memory bar = "baz"; // 将uint8数组转为bytes bytes memory fooBytes = new bytes(foo.length); for (uint256 i = 0; i < foo.length; i++) { fooBytes[i] = bytes1(foo[i]); } // 此时哈希对比结果为true bool result = keccak256(abi.encodePacked(fooBytes)) == keccak256(abi.encodePacked(bytes(bar)));
方式2:逐元素直接对比(更省Gas)
如果不需要哈希校验,直接检查长度和每个元素的匹配性,这种方式避免了哈希计算的Gas开销:
uint8[3] memory foo = [98, 97, 122]; string memory bar = "baz"; bytes memory barBytes = bytes(bar); bool result = true; // 先校验长度是否一致 if (barBytes.length != foo.length) { result = false; } else { // 逐元素对比 for (uint256 i = 0; i < foo.length; i++) { if (bytes1(foo[i]) != barBytes[i]) { result = false; break; } } }
方式3:展开数组元素编码(仅适用于固定长度数组)
如果数组长度固定,可以直接把所有元素展开到encodePacked中,跳过数组类型的编码逻辑:
uint8[3] memory foo = [98, 97, 122]; string memory bar = "baz"; bool result = keccak256(abi.encodePacked(foo[0], foo[1], foo[2])) == keccak256(abi.encodePacked(bytes(bar)));
内容的提问来源于stack exchange,提问作者Elf
相关产品推荐
相关产品推荐

