1️⃣ 参考
- 北京大学肖臻老师《区块链技术与应用》
2️⃣ 密码学原理篇
1. 哈希
哈希函数(cryptographic hash function),因为鸽笼原理(抽屉原理)【把多于n个的物品放到n个抽屉里,则至少有一个抽屉里的物品不少于两件】,会产生哈希碰撞(collision)
密码学中哈希函数性质:
-
抗碰撞性(collision resistance)
- 理解: 例如
x≠y H(x)=H(y)
两个不同的输入,输出却是相等的,这就称哈希碰撞。它是不可避免的,因为输入空间总大于输出空间。理论上可以用暴力比对(brute-force)来破解,但运算量极其大,所以一般认为破解不了。 - 作用: 对一个 message 求摘要(digest),用于检测对输入值是否篡改。
- 理解: 例如
-
哈希函数计算过程是单向不可逆(hiding)
- 理解: 从 H (x) 无法推导出 x,前提是输入空间足够大,分布比较均匀。如果不是足够大,一般在 x 后面拼接一个随机数,如 H (x||nonce)。
- 作用: 结合抗碰撞性,实现使用实现数字承诺or密封信封的数字等价物(digital commitment or digital equivalent of a sealed envelope),也就是让人们知道哈希值而不知道预测值(假设是X)
如下图,不能提前透露的预测值X,经过哈希运算后,只要摘要不变,就保证了的X没有被修改
比特币中哈希函数的性质:
- puzzle friendly
- 理解: 指哈希值的预算事先是不可预测
- 作用: 保证只能从头开始一个一个的尝试nonce(挖矿),一种公平机制,没有捷径,也是工作量证明(proof of work)
- 设计: 要满足difficult to slove, but easy to verify
“集大成者”:比特币中用的哈希函数叫作 SHA-256
(secure hash algorithm) 以上三个性质它都是满足的。
尝试理解挖矿过程:尝试nonce,计算出哈希值,满足 H ( b l o c k h e a d e r ) < = t a r g e t H(block \ header) <= target H(block header)<=target 就算成功,成功后发布nonce值,其余人验证nonce是否满足。
2. 签名
-
非对称加密(asymmetric encryption algorithm)
- 理解:公钥和私钥(public key, private key)对
- 咋用:使用接收方的公钥加密后发个接收方,接收方使用与自己公钥匹配的私钥解密,类似公钥-银行卡号,私钥-银行卡密码,转钱时只需要知道对方银行卡号
- 关键:生成优质的公钥和私钥关键(好的随机源)
-
对称加密(encryption algorithm)
- 理解:加密解密使用同一个密钥(encryption key)
- 咋用:类似RAR压缩包密码,加密和解密必须一样
- 缺点:如何安全的发送密钥给对方
3️⃣ 数据结构篇
1. 哈希指针
一个普通指针p指向结构体地址 + 保存结构体哈希值H()
优点: 既可以找到结构体的位置,同时还可以检测出结构体有没有被篡改
2. 区块链与普通链
-
区别
- 使用哈希指针代替了普通指针
- 当修改一个节点(中的内容)后,普通链表不影响,区块链会牵一发而动全身
-
区块链的特征
- 第一个区块称作:
genesis block
- 最后一个区块(也是最近产生的)称作:
most recent block
- 每一个区块都包含指向前一个区块的哈希指针,其中的哈希值是将前一个区块全部内容取的哈希
- 指向最后一个区块的哈希指针保存在本地,由于区块链的
tamper-evident log
(防篡改log)特点,一区块改动,后面一个区块的哈希值就要改变,以此类推,最后的哈希值肯定会变,所以只需要比对最后一个区块的哈希值就知道整个区块链有没有被篡改
- 第一个区块称作:
3. 默克尔树
- 一图胜千言
Merkle tree
- 与二叉树区别: 指针变成了哈希指针
- 作用: 用于区块内部交易信息的数据结构
- Merkel proof
- 背景:因为硬件的局限。一个区块大小为1MB,比特币中的节点分为全节点和轻节点,全节点保存整个区块内容(block header + block body),轻节点类似手机上的比特币钱包的应用(may be only block header),那么如何向轻节点证明某个交易是否写入区块链里?
- 这便需要用到
Markle proof
。我们将交易到根节点这一条路径称为Markle proof
,全节点将整个Markle proof
发送给轻节点(如上图所示),轻节点即可根据其算出根哈希值,和自己保存的对比,从而验证该交易是否被写入区块链。只要沿着该路径,所有哈希值都正确,说明内容没有被修改过。具体过程如下:
① 求出某个tx哈希(绿色H()) + 向全节点请求来的红色H() =>root hash
② 求出的root hash
与本地root hash
对比,相同说明没有发生交易,不同说明发生了交易 - 证明Merkel tree中包含了某个交易(tx),这种证明方式:证明存在的方式被称为
proof of membership or proof of inclusion
(证明包含),时间复杂度为O(log(n)) - 仅仅能说明有交易,但交易的具体内容不能保证
- Merkel proof
3. 补充
-
能不能证明(节点)不存在(proof of non-menbership) ?
- 假设需要证明不存储的节点为B
① 发送全部交易给轻节点,一个一个与B比对
② 按照哈希值从小到大排序叶节点(sorted merkle tree),假设H(B)夹在H(A)与H[C]之间,此时计算 H(A)与 H[C]的Merkel proof,如果最终root hash
与本地一致,就说明H(A)与H[C]本来就是相邻的, 侧面证明了H(B)不存在
- 假设需要证明不存储的节点为B
-
思考:是否存在不安全的情况?
源于:https://blog.nowcoder.net/n/cba8b18bd5294a14b09b299c1ff5d961