Solidity两个string的⽐较
有三种⽐较⽅法
⽅法⼀:⽐较string的哈希值
⽅法⼆:先⽐较string的长度,再⽐较每个对应位置的字母是否相同
⽅法三:先⽐较string的长度,再⽐较string的哈希值
⼀.⽐较string的哈希值
function hashCompareInternal(string a, string b) internal returns (bool) {
return keccak256(a) == keccak256(b);
}
⼆.先⽐较string的长度,再⽐较每个对应位置的字母是否相同
function utilCompareInternal(string a, string b) internal returns (bool) {
if (bytes(a).length != bytes(b).length) {
return false;
}
for (uint i = 0; i < bytes(a).length; i ++) {
if(bytes(a)[i] != bytes(b)[i]) {
return false;
}
}
return true;
}
三.先⽐较string的长度,再⽐较string的哈希值
function hashCompareWithLengthCheckInternal(string a, string b) internal returns (bool) {
if (bytes(a).length != bytes(b).length) {
return false;
} else {
return keccak256(a) == keccak256(b);
}
}
四.三种⽐较⽅法的gas分析
在remix上执⾏也可以看到gas情况,但感觉不准,这⾥的统计参考:
由以上的测试可知:
1.当超过两个字母需要⽐较的时候,哈希⽅法(⽅法⼀和⽅法三)消耗的gas⽐较少;
2.当这两个string的长度不同时,先进⾏长度⽐较(⽅法⼆和⽅法三)可以节省将近40%的gas。
3.先进⾏长度⽐较只是多花了3%的gas,但可能可以节省40%的gas。
4.与使⽤字母⽐较(⽅法⼆)的⽅法相⽐,使⽤哈希⽅法(⽅法⼀和⽅法三)gas的消耗⽐较稳定。使⽤字母⽐较的⽅法消耗gas的数量呈线性增长。
五.在实际应⽤中,可以AOP⽅式,也可以在函数中直接判断
pragma solidity ^0.4.24;
contract StringComp {
mapping (address => bool) public compareRecord;
bool public checkResult = false;
modifier check(string _str1,string _str2) {
require(dePacked(_str1)) == dePacked(_str2)));
_;
}
// 使⽤AOP⽅式check⽐较两个字符串
function func1 (string __str1, string __str2) public check(__str1,__str2)  returns(bool)  {
//  保存调⽤者的⽐较结果
compareRecord[msg.sender] = true;
}
// 函数中直接判断
function compareStr (string _str1, string _str2) public returns(bool) {
solidityif(dePacked(_str1)) == dePacked(_str2))) {
// 如果⼆者相等,使checkResult为true
checkResult = true;
}else {
checkResult = false;
}
// 返回checkResult
return checkResult;
}
}
在这⾥,有直接⽤dePacked进⾏打包,关于dePacked⽅法说明,详见如下:
详见:
五.特别说明
keccak256⽅法在0.4.2及其下版本不⽀持,⾄少需0.4.3版本。
附:在remix上运⾏截图
1.StrComp.sol
pragma solidity ^0.4.24;
contract StrComp {
function hashCompareInternal(string a, string b) public returns (bool) {
return keccak256(a) == keccak256(b);
}
function utilCompareInternal(string a, string b) public returns (bool) {
if (bytes(a).length != bytes(b).length) {
return false;
}
for (uint i = 0; i < bytes(a).length; i ++) {
if(bytes(a)[i] != bytes(b)[i]) {
return false;
}
}
return true;
}
function hashCompareWithLengthCheckInternal(string a, string b) public returns (bool) {
if (bytes(a).length != bytes(b).length) {
return false;
} else {
return keccak256(a) == keccak256(b);
}
}
}
2.StringComp.sol
pragma solidity ^0.4.24;
contract StringComp {
mapping (address => bool) public compareRecord;
bool public checkResult = false;
modifier check(string _str1,string _str2) {
require(dePacked(_str1)) == dePacked(_str2)));        _;
}
// 使⽤AOP⽅式check⽐较两个字符串
function func1 (string __str1, string __str2) public check(__str1,__str2)  returns(bool)  { //  保存调⽤者的⽐较结果
compareRecord[msg.sender] = true;
}
// 函数中直接判断
function compareStr (string _str1, string _str2) public returns(bool) {
if(dePacked(_str1)) == dePacked(_str2))) {
// 如果⼆者相等,使checkResult为true
checkResult = true;
}else {
checkResult = false;
}
// 返回checkResult
return checkResult;
}
}
参考⽂章:remix地址: