本文是基于我在 360 区块链开放日上的分享整理完善而成,演讲时有些逻辑没有讲明白,感觉用文字表述可能更好一些。作为自己区块链系列的开篇第一篇,谈谈怎么从技术的角度理解区块链。
说到区块链技术分享,区块链相关的各种技术词汇就纷至杳来。区块链领域是一个喜欢造新词的领域,这也给想了解这个领域技术的人造成了门槛。我一直想梳理下区块链的技术演进逻辑,试图从互联网技术的发展角度来解释区块链技术,这样可以让互联网领域的技术人更容易理解区块链。
技术有没有世界观?
技术本身的目标是对现实抽象和建模,所以技术实际上有自己对世界的理解和假设。比如编程范式里的面对对象和函数式编程,有完全不同的世界观理解。而区块链对世界是一种怎么样的抽象呢?
我们还是从萧伯纳那句名言开始。
- 你和我各有一个苹果,如果我们交换苹果的话,我们还是只有一个苹果。但当你和我各有一个想法,我们交换想法的话,我们就都有两个想法了。
— 萧伯纳
这句话也被很多人用来解释区块链以及互联网的区别。交换苹果代表价值交换,交换想法代表信息交换。信息交换可以保留多个副本,但价值交换就不行。所以流行的一个说法是:
- 互联网-信息交换
- 区块链-价值交换
但是交换信息就不需要考虑价值了么?其实也不是,毕竟贡献想法也是需要激励机制的。现在的互联网就没有价值交换了吗?区块链不也是在信息世界的吗?本质的问题实际是:
如何在信息世界进行价值交换?或者说如何通过交换信息的方式进行价值交换?
这个问题其实也不是一个新问题。在没有互联网的时代,人类就在尝试。比如各国都普遍实行的不动产登记制度。你买房买的是房子的控制权吗?或者说买房的时候你住进去就算买到了吗?实际上不是,要不动产登记账本变更后才算,这个登记变更实际上就是信息交换。无论这个账本是原来的纸质账本,还是变成计算机的数据库,甚至再到未来的区块链,载体变了本质上是没变的。再比如银行的财产登记,股票交易所的股票登记,都是一个道理,如果说货币还有纸币这种物理实体代表,股票则是纯信息化的,没人见过股票长什么样子吧。
所以总结一下,信息世界进行价值交换的唯一方式是统一的账本,并且对这个账本的要求是它必须是一个公共知识(common knowledge),可以简单理解成大家常说的共识。唯有这样,信息的副本才不会生效,比如黑客即便是黑了交易所复制了数据,也不可能重新搭建出一个交易所来让大家交易。至于如何达成这样的共识,是通过市场竞争,还是依赖权威机构,这里暂不讨论。
现在区块链来了,要搞去中心化账本。去中心化这个词是个热词,网上一直争论不休。由于时间关系这里不进行详细阐述,等有机会单独写文章阐述。这里只简单说明下我个人思考的去中心化的两个方面:
- 账本用户侧去中心化 这个是从用户侧的准入机制上考量,比如传统媒体只有专业媒体人可以发布内容,到互联网门户,再到微博微信公众号等自媒体,本质上也是一种去中心化的过程。
- 账本供给侧去中心化 这个是从账本的供给角度考量。比如还是前面的例子,传统媒体有很多,各种报纸杂志,挂一个媒体影响不大,到门户时代就少了,再到现在基本就剩下几个平台了,挂一个平台影响就大了。那现在能不能再反过来,同一个账本由多个供给方一起提供?这样就兼具二者优势了。区块链主要关注的是这个方向。
至于为什么账本会向去中心化账本演进,动力在哪里,这里就不展开了。先从技术演进角度来理解一下,从中心化的账本到去中心化账本之间的技术演进过程。
账本架构演进之路
我总结了这样一个演进过程:
单数据库账本
这个架构图做互联网应用的朋友应该看起来很亲切。早期的企业以及互联网应用都是这个样子的,应用界面面向最终用户,应用本身的程序封装了业务逻辑,应用状态直接存储到数据库中。这时候关注的账本相关技术主要是『事务』。通过数据库提供的事务机制,保证了账本的原子性操作。
分布式数据库账本
当单机数据库无法承载读写或者数据的时候,就有了分布式数据库。分布式数据库的数据分散到了不同的节点,通过分片以及多副本来解决上述问题。但同时带来的问题是如何保证同一个分片在不同节点的数据的一致性以及跨节点的分布式事务。这时候账本相关技术主要是『分布式共识算法(paxos,raft ),分布式事务』。分布式事务由于其复杂性,分布式数据库不一定能够提供,很多情况需要在业务逻辑里处理。
多机房账本
随着账本越来越重要,异地副本都不能满足需求,需要异地多活了,于是有了多机房方案。多机房方案里,不同的机房之间需要同步数据,并且保证一致性。这时候账本技术的挑战主要是『跨机房分布式共识算法,应用状态的复杂性』。前者是说分布式共识算法需要考虑更复杂的网络场景,后者是说大部分应用的状态维护比较复杂,不仅仅在数据库中,只是通过一个跨机房复制工具把数据库状态复制过去,是很难应对多机房应用场景,实际上需要应用架构的改变。
多运营方账本
上面的账本都只考虑同一个主体运营维护的场景,内部的信任较高。但如果是多方共同维护一个账本的场景,也就是上一个方案的不同机房其实属于不同的主体。这样的场景下,另外一方无法直接信任应用的最终状态,所以在不同机房同步的不能是应用的状态,而是应用的 Event(事件)。无论是本机房用户写操作的 Event 还是从其他机房同步过来的,都需要经过业务逻辑校验处理后再变更应用状态。这实际就是 EventSource/CQRS 的架构,也是很多联盟链的架构。多机房场景下其实也会用这种架构,主要区别是在对从其他机房同步过来的 Event 的信任度。这时候,账本技术的挑战除了跨机房分布式共识算法,还有共识算法和业务逻辑融合。在前面场景里的共识算法,基本只关心数据,不关心业务,共识算法只保证数据的一致性,并不保证数据在业务场景下的合法性。但在这个场景下,共识算法要保证只对合法的数据达成一致,二者融合了。无法直接沿用上面几种分布式共识算法,需要考虑作弊情况的共识算法,比如 BFT 这样的。
有人会问,有什么动力要将同一个账本交给多个运营方呢?那我们拿互联网电商来说明这个场景。当前的电商,一方面对接商家和商家的库存管理系统,另外一方面对接银行和快递系统,以及最终用户。一个商品,从库存管理系统,到电商平台,用户购买后,从银行扣钱,发送快递,实际上是同一个账本上的信息在不同的运营方系统之间的同步。当前的实现方式是通过远程调用或者商家和用户介入手工操作。那不同的账本之间如何保证一致性呢?只能定时对账清算,因为远程调用本质上只是信息传递,无法保证一致性。如果这时候有个多方共享的账本,架构就会像上面那样,不仅架构更优雅,同时结算效率会更高。
关于联盟链的技术架构以及模式的更详细分析,我会在下一篇文章中细说。
去中心化账本
去中心化账本这个概念没有非常准确的定义,但我们这里可以简单的理解成 Peer to Peer 网络 + 账本。Peer to Peer 网络的特征是无准入机制,给人的印象也是不可靠,更不追求一致性,而账本是要追求一致性的。比特币创造性的把二者结合起来。所以一般所说的去中心化账本,或者公链,关键一个特性就是无准入机制。
之前的账本都是有准入机制的,并且账本本身的运营成本以及收益通过系统外的机制来解决,那如果去掉准入限制,同时账本的运营成本以及收益也通过账本系统内置的机制来调节,会有哪些新的挑战?
- 如何激励生产者?生产者为什么提供服务器资源?如何度量生产者的工作?
- 如何实现一致性?无准入机制的情况下,节点数不确定,随时加入退出,无法用 BFT 这样的投票共识算法。
- 如何防攻击?比如生产大量数据(DoS攻击),伪造大量节点(女巫攻击)。有了激励就有了攻击和作弊的利益动机,传统的 Peer to Peer 网络没有激励,一般人也不会做损人不利己的事情。
下面我们通过几个公链是来分析上面的问题。
Bitcoin: A Peer-to-Peer Electronic Cash System
比特币首先带给我们的是一套内生的激励机制。虽然比特币到底应该理解成货币,还是数字黄金,还是股票,大家争论不休。这里我们把比特币设想成一个创业公司,这个创业公司要做一个记账交易系统。于是它发行了2100万股,发行规则直接写到了这个记账系统的代码中,分期释放,奖励给给这个系统提供运行资源的人。而用户拿什么来交易呢?也用它的股票来做交易媒介。这样它就实现了软件系统在经济上的自举,也带给软件系统一种能力:在程序算法中引入经济博弈机制。
Proof of Work
PoW 到底应该算是激励的评估机制,还是共识算法,还是反 DoS 策略?实际上它兼具多种功能。所以这也是公链的共识算法和传统分布式共识算法的差异之处,容易让人迷惑。
最早应用 PoW 的是 hashcash,它的主要目的就是通过 PoW 来实现邮件的反垃圾,关键点是通过 PoW 制造额外成本,这样发邮件少的用户可以接受成本,但发垃圾邮件的用户就很难承担这样的成本。
同时,有了成本也就可以作为贡献的评估标准,Proof of Work 这个词,顾名思义,就像是一个工作的评估机制。运行比特币系统,需要机房,机器,带宽等,如何通过程序来评估资源提供者的工作呢?比特币的做法就是算哈希函数,要求算出来的哈希值小于一个难度。虽然简单粗暴,但它难计算,易验证,是一种可行的办法。
中本聪共识(Nakamoto Consensus)
只有 PoW 是无法实现一致性的,需要再加上其他的一些策略,统称为中本聪共识。
- 内置的校验机制(包括 hash 难度校验,merkle 校验,链式关系校验,UTXO 校验等),每个区块只认可通过校验的合法区块,拒绝非法区块。
- 最长链选择 如果由于网络延迟造成软分叉,每个节点应该在最长的一条链上继续工作。
- 如果有节点试图违反以上规则,则会带来经济成本(自己挖出的块不合法被拒绝,在短链上的工作不被认可等),通过经济上的博弈实现防作弊。
中本聪共识的特点是无交互,纯异步,每个节点只需要按照内置的规则处理即可,无需和其他节点交互协调。
区块与链式结构
比特币带来的区块与链式结构,也是区块链这个名字的由来。但区块和链式结构是必须的吗?真的存在一条这样的全局链式结构吗?实际上区块只是一种为了降低网络开销的批量操作,链式结构的主要目的是建立一种时间上的依赖关系,即便两个交易本身不相关,但由于链式结构的存在,后面的交易实际上给前面的交易做了背书,增加了篡改和回滚的成本,因为一旦想要撤回前面的交易,必然也会影响后来的交易。这种结构和关系只是共识协议的一部分,并不存在这样一个全局的结构,具体每个节点如何保存数据,是节点自己决定的。链式结构虽然存在分叉,但只要配合共识机制,最终可以选择出一条唯一的链,达到最终一致性。也就是说,只要能达到这个目标,区块和链式结构并不是必须的,也没必要因为这个名字纠结什么是真正的区块链。
UTXO 与 MerkleTree
UTXO 本身是一种复式记账法。比特币的定位是数字货币,UTXO 属于它的账本业务逻辑。这种记账法的好处是任何一笔交易都可以回溯到创币交易,保证货币只能由创币交易产生,无法凭空产生。如果只是货币场景,UTXO 确实比 Account 模型要安全,但如果考虑到其他应用场景,应用的状态就很难设计出一种 UTXO 模型来追踪变更,这也是为什么后来的面向应用的链放弃 UTXO 的原因。
比特币通过 MerkleTree 提供交易证明,方便没有全量账本的轻客户端校验交易。但比特币的 MerkleTree 是每个账本一个,没有全局 MerkleTree,也就是说没办法提供全局证明,轻客户端的实现就会比较复杂。这方面比特币社区也讨论很久,详情可以参看我以前的一篇文章:《谈谈区块链的 UTXO 证明》。后面会谈到 Ethereum 的改进。
Bitcoin Script
比特币的 Script 可以理解成一种支付校验逻辑的扩展能力。前面说了,去中心化账本的业务逻辑和共识机制融合在一起了,支付校验本身也属于业务逻辑。这种逻辑的变更会影响共识,进而可能导致硬分叉,而提供一种可自定义逻辑的脚本,则是一种兼顾的策略。
同时,比特币的这种能力也给后来的染色币(Colored Coin)提供了机会。本来比特币的账本只能记录比特币的交易,但有了 Script 后,可以在 Script 嵌入自定义数据结构,可以理解成对比特币账本的数据扩展。染色币就利用这种机制来制造新的加密币。
这种机制的好处是染色币不需要重新构建一个去中心化的账本网络,降低了时间以及经济成本。但缺点也很明显,一方面,这种目的毕竟不属于比特币的初始设想,得不到更多支持,另外一方面,比特币 Script 只能嵌入数据,无法嵌入对这种数据的校验逻辑,校验逻辑还需要通过部署独立的节点程序来实现。
于是这种需求背景下,以太坊产生了。
Ethereum: A Decentralized Platform that runs Smart Contracts
以太坊的设想是既然运行一个去中心化账本成本这么高,那能不能先运行一个通用的账本,然后提供机制允许用户在上面自定义业务逻辑?所以它的目的不是数字货币,而是运行『智能合约』的平台。如果说以太坊当前的 PoW 共识机制等只是在比特币 PoW 基础上的优化改良,它的最关键的创新就是智能合约和 Global State Trie。
智能合约
这里顺便扯一下对『智能合约』的看法。很多批评『智能合约』的人说这只是一种脚本程序,并不智能。那这样说智能手机(Smart Phone)哪里智能了?智能家居,智能手表,智能xx不都一样?中文领域里把 Smart 和 Intelligence(Artificial Intelligence,AI 人工智能) 都翻译成智能,确实造成混淆。但这是历史遗留问题了,纠结这个名字没有意义。
于是以太坊提供了一种图灵完备的脚本语言来定义业务逻辑,交易数据中明确允许嵌入自定义数据结构(以太坊 transaction 的 data 字段),链不关心合约本身的逻辑,只是通过在不同的节点重复运行合约,来保证合约的输出是确定的。它和比特币的 Script 的差异不仅在是否图灵完备,更大的差异在于自定义数据和自定义逻辑的结合。染色币这样的场景,它同时托管了染色币的账本数据和交易逻辑,于是引来了一场发币的热潮。它这种机制带来的挑战是不同的场景的业务逻辑的输入输出不一样,如何存储和维护?如何提供证明?
于是它创造性的引入了 Global State Trie。
Global State Trie
以太坊的黄皮书中通过一个公式来定义以太坊。
σt+1≡Υ(σt,T)这个公式中的 σ 代表以太坊的状态,Υ 代表处理函数(包括合约以及内置的 Ether 交易逻辑),T 代表交易(包含调用合约的交易), t+1 的状态等于处理函数在 t 状态基础上处理 T 的执行结果。
而这里的状态的程序表达形式就是一个 Merkle Patrica Trie。
这是一个两层的 Trie,第一层的叶节点上保存的是每个 Account 的余额(Balance),以及针对合约 Account 的 CodeHash 和 Storage root。Storage root 是另外一个 Trie 结构,叶节点是合约内部的状态。任何一个 Account 的余额或者合约状态变更,都会导致 Global State Root 变更,而每个区块都会在区块头上带上当前区块中的 Transaction 执行完后的 State Root 。
这样,一方面提供一种全局校验机制,只要比较 State Root 就可以快速知道不同节点的状态是否一致,这个和 Git 中引入 Merkle hash 证明机制的原理是一样的。Linus 一次分享 Git 的时候也说了,Git 的这种机制可以让他方便的信任来自第三方保存的代码。有了这套机制后,新节点同步的时候可以信任一定区块以前的全局状态,而不是完全通过区块回放来重新构建。这也回答了我们前面提出的那个问题,如何快速校验不同机房的数据状态一致性。
另外一方面,它也提供了一种单个账号状态和全局状态关系的证明能力,可以通过 Merkle Path 证明一个账号的当前状态和全局状态之间的关系,轻钱包实现就会更容易。
如果纯粹从模型看,以太坊已经是一个非常理想的模型了。大家常说程序就是数据结构加算法,它既提供了数据结构的自定义以及存储能力,也提供了算法的计算环境,理论上任何程序都可以放上去运行了。但套用一句俗话,理想是丰满的,现实是骨感的,这样的全球分布式账本的存储和计算成本太高了,稍微复杂的应用都很难运行起来。
EOS:The most powerful Infrastructure for Decentralized Applications
EOS 自项目启动开始,主打的旗帜就是吞吐和性能。如果说比特币和以太坊两个项目带有一种理想主义特质,EOS 则带有非常明显的实用主义特质。
前面说到,Peer to Peer 网络的问题是无准入,节点数不固定,匿名情况下防作弊成本高。EOS 的 DPoS 思路就是通过投票选举,让参与共识的节点在一定时间内保持稳定,同时通过竞选机制,让竞选节点不再匿名,降低防作弊的成本,然后把注意力集中到吞吐以及应用模型的改进上。
互联网应用开发者看了 EOS 的应用模型后,会感觉更容易理解。看它的 ABI 描述文件,第一眼的感觉就像是在定义应用表结构。它交易结构中直接嵌入的是 Message,相当于 EventSource 架构中的 Event。以太坊的链上还保留了 Ether 本身的交易逻辑,而 EOS 上 EOS Token 本身也是通过合约实现的,只是合约分为系统合约和用户应用合约,整个链成为了一个更纯粹的合约执行平台。
EOS 中没有 Global State Trie,这个问题 Vitalik 和 BM 争论过很多次,这代表了两种不同的思维方式,感兴趣的人可以找来看看,我个人是同意 Vitalik 的看法的。
EOS 另外两个值得关注的点是它的经济模型以及链上治理模型。它试图提供免费的交易,但毕竟资源有限,所以通过其他限制来替代交易费模式。链上治理带来的启示是,大家常说的共识到底包含哪些方面?代码中的共识逻辑?最终的一致性账本?社区的用户选择是否也可以沉淀到链上,以解决分歧以及约束区块生产者(矿工)?
到底需要多少去中心化账本?
前面我们分析了账本的架构演进以及几条典型的公链。如果说比特币是一个区块链应用的演示,以太坊和 EOS 则可以看成应用实验平台。那到底世界需要多少去中心化账本?多少条公链?通用公链的扩展性困境不仅仅来自技术层面的容量和吞吐,同时也来自应用方向。做一个有无限可能的链,还是一个和具体业务逻辑绑定的链?是新链开发者必须要面临的选择。
当前的情况下,通过分片来解决扩展性(容量和吞吐)问题的复杂度过高,短期很难落地,于是社区提出了分层的概念。
Layer2 的道理很简单,也符合大家的认知常识。不同的账本需要的安全级别以及共识范围是不一样的,没必要每个交易都需要全球共识。但关键是怎么做到呢?
它的核心思路是通过 Layer1(链层)提供的机制来约束 Layer2,具体方案可分为两种:
状态通道(比如闪电网络)顾名思义,它主要是两个人之间的一个通道,相当于两个人之间的一个账本。因为每个账本只有两个人,所以账本上只需记录每个人的最终状态,无需记录每次交易,最后按最终状态分账就行,没有直接通道的用户之间可以通过路由中转的方式来进行交易。链提供机制,避免作弊以及不合作风险,具体安全策略这里不详述,有兴趣的朋友看我的视频10分钟理解闪电网络以及区块链二层解决方案的原理。
多方链下账本 如果是多个人之间可以直接互相交易,又不希望建立过多通道(成本原因),就只能通过维护一个多人的共同账本来实现了。这个账本也必须找到托管方,但关键是如何保证安全。我们传统的账本安全其实是靠审计,用户以及第三方监督等机制实现,那能不能把这套机制也在链上实现?链用来公示以及争议裁判(双方需要提供证明,程序自动判决),用户和账本托管方互相监督,再或者引入其他托管方把账本变成一个联盟链。
关于 Layer2 的各种方案的探索,至少给我们展示了一个可能,就是各种账本之前并没有泾渭分明的界线,会有机制将它们混合在一起,共同形成价值网络,后面会写再文章单独分析。
总结
本文整体从账本的作用以及架构演进来阐释区块链。阐释区块链的方式有很多种,我这里主要以技术演进的角度进行。
早就想写一个系列,谈谈区块链,但年初的时候区块链鼓吹者甚多,作为一个技术人,完全插不上嘴。最近熊市,冷清了许多,连区块链是一种落后技术的言论都出来了,于是决定写一写。
区块链绝对不是一种落后的技术,而是一种更优秀的分布式系统。同时它带来的技术挑战和契机也非常大,以前我们主要关心数据如何计算以及存储,区块链时代我们更要关心如何证明,从存储到计算整个体系都会有变革的契机。
同时,它引入了经济体系,以及链上治理机制,有超越技术的深远的影响,不过这个话题就更大了,我会在另外的文章中探讨。