区块链技术基础
区块链 blockchain
区块链这个概念为什么最近特别火?
中共中央政治局10月24日下午就区块链技术发展现状和趋势进行第十八次集体学习。总书记在中央政治局第十八次集体学习时强调,区块链技术的集成应用在新的技术革新和产业变革中起着重要作用。要把区块链作为核心技术自主创新的重要突破口,明确主攻方向,加大投入力度,着力攻克一批关键核心技术,加快推动区块链技术和产业创新发展。
埃里克说在前面
区块链是一项极其伟大的创造,之所以这么说,是因为它解决了人类社会诞生以来一直存在的一个问题——“信任”。在生活中,失信的例子随处可见大到金融诈骗,食品安全,小到造谣忽悠,违背承诺。失信会对当事人及受害人造成多层次的伤害。
从第一代区块链的实践可以看到,比特币的匿名性,稳定性,以及强大的生命力令人叹服。
- 正是因为匿名性,使得交易进行的更安全,交易信息不会被泄漏,没有任何机构可以冻结你的资金。
- 在比特币十年运行历史中,只出现了两次共14小时47分钟的宕机时间。
- 即使各国陆续封杀了比特币,但他仍然存在,他的分布式特点使得,只要这个世界上还有一台机器保留了账本,整个系统就可以活下去。
但是这样一种发明,在国内却被污名化了。究其原因,是因为那些假借区块链噱头进行金融诈骗的“空气币”及进行ICO的投机分子。在国内,一提到区块链就等同于各种空气币,等同于金融诈骗,庞氏骗局,人人得而诛之。
引用巴比特的一篇文章
区块链技术很快会被应用到实体经济中并产生价值,而原来各类「空气币」项目会加速淘汰。比特币为代表的传统区块链项目是否能生存仍是个疑问。
引用朋友圈的一句话作为结尾:「上边重视区块链,你们这些打着区块链幌子行骗的高兴什么?历史告诉我们,正规军进山,第一件事情就是剿匪。」
最后,未来充满无限可能。
区块链发展历程
2009年1月 区块链1.0 比特币区块链 加密货币
2015年7月 区块链2.0 以太坊区块链 智能合约
区块链的定义
去中心化的分布式数据库。
区块链作用
- 身份认证个人证明 - 不可篡改性
- 商品全程可溯源 - 不可篡改性
- 反学术造假 - 不可篡改性
- 投票选举 - 不可篡改性
- 版权保护 - 去中心化
- 交易无需第三方 - 去中心化
- 资金不会被冻结 - 去中心化
区块头
区块头里面存储着区块的头信息,包含上一个区块的哈希值(PreHash),本区块体的哈希值(Hash),以及时间戳(TimeStamp)等等。
区块体
区块体存储着这个区块的详细数据(Data),这个数据包含若干行记录,可以是交易信息,也可以是其他某种信息。
哈希值
在区块链中,采用的是SHA256。最新的数据信息经过一系列复杂的计算,最终会通过这个哈希算法转化成了长度为256bit的哈希值字符串,也就是区块头当中的Hash。
区块与Hash是一一对应的,Hash可以当做是区块的唯一标识。
不同的区块之间是依靠Hash和PreHash来关联。每一个区块的PreHash和前一个区块的Hash值是相等的。
为什么要计算哈希值
既然区块链是一个链状结构,就必然存在链条的头节点(第一个区块)和尾节点(最后一个区块)。一旦有人计算出区块链最新数据信息的哈希值,相当于对最新的交易记录进行打包,新的区块会被创建出来,衔接在区块链的末尾。
新区块头的Hash就是刚刚计算出的哈希值,PreHash等于上一个区块的Hash。区块体的Data存储的是打包前的交易记录,这部分数据信息已经变得不可修改。
如果区块的内容变了,它的哈希一定会改变。
去中心化
区块链不依赖于某个中心节点,整个系统的数据由全网所有对等节点共同维护,都可以进行数据的存储和检验。这样一来,除非攻击者黑掉全网半数以上的节点,否则整个系统是不会遭到破坏的。
信息不可篡改
区块内的数据是无法被篡改的。一旦数据遭到篡改哪怕一丁点,整个区块对应的哈希值就会随之改变,不再是一个有效的哈希值,后面链接的区块也会随之断裂。这一点对区块链有重大意义。如果有人修改了一个区块,该区块的哈希就变了。为了让后面的区块还能连到它(因为下一个区块包含上一个区块的哈希),该人必须依次修改后面所有的区块,否则被改掉的区块就脱离区块链了。由于后面要提到的原因,哈希的计算很耗时,短时间内修改多个区块几乎不可能发生,除非有人掌握了全网51%以上的计算能力。
哈希的特点
哈希函数作为一种加密函数,其拥有两个最重要特点:
- 不可逆性。输入信息得出输出的字符串(哈希值)非常容易,但是从输出的字符串反推出输入的结果却是却非常非常难。
从数学理论上来讲,函数都是可逆的,知道输出结果和函数关系,一定可以推出输入值。而现在计算机所采取的方法就是暴力破解(彩虹表),采取枚举的方法,一个一个试(哈希碰撞),直至试出正确的结果。
- 输出值唯一性和不可预测性。只要输入的信息有一点点区别,那么根据哈希算法得出来的输出值也相差甚远。
哈希值的计算
Hash = SHA-256(最后一个区块的Hash + 新区块基本信息 + 交易记录信息 + 随机数)
其中,交易记录信息也是一串哈希值,它的计算涉及到一个数据结构 Merkle Tree。
这里关键的计算难点在于随机数的生成。区块链发明者为了增大Hash的计算难度,要求Hash结果的前72bit必须都是0,这个几率实在是太小太小。
哈希值计算难度
由于(最后一个区块的Hash + 新区块基本信息 + 交易记录信息)是固定的,所以能否获得符合要求的Hash,完全取决于随机数的值。挖矿者必须经过海量计算,反复生成随机数进行“撞大运”一般的尝试,才有可能得到正确的Hash,从而挖矿成功。
同时,区块头内还包含着一个动态的难度系数,当全世界的硬件计算能力越来越快的时候,区块链的难度系数也会水涨船高,使得全网平均每10分钟才能产生出一个新区块。
区块头包含一个难度系数(difficulty),这个值决定了计算哈希的难度。
区块链协议规定,使用一个常量除以难度系数,可以得到目标值(target)。显然,难度系数越大,目标值就越小。
哈希的有效性跟目标值密切相关,只有小于目标值的哈希才是有效的,否则哈希无效,必须重算。
为了将产出速率恒定在十分钟,中本聪还设计了难度系数的动态调节机制。他规定,难度系数每两周(2016个区块)调整一次。如果这两周里面,区块的平均生成速度是9分钟,就意味着比法定速度快了10%,因此接下来的难度系数就要调高10%;如果平均生成速度是11分钟,就意味着比法定速度慢了10%,因此接下来的难度系数就要调低10%。
哈希值中的随机数 Nonce
当前区块的哈希由区块头唯一决定。如果要对同一个区块反复计算哈希,就意味着,区块头必须不停地变化,否则不可能算出不一样的哈希。区块头里面所有的特征值都是固定的,为了让区块头产生变化,中本聪故意增加了一个随机项,叫做 Nonce。
Nonce 是一个随机值,矿工的作用其实就是猜出 Nonce 的值,使得区块头的哈希可以小于目标值,从而能够写入区块链。Nonce 是非常难猜的,目前只能通过穷举法一个个试错。根据协议,Nonce 是一个32位的二进制值,即最大可以到21.47亿。
什么是挖矿
这个计算Hash值,创建新区块的过程就叫做挖矿。
用于进行海量计算的服务器,叫做矿机。
操作计算的工作人员,叫做矿工。
为什么要挖矿
任何人都可以随时加入区块链系统,读取/更新/记录账本,只要解题的速度够快且准确,就可以争取到比特币作为奖励(我们这里只用比特币的工作机制举例)。
51% (优势) 算力攻击
攻击者通过优势算力,挖掘一条比原链更长的攻击链。
攻击链向全网广播后,节点按规则,将接受更长的链,丢弃原链。
比特币网络中只有拥有超过51%的算力才能破坏网络安全,如果单纯破坏的话,会浪费自己的大量资源,收益可能并不高于成本。
所以区块链的安全是基于利益驱动的,即每个个体都是趋向于利益最大化的。
区块链的分叉
如果两个人同时向区块链写入数据,也就是说,同时有两个区块加入,因为它们都连着前一个区块,就形成了分叉。这时应该采纳哪一个区块呢?
现在的规则是,新节点总是采用最长的那条区块链。如果区块链有分叉,将看哪个分支在分叉点后面,先达到6个新区块(称为”六次确认”)。按照10分钟一个区块计算,一小时就可以确认。
由于新区块的生成速度由计算能力决定,所以这条规则就是说,拥有大多数计算能力的那条分支,就是正宗的区块链。
如何解决拜占庭将军问题
工作量证明系统(Proof-of-Work,PoW)主要特征是众多参与节点需要做一定难度的工作得出一个结果,谁先得出立即全网广播,其他节点很容易通过结果来检查出之前节点是不是做了相应的工作,一旦结果被证明正确,其他节点会把之前节点的结果添加到各自的账单中,为争取下一笔的交易记录做好计算的准备。
沿用比特币的工作机制,将军A在互联网上先发布了一个消息“进攻”并附上了自己的签名“将军A” 。
将军A的消息被其他节点收到,如果其他将军也打算进攻,则在将军A的消息后面跟上自己的信息,以此类推。当此类消息达到十个,他们必将堵上未来,一同发起进攻。
这时也会出现一种情况,将军A发出消息后,可能会有两个或多个将军同时跟上消息,这时,各个节点会严格按照广播的精确时间进行排序,确保一条链的完整性。
也有完全同时广播出来的情况,这时就是区块链的分叉,出现一个分开的两条链,之后,哪条链上添加的账本多(共识多),哪条就成为主链,另一条分叉链就此中断或被部分矿工认可继续添加(如:以太坊和以太坊经典)。
之所以能够达成统一的共识,认可这一账本,最终是因为利益驱使。
墨克树 Merkle tree
Merkle Tree可以看做Hash List的泛化(Hash List可以看作一种特殊的Merkle Tree,即树高为2的多叉Merkle Tree)。
在最底层,和哈希列表一样,我们把数据分成小的数据块,有相应地哈希和它对应。但是往上走,并不是直接去运算根哈希,而是把相邻的两个哈希合并成一个字符串,然后运算这个字符串的哈希,这样每两个哈希就结婚生子,得到了一个”子哈希“。如果最底层的哈希总数是单数,那到最后必然出现一个单身哈希,这种情况就直接对它进行哈希运算,所以也能得到它的子哈希。于是往上推,依然是一样的方式,可以得到数目更少的新一级哈希,最终必然形成一棵倒挂的树,到了树根的这个位置,这一代就剩下一个根哈希了,我们把它叫做 Merkle Root。
在p2p网络下载网络之前,先从可信的源获得文件的Merkle Tree树根。一旦获得了树根,就可以从其他从不可信的源获取Merkle tree。通过可信的树根来检查接受到的Merkle Tree。如果Merkle Tree是损坏的或者虚假的,就从其他源获得另一个Merkle Tree,直到获得一个与可信树根匹配的Merkle Tree。
Merkle Tree和Hash List的主要区别是,可以直接下载并立即验证Merkle Tree的一个分支。因为可以将文件切分成小的数据块,这样如果有一块数据损坏,仅仅重新下载这个数据块就行了。如果文件非常大,那么Merkle tree和Hash list都很到,但是Merkle tree可以一次下载一个分支,然后立即验证这个分支,如果分支验证通过,就可以下载数据了。而Hash list只有下载整个hash list才能验证。
Hash List
在点对点网络中作数据传输的时候,会同时从多个机器上下载数据,而且很多机器可以认为是不稳定或者不可信的。为了校验数据的完整性,更好的办法是把大的文件分割成小的数据块(例如,把分割成2K为单位的数据块)。这样的好处是,如果小块数据在传输过程中损坏了,那么只要重新下载这一快数据就行了,不用重新下载整个文件。
怎么确定小的数据块没有损坏哪?只需要为每个数据块做Hash。BT下载的时候,在下载到真正数据之前,我们会先下载一个Hash列表。那么问题又来了,怎么确定这个Hash列表本事是正确的哪?答案是把每个小块数据的Hash值拼到一起,然后对这个长字符串在作一次Hash运算,这样就得到Hash列表的根Hash(Top Hash or Root Hash)。下载数据的时候,首先从可信的数据源得到正确的根Hash,就可以用它来校验Hash列表了,然后通过校验后的Hash列表校验数据块。
关于版权
本文内容部分来源于网络(知乎 CSDN 简书),但由于内容来源未注明出处且不一定原创,所以我无法对引用内容来源进行声明,若此文中内容侵犯了您的版权,烦请您联系我以便立即删除相关内容,感谢您的理解与支持!