区块链中的哈希函数
所谓哈希函数不是指某种特定的函数,而是一类函数,它有各种各样的实现。
维基百科对散列函数的定义如下:
散列函数(英语:Hash function)又称**散列算法**、**哈希函数**,是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个叫做**散列值**(hash values,hash codes,hash sums,或hashes)的指纹。散列值通常用一个短的随机字母和数字组成的字符串来代表。好的散列函数在输入域中很少出现[散列冲突]。在[散列表]和[数据处理]中,不抑制冲突来区别数据,会使得数据库记录更难找到。
通过这个定义,很难看明白这个哈希函数到底是干什么用的。我们可以先看看这个哈希函数都有哪些性质,通过对性质的分析,可能会对这个hash函数有进一步认识,在北大肖臻的区块链课程中有提到这些性质,我们接下来挨个来看看。

1. 防碰撞性(collision resistance)
当给定不同的输入参数x,y,且x≠y,但是算出来的结果H(x) = H(y),这样的现象就被称为哈希碰撞,产生这种现象的原因,是因为输入空间远远大于输出空间。
这里的防碰撞特性的意思是,给定一个x可以计算出其哈希值为H(x),但是没有比较好的办法,能找到另外一个值y,使它的哈希值H(y)=H(x),也就是人为的制造哈希碰撞。
遍历所有输入空间去找到这个值,这种方式就叫做brute-force暴力破解。
哈希函数一般用来计算digest(摘要信息),可以很好的保证信息不被篡改。
场景分析:比如一个区块链地址:0xf14f7a4b4ddd69f7bf500ca4c962b03ac95c30fe24e1b4afa87d21e8285c4be9,就是对整个区块进行哈希计算,在比特币中,一个区块大概可以包含4000比交易,但是通过这个地址,就可以完成对这4000比交易的验证,这里就体现了哈希函数的压缩特性和防碰撞特性。

2. 隐藏性(Hiding)
哈希函数的计算过程是单向不可逆的。也就是通过可以推出H(x),但是没有办法通过H(x)这个结果反推x的值,也就是说,哈希值H(x)没有泄露输入的x的任何信息。也就是x的信息被安全的隐藏起来。
场景分析:还是拿这个区块链地址来看:0xf14f7a4b4ddd69f7bf500ca4c962b03ac95c30fe24e1b4afa87d21e8285c4be9
假设这个区块中包含了4000比交易,因为哈希函数具有的压缩特性,使得根本没办法从这个地址,恢复出4000比交易的完整信息。这也就说明,这个地址,没有泄露区块中任何一笔交易的信息,体现的就是隐藏性(单向性)。

3. 谜题友好(puzzlefriendly)
无法通过控制输入值x来获得任意想要的输出值H(x),但是一旦找到了某个H(x),其他人验证,又是佷容易的。
场景分析:在区块链中,某个区块被打包后,会在全网广播。当其他节点拿到算出来的hash值和区块的完整交易信息后,需要对它们做验证,验证的方式就用这些交易信息再次计算hash值,再将自己计算的hash值和广播的hash值比对,来确定广播的信息是否可信。
下图为wiki中,对常见的哈希函数的对比分析:

在区块链的项目实现中,SHA256占据了很重要的位置,后面会贴出在btc和eth中,SHA256的使用代码,足可见此方法的奠基性。

SHA256简介
SHA-2,名称来自于安全散列算法2(英语:Secure Hash Algorithm 2)的缩写,一种密码散列函数算法标准。SHA256属于SHA-2,SHA-2总共包括SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256这六个标准。
SHA-256和SHA-512是很新的散列函数,前者以定义一个word为32位,后者则定义一个word为64位。它们分别使用了不同的偏移量,或用不同的常量,然而,实际上二者结构是相同的,只在循环执行的次数上有所差异。SHA-224以及SHA-384则是前述二种散列函数的截短版,利用不同的初始值做计算。
对SHA256底层有兴趣的,可以进一步学习算法实现的文章。比如:[大白话讲解SHA256](https://juejin.cn/post/7128056401087168519)
在btcd(比特币的go语言实现)项目中,调用的hash方法的代码是:
在go-ethereum项目依赖golang.org/x/crypto@v0.1.0/sha3/hashes.go中的代码是:
我们知道MD5 与 SHA-1 算法已被攻破,不应该再被用于新的用途;SHA-2 与 SHA-3 还是安全的,可以使用。
SHA-2系列包括:SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。
SHA-3系列包括:SHA3-224、SHA3-256、SHA3-384、SHA3-512。

从源代码中可以看出,以太坊用的是sha3-256,而比特币用的是sha-256。

