声明:本文旨在传递更多市场信息,不构成任何投资建议。文章仅代表作者观点,不代表火星财经官方立场。
边肖:记得要集中注意力。
来源:了解于闯
作者:0x7F@了解于闯404实验室时间:2020年01月09日
原文:https://paper.seebug.org/1110/
0x00前言随着技术浪潮的汹涌和国家政策的推动,区块链慢慢进入了我们的视野。在2020年初的这个时刻,让我们回顾一下区块链的发展,谈谈区块链的几个技术要点,为新的一年打下基础。
2017年是数据货币爆炸年。其标志性事件是2017年12月比特币价格达到历史最高,区块链被引入大众视野;所以2018年被称为区块链元年,各种与区块链相关的数字货币和技术在互联网上如雨后春笋般涌现;后来,随着区块链的监管力度加大,2019年对区块链来说是寒冷的一年。最后,所有经过测试的区块链项目都是有价值的。
那么,在本文中,我们暂且抛开数字货币,仅从区块链方面来谈;用比特币v0.19.x的源码(commit:0655 c 7 a 94 c 9 BF 54d 43 ceed 805 e 83 f1 b 59 e 2409)来帮助你理解。
0x01区块链简介区块链是随着比特币的诞生而诞生的。它最早出现在比特币(https://bitcoin.org/bitcoin.pdf)白皮书中,用于存储比特币的交易记录。在比特币中,多条交易记录按照时间顺序集中排序存储形成块,块之间通过哈希值连接形成链式结构,我们称之为区块链。
在比特币中,多个节点通过P2P网络共同维护一个区块链,使得这种链状结构去中心化、不可改变、可追溯。后续的以太坊、超级账本等项目也是基于这种链式结构。
让我们把数字货币放在一边,看看主角区块链。我们可以更容易理解区块链:区块链是基于P2P的分布式数据库,多个节点共同维护一个数据;从这个角度来说,比特币区块链中存储的“交易记录”也是数据,只是数据比较特殊。
0x02区块链vs分布式数据库我们可以认为区块链是基于P2P的分布式数据库,因为区块链和分布式数据库有一个相似的目标:使用多个节点共同维护一个数据。
但是,我们只理解了“存储”的操作,而忽略了自身的应用场景。默认情况下,所有节点都是可信的、可靠的,并且可以无延迟地通信,等等。在现实中,我们需要考虑上述因素,所以区块链不能等同于分布式存储数据库。
我们使用表格来比较区块链和分布式数据库:
区块链分布式数据库
分布式体系结构
倡导数字信任系统的高性能存储和访问
通信对等客户端-服务器
管理模式集中管理分散管理
结构链索引等。
节点猜疑制约信任与合作。
一致性算法的主从复制
持久数据、不可变数据、可修改的非持久数据
低性能和高性能
了解了区块链和分布式存储数据库的异同后,可以知道分布式存储数据库和区块链都需要解决分布中的问题;区块链也需要解决其独特的问题。所以我们以分布式存储数据库为基础来帮助我们理解区块链中涉及的技术要点。
0x03分布式1中的挑战。FLP不可能原理对于分布式系统中的不确定性,费希尔、林奇和帕特森三位科学家在1985年发表论文,提出了FLP不可能原理:在网络可靠但只允许一个节点失效的最小化异步模型系统中,不存在能够解决一致性问题的确定性算法。
因此,一致性问题在理论上没有完美的解决方案,但在工程应用中,我们可以选择牺牲一些特性来换取一个可行的方案。
2.CAP原则那么我们应该如何选择代价来换取这个可行的方案呢?2000年,Eric Brewer教授在ACM组织的一次研讨会上提出了CAP原理:分布式系统不可能同时保证以下三个特性:一致性、可用性和分区容忍度,在设计中往往需要削弱对某一特性的保证。
根据CAP的原理,我们可以根据不同的需求选择三个特性。如果访问分布式网站的静态内容,可以接受数据的延迟更新,削弱了一致性;在区块链,即使牺牲性能,也必须确保只有一个公认的数据,这削弱了可用性。
3.拜占庭容错在分布式数据库中,节点相互信任,彼此忠诚。他们可能离线、下线,但绝不会发错消息;因此,我们可以信任任何节点。分布式数据库通常使用“主从复制”来实现一致性,即选择一个节点作为主节点,其他节点从这个节点复制数据,如果这个节点出现故障,则重新选择一个新的主节点。
但是在区块链中,节点可以自由加入和退出,可能会出现恶意节点:这个节点可能会离线、宕机,发送错误消息扰乱数据的一致性;这通常被称为拜占庭一般问题。
这是上世纪80年代提出的假设性问题。其中描述道:“一群拜占庭将军各自率领一支军队一起围攻一座城市。因为每支军队都在城市的不同方向,他们只能通过信使互相交流;军队的行动策略仅限于进攻或撤退。一些部队进攻,一些部队撤退,可能会造成灾难性的后果。因此,将军们必须投票达成一致的策略。每位将军通过信使将自己投票信息通知其他将军,这样每位将军就可以知道投票结果,并根据自己的投票和所有其他将军发送的信息决定行动策略。”
上图中,叛军发送的错误投票信息导致的不一致问题称为“拜占庭错误”,能够处理拜占庭错误的方法称为“拜占庭容错”。那么在区块链是如何解决的呢?
0x04一致性算法PBFT算法PBFT(实用拜占庭容错)算法是为了解决拜占庭错误而提出的。算法的核心是三个阶段:预准备阶段(pre-preparation stage)、准备阶段(preparation stage)和提交阶段(commit stage)。我们将理解下图中的算法。
c代表发起请求的客户端,0123代表服务节点,3个节点出现故障,F代表故障节点的数量。
向节点C 0发送请求。节点0向其他服务节点广播请求。在接收到预准备消息后,节点可以选择接受或拒绝该消息。收到消息后,它将准备消息广播给其他服务节点。当节点处于准备阶段并接收到2f准备消息时,它进入提交阶段。向其他服务节点广播提交消息。当一个节点处于提交阶段并接收到2f 1提交消息(包括其自身)时,它向C客户端发送一条消息。当C客户端收到f 1回复消息时,表示共识已经完成。
PBFT中的节点数必须满足N=3f 1的关系,只要节点中失败的节点数不超过1/3,就可以完成一致性判定。由于PBFT算法的特点和性能问题,它经常被用于小规模的联盟链。
PoW算法比特币使用的PoW(工作证明)算法就是工作负载证明算法。算法的核心是利用复杂的数学计算来争夺一次加块的机会,结合“不利原则”和只承认最长的链为合法链的规则,从而完成节点的共识。
在比特币中,PoW的工作方式如下:
用户发起事务,节点广播事务,直到所有节点收到事务包并放入一个块,一个节点计算散列结果,从而获得添加块的机会。将2中的块加到区块链的末尾,广播该块,直到所有节点都收到新的块信息,然后验证该块合法,再加到区块链的末尾,进入下一轮竞争。通过PoW算法,即使全网50%的节点出现错误,比特币依然可以完成共识。
PoW算法的实现PoW算法位于块生成模块(挖掘)。我们先来看看比特币的启动过程。比特币程序入口位于bitcoind.cpp下,比特币中的各种服务都是通过这样一个调用链来启动的:
main-AppInit-AppInitMain
包括RPC服务。在比特币中,我们需要使用bitcoin-cli通过RPC服务开始挖坑,最后到rpc/mining.cpp/generateBlocks生成主逻辑:
其中,pow.cpp/CheckProofOfWork函数通过PoW算法进行验证,主要是判断当前nonce值下,块的hash值是否小于难度值:
然而,由于PoW算法的低性能和计算能力的浪费,许多新的共识算法被提出,如PoS(股权证明),DPoS(主要股权持有人证明机制),等等。但从比特币占区块链项目半壁江山来看,PoW仍然是目前最常用的共识算法。
0x05存储结构了解了共识算法之后,就可以保证数据的一致性了。那么这些数据是如何存储在区块链中的呢?
Merkle Tree在比特币中,Merkle Tree用于组织和存储块内的交易信息。它是基于hash的二叉树(或多分支树),其结构如下:
叶节点存储数据,非叶节点存储其子节点内容的哈希值。使用Merkle树的优点是:
快速对比大量数据,对比根节点的哈希值就知道两组数据是否相同。快速定位和修改,子节点的任何变化都会传递到根节点,从根节点向下搜索就能找到修改的节点。
Merkle树在比特币中实现,Merkle树的生成是挖掘步骤中的一个子步骤。它遵循上述块生成过程中的miner.cpp/IncrementExtraNonce函数,并在该函数中调用consensus/merkle . CPP/blockerkroot函数来构建Merkle树:
在一个块中,哈希链不仅包括打包到Merkle树中的事务信息,还包括块高、随机数、时间等。父块的哈希值链接所有块以形成链结构,如下所示:
哈希链是用比特币实现的。块由块头和Merkle事务树组成。块头的数据结构在primitives/block.h中定义如下:
0x06网络通信在区块链中,节点如何传输数据?与分布式数据库服务器-客户端网络结构相比,数据通过主从复制进行同步,区块链是一种对等网络结构。当一个节点获取数据时,它也需要向其他节点提供数据。
我们直接看一下比特币中p2p协议的实现。
P2p协议是用比特币实现的。默认情况下,tcp监控建立在端口8333上,以启动p2p服务。在bitcoind的init.cpp/AppInitMain启动过程中,网络被初始化并启动:
[init.cpp/AppInitMain()]
node.connman-Start
开始节点进入,网络初始化和建立。
[net.cpp/Start()]
2.初始化绑定
建立网络监控
3.AddOneShot
添加种子节点
4.跟踪线程.
启动五个网络处理线程。
这五个线程负责p2p网络处理流程:
负责p2p协议处理的线程是ThreadMessageHandler线程。我们主要看这部分的流程。尝试从这个线程中的每个节点接收数据,接收到的数据调用如下:
[net_processing.cpp]
进程消息-进程消息
判断ProcessMessages中的协议格式,比特币中的p2p协议格式如下:
然后输入实际消息处理流程的ProcessMessage。在这个函数中,主要逻辑是多个if-else语句根据commmand进入不同的消息处理流程。支持的消息有:
每个命令都有不同的消息格式和处理逻辑。这样比特币就打通了节点之间的通道。
0x07总结通过这篇文章,我们从分布式数据库的角度讲了区块链的几个技术点,了解了区块链和传统分布式的异同,以及区块链的基本概念和原理。
区块链的去中心化和防篡改的特性给我们提供了无限的遐想,但是目前还没有公开完善的区块链项目。我们希望这一天会很快到来。
参考资料:
1.《区块链技术指南》
2.《白话区块链》
3.《区块链原理、设计与应用》
4.https://bitcoin.org/bitcoin.pdf
5.https://101 block chains . com/区块链对比数据库差异/
6.https://groups.csail.mit.edu/tds/papers/Lynch/jacm85.pdf
7.https://medium . com/ultrain-chain/区块链和分布式数据库之间的差异-556f8361e6b3
8.http://pmg.csail.mit.edu/papers/osdi99.pdf
9.https://github.com/bitcoin/bitcoin
10.https://zh.wikipedia.org/wiki/.的拜占庭将军
11.https://www.zhihu.com/question/264717547
转载请注明出处。