码迷,mamicode.com
首页 > 其他好文 > 详细

Solidity两个string的比较

时间:2018-12-13 19:18:46      阅读:455      评论:0      收藏:0      [点我收藏+]

标签:string   index   util   字符串   ocs   blank   线性   pattern   ack   

有三种比较方法

方法一:比较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情况,但感觉不准,这里的统计参考:https://blog.csdn.net/xiaomei1xiake2/article/details/81868317

由以上的测试可知:
      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(keccak256(abi.encodePacked(_str1)) == keccak256(abi.encodePacked(_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(keccak256(abi.encodePacked(_str1)) == keccak256(abi.encodePacked(_str2))) {
            // 如果二者相等,使checkResult为true
            checkResult = true;
        }else {
            checkResult = false;
        }
        // 返回checkResult
        return checkResult;
    }
}

        在这里,有直接用abi.encodePacked进行打包,关于abi.encodePacked方法说明,详见如下:

技术分享图片

        详见:https://solidity.readthedocs.io/en/v0.4.24/units-and-global-variables.html

 

五.特别说明

        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(keccak256(abi.encodePacked(_str1)) == keccak256(abi.encodePacked(_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(keccak256(abi.encodePacked(_str1)) == keccak256(abi.encodePacked(_str2))) {
            // 如果二者相等,使checkResult为true
            checkResult = true;
        }else {
            checkResult = false;
        }
        // 返回checkResult
        return checkResult;
    }
}

技术分享图片

 

参考文章:https://blog.csdn.net/xiaomei1xiake2/article/details/81868317

https://www.liankexing.com/index.php/Question/question_page.html?id=1249

https://solidity.readthedocs.io/en/v0.4.24/units-and-global-variables.html

String Equality Comparison

String patterns github

remix地址:https://remix.ethereum.org/

Solidity两个string的比较

标签:string   index   util   字符串   ocs   blank   线性   pattern   ack   

原文地址:https://www.cnblogs.com/flyingeagle/p/10115287.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!