目录
1.概述
2.密码学原理
2.1.hash函数
2.2.签名
3.数据结构
3.1.区块结构
3.2.hash pointer
3.3.merkle tree
3.3.1.概述
3.3.2.证明数据存在
3.3.3.证明数据不存在
4.比特币的共识协议
4.1.概述
4.2.验证有效性
4.2.1.验证交易有效性
4.2.2.验证节点有效性
4.3.发行货币
5.一些实现上的便捷机制
5.1.未使用的交易输出
5.2.交易费用
1.概述
我们常听说大数据、云计算、人工智能、5G、区块链这些名词,这些“未来技术”最终目的是想使得未来社会的走向“智能化”,生产、交通、学习、城市管理、能源传输等等都将智能化,所谓智能化就是让以上场景变得更加高效。而智能化的实现则需要各方技术协作,整个支持智能化社会的技术架构将会是:
我们常听说区块链是一个去中心化的“账本”,本质上来说区块链是社会关系的智能化,核心问题是为了解决“信任”问题,传统的社会关系是由人与人之间构建起来的,依赖于人与人之间的情感和信任,往往会影响社会的效率和公正;区块链依靠机器和算法来构建社会关系,能保证公平高效。
2.密码学原理
2.1.hash函数
hash函数是把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。hash函数只是一种广义上的思想,具体的落地实现,五花八门。
hash函数优质与否的指标在于hash碰撞,x≠y,hash(x)=hash(y),称为hash碰撞,杜绝hash碰撞是几乎不可能的,因此优质的hash函数要确保低碰撞率。
hash函数的两个重要性质:
防篡改
一旦原文被改动了,hash运算出来的摘要也会改变,除非更改后的内容与原内容产生了hash碰撞,所以这时候hash函数的优质与否就起到了决定性因素。
隐藏
hash函数是单项的没办法从摘要直接还原成原文,因此hash函数能较好的隐藏原文的特点。
2.2.签名
由于区块链网络中,信息都是公开的,需要签名来防止伪造操作,比如A有十个比特币,系统中突然出现一条A把10个比特币转给了B,这么知道这是A自己发出的请求而不是别人伪造的喃?这就是签名的作用。区块链中的签名使用的是非对称加密。
3.数据结构
3.1.区块结构
每个区块由两部分组成:
block header(块头),包含如下内容:
存放协议版本号
指向前一区块的hash指针
当前节点的merkle tree root hash
挖矿的难度阈值target
随机数nonce
block body(块身),包含如下内容:
用merkle tree来存放所有交易记录。
区块分为两种类型:
全结点,包含block header、block body的结点,真正参与存储数据的区块链的真正的结点。
轻结点,只保存block header,如手机上的比特币钱包。
3.2.hash pointer
hash pointer,哈希指针,普通指针是指向地址,而哈希指针是指向哈希值。
区块链中每一个区块的block header都有一个hash pointer指向前一个区块的哈希值
区块链中每一个块的哈希值由block header运算得出,block header里包含指向前一个block的hash pointer,所以每个block的hash都是由前一个块的哈希值参与运算得出,
系统里有一个hash pointer指向最后一个区块,
这种结构能保证从系统反推到任意一个块的篡改。
使用hash pointer时要特别注意hash碰撞造成的环路,一旦出现环路,使用hash值定位就会失效。
3.3.merkle tree
3.3.1.概述
区块链在落地使用时一般会分成多个分区,分区内部每个区块会记录当前分区中所有区块的数据:
每个块内部使用merkle tree来组织存储数据。
merkle tree,梅克尔树,和普通树相比区别在于,梅克尔树用hash pointer代替了普通指针。
每个结点的hash都是由左右孩子结点的hash一同参与生成的,整颗树的根结点的hash称为root hash。
merkle树的叶节点上挂得是data block(数据)。
merkle tree是从data block开始,两两配对生成一个节点,然后节点之间再两两配对生成一个父节点,然后父节点之间再两两配对生成一个节点…..以此类推最后生成一个根节点,根节点的左右hash最后生成root hash:
这种结构能保证从系统(root hash)向下反推到任意一个结点的篡改,验证其是否合法,并且由于其是树形结构,比链表结构的hash pointer验证效率要高。
如果merkle tree要新增、删除、修改data block里的data,如果这个操作是被同意的,那么会引起整颗树的hash的变化,下次再去校验的时候,这个操作能通过。
如果这个操作不是被同意的,而是悄悄咪咪做的,那么去校验的时候由于整棵树的hash并没有变化,被篡改的data验证一定通过不了。
3.3.2.证明数据存在
使用手机进行转账,手机这个轻结点如何知道交易是否已经被写到区块链中了?
比如校验黄色交易是否存在,只要轻结点向全节点拿红色的那几个hash,轻结点用自己block header里面的root hash就能算出黄色的交易是否合法。
从根节点到叶节点上的某个数据块的那条路径被称为merkle proof,merkle proof存在即数据存在。
3.3.3.证明数据不存在
证明数据存在很简单,但是证明数不存在很麻烦。因为交易可能存在于叶节点的任何位置,所以要验证数据不存在只能把整棵树全部传给轻结点让它自己挨着去找。
原生merkle tree提供不了高效的证明数据不存在的方式,需要用到sorted merkle tree。
将叶节点想办法排序起来,然后将要证明的交易的hash值传拿去进行比较,找到它左右相邻的叶节点,然后沿着这两个叶节点向上找merkle proof,如果merkle proof存在交易就存在,否则交易就不存在。
比特币中因为不需要校验交易不存在,所以没有用到sorted merkle tree。
4.比特币的共识协议
4.1.概述
比特币要达成的共识是这个分布式账本里面的内容,全局需要达成共识、维护它的正确性。实现这个共识,具象化为需要解决两个核心问题:
验证有效性
验证交易的有效性
验证节点的有效性
发行货币
4.2.验证有效性
4.2.1.验证交易有效性
merkle tree的merkle proof只是用于验证数据是否存在,数据写入树就存在,不写入树就不存在,那么每笔新的交易产生的时候,如何判断这笔交易是否应该写入树喃?即验证交易的有效性。验证交易的有效性,需要验证两点:
币是不是够,币都不够肯定交易是不合法的。
意愿是不是真实,假如有一笔交易是A向B转账,需要验证这是不是A的真实意愿。
区块链中采用了以下结构来支持交易有效性的验证:
系统中有两种hash指针和一个签名:
指向前一笔交易的hash指针,用来校验前一个区块的数据是否被篡改。
指向当前交易的货币来源的hash指针,用于方便进行所交易的货币的回溯。
币的来源方的签名,用于验证交易是否是币的来源方的真实意图,核实交易是不是第三方伪造的。
以下简单阐述一下流程:
注意为了简化结构,便于理解,上图每个区块种只有一个交易,实际区块链中每个区块会用merkle tree组织存储多笔交易。
首先是准备动作:
有一个新交易B向F转5个币,货币来源指针指向第二笔交易,另一个hash指针指向前一个交易,为了保证交易的意愿真实,采用了签名机制,区块链中的签名都是非对称加密的,所以需要每次交易由币源方告诉接收方自己的公钥,于是B告诉F自己的公钥。
接下来是验证动作:
首先验证新交易是不是B发起的,沿着货币来源指针找到第二笔交易,通过公钥先验签名。
如果签名合法,再沿着链路从尾到头逆向往第二笔交易回溯验证交易是否合法,发现在第三笔交易的时候B的5个货币就已经用完了,所以新交易不合法,不写入merkel tree中。
这里再说明一下,可以看到货币来源指针很有用,既能用于验签,又能用于确定回溯的范围,避免全局回溯,从而提升性能。
4.2.2.验证节点有效性
1.分布式共识
分布式共识,分布式系统中由于一些意外,集群中各个节点间一定会存在数据一致性问题,区块链采用的分布式架构,自然也存在这个问题,如何保证数据一致性,让全局对数据结果达成一致性认识,这是需要解决的一个问题。
merkle tree只是存储的交易记录,因为存在验证交易是否有效的机制,写进树里面的数据一定是合法的,但是由于网络等诸多原因,可能会存在数据丢失的问题,有的节点上会有些交易并没有被存储,如果验证合法性只询问了一个区块,而询问的区块又正好丢失了这笔交易记录,就会出现误判。或者说这个被询问的区块正好就是个恶意区块,它里面的交易是伪造的,也会造成无中生有的判断结果。所以在区块链中当我们验证交易合法性的时候需要多节点参与进行投票以免这种数据不一致造成的误判。
2.票权
投票在区块链中存在一个致命缺点:
女巫攻击,可以恶意伪造很多携带假交易的块出来,使得投票强行通过,这样即使树里面不存在的交易也能通过这种伪造强行被验证为存在。
由此我们发现投票权是个很重要的东西,有记账权的区块才能有票权,不能说随意新增的区块都有记账权,需要有一个标准来衡量新增的区块是否拥有记账权。在区块链中通过工作量证明来获得记账权:
block header中存储有一个挖矿难度阈值target,这个target由比特币协议生成,全局相同的,每个区块上存的target都相同,每当达到一定的条件后会全局重新调整这个target。
H(block header)≤target,则该区块能被发布。
由于block header中其他值都是固定不能调整的,所以block header中存在一个随机数nonce,通过调整这个nonce不断的去算这个target。
3.最长链原则
区块链中存在这样一种攻击,如果我算出了一个合法块,那么我就可以利用这个合法块的hash和nonce不停的去造新块,使得挖矿变得很容易。为了预防这种攻击,出现了“最长链原则”。
最长链原则,新来的合法区块只能是在扩展最长链才能被接纳入区块链中。这样的话即使有上述的攻击出现,无非以下应对:
因为其他机器也在算,可能有其他机器已经算出来了,所以恶意造出来的新块不一定是在最长链上。
即使最长链上,大家都这样干,也会是算力最强的机器产生的才是最长信任链,然后区块产生速度过快自动会触发调整机制,平衡比特币的收益和target的难度。
所以最长链原则保证了机器一定会根据算力得到回报。
如何确认最长链?有可能多个矿工同时挖出合法的区块。如果出现这种情况,区块链中会暂时维持这种分叉,等这几个矿工自行竞争,看谁先算出下一个合法区块,这样算力高的一定会自成一个最长链,将分叉中最长链纳入区块,其余短链丢弃掉:
4.3.发行货币
矿工挖到矿,发布新的合法节点,被区块链验证纳入后,根据协议矿工会获得一定数量的币,所以新区块的发布也被称为“铸币交易”,铸币交易是币的唯一来源。铸币交易的奖励通常会随着时间的推移而减少。例如,比特币每四年就会减半一次,以控制比特币的总量,直到最终达到2100万个比特币的上限。
5.一些实现上的便捷机制
5.1.未使用的交易输出
区块链中没有地方记录每个账户有多少钱,而是通过计算币源来确定某个账户有多少钱,由于币源以交易记录的方式存在每个区块的merkle tree中的,想知道某个账户有多少钱的时候,需要大面积的进行遍历,然后聚合出结果,效率不是很高,所以需要一个更优的实现机制来提升效率,这个机制就是——没花交易输出,UTXO,unspent transaction output,没有花出去的交易的输出集合,这个集合中存储了所有还没花出去的交易,想知道某个账户的余额的时候只需要遍历UTXO即可。
5.2.交易费用
交易费用,transaction fee,区块链中除了通过挖矿获得记账权而获得的记账奖励外的一种奖励机制,当用户发送交易时需要支付。这些费用支付给网络中的矿工或验证者,他们负责处理和验证交易。这种交易费用用于防止垃圾邮件交易和其他类型的网络滥用。通过要求用户支付费用才能发送交易,更难以使用大量交易淹没网络,从而减缓网络速度或导致其他问题。