Solidity极简入门: 28. Hash

我最近在重新学solidity,巩固一下细节,也写一个“Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。

欢迎关注我的推特:@0xAA_Science

WTF技术社群discord,内有加微信群方法:链接

所有代码和教程开源在github(1024个star发课程认证,2048个star发社群NFT): github.com/AmazingAng/WTFSolidity


哈希函数(hash function)是一个密码学概念,它可以将任意长度的消息转换为一个固定长度的值,这个值也称作哈希(hash)。这一讲,我们简单介绍一下哈希函数及在solidity的应用

Hash的性质

一个好的哈希函数应该具有以下几个特性:

  • 单向性:从输入的消息到它的哈希的正向运算简单且唯一确定,而反过来非常难,只能靠暴力枚举。
  • 灵敏性:输入的消息改变一点对它的哈希改变很大。
  • 高效性:从输入的消息到哈希的运算高效。
  • 均一性:每个哈希值被取到的概率应该基本相等。
  • 抗碰撞性:
    • 弱抗碰撞性:给定一个消息x,找到另一个消息x'使得hash(x) = hash(x')是困难的。
    • 强抗碰撞性:找到任意xx',使得hash(x) = hash(x’)是困难的。

Hash的应用

  • 生成数据唯一标识
  • 加密签名
  • 安全加密

Keccak256

Keccak256函数是solidity中最常用的哈希函数,用法非常简单:

哈希 = keccak256(数据);

生成数据唯一标识

我们可以利用keccak256来生成一些数据的唯一标识。比如我们有几个不同类型的数据:uintstringaddress,我们可以先用abi.encodePacked方法将他们打包编码,然后再用keccak256来生成唯一标识:

    function hash(
        uint _num,
        string memory _string,
        address _addr
    ) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(_num, _string, _addr));
    }

弱抗碰撞性

我们用keccak256演示一下之前讲到的弱抗碰撞性,即给定一个消息x,找到另一个消息x'使得hash(x) = hash(x')是困难的。

我们给定一个消息0xAA,试图去找另一个消息,使得它们的哈希值相等:

    // 弱抗碰撞性
    function weak(
        string memory string1
    )public view returns (bool){
        return keccak256(abi.encodePacked(string1)) == _msg;
    }

大家可以试个10次,看看能不能幸运的碰撞上。

强抗碰撞性

我们用keccak256演示一下之前讲到的强抗碰撞性,即找到任意不同的xx',使得hash(x) = hash(x’)是困难的。

我们构造一个函数strong,接收两个不同的string参数string1string2,然后判断它们的哈希是否相同:

    // 强抗碰撞性
    function strong(
        string memory string1,
        string memory string2
    )public pure returns (bool){
        return keccak256(abi.encodePacked(string1)) == keccak256(abi.encodePacked(string2));
    }

大家可以试个10次,看看能不能幸运的碰撞上。

总结

这一讲,我们介绍了什么是哈希函数,以及如何使用solidity最常用的哈希函数keccak256

Subscribe to 0xAA
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.