区块链技术综述

  纸上谈兵

Posted by xuguangjin on March 2, 2017

货币历史

The Times 03/Jan/2009 Chancellor on brink of second bailout for banks

纽约时间2008年10月31日下午2点10分,中本聪向一个密码学的邮件组发出了他那封宣告比特币诞生的邮件,并附上了比特币的相关论文。想要了解区块链,就必须从区块链上的第一个应用比特币说起。既然比特币作为一种货币,那我们就不得不先来关注下货币的历史和特性。

黄金天然不是货币,但货币天然就是黄金。在贵金属垄断货币地位的年代,贵金属与货币完全是等价物。由于这种货币来源的局限性(金矿银矿的稀缺),大多数国家面临的问题并不是今天人们经常看到的通货膨胀,而是货币稀缺导致的通货紧缩。后来货币由实物货币发展为信用货币,纸币依靠贵金属的背书才能赢得信任而实现流通。二战后美国利用自己的超级大国地位建立布雷顿森林,以黄金储备为美元背书,并强制以美元为其他国家货币背书,希望通过这种金融手段彻底的控制世界。

由于黄金产量有限,且二战后的各国的快速复苏,使美元相对于黄金的超发成为必然,各国为了防止美元的贬值而纷纷向美国挤兑黄金,最终导致美国政府放弃金本位制度,从此金本位彻底退出了货币舞台。没有了金本位的限制,各国央行就有了更足的底气进行货币超发,并以各种各样的名字来命名这种损不足而补有余的行为,如量化宽松,逆回购等等。

货币已经成为人类社会运行的必不可少的一项元素,而且一直在随着社会的发展而前行。但随着近几十年来不断爆发出的种种金融危机,人们越来越认识到当今的货币体系存在种种问题,但尾大不掉,难以动摇。如今让普通百姓最大的痛点莫过于央行过于任性的印钞行为。中本聪的比特币里很有趣的一点便是:比特币以技术为保证永远不会超发。下面是中本聪的邮件里提到的比特币的几个重要属性:

  • 以点对点的网络避免双重支付
  • 没有央行,也没有其他可信任机构
  • 参与者可匿名
  • 货币通过基于hashcach的工作量证明(proof-of-work)的方式产生
  • PoW还能使整个系统避免双重支付的潜在风险

下面我们来看下这些特性是如何实现的

区块链的技术基石

If I have been able to see further, it was only because I stood on the shoulders of giants

区块链里的很多核心技术并非中本聪首创,这里就不得不谈到一个略显神秘的团体:密码朋克(CypherPunk)。这个团体是密码天才们的松散联盟。在比特币的创新中,大量借鉴了密码朋克成员的贡献。密码朋克本身就是数字货币最早的传播者,在其电子邮件组中,常见关于数字货币的讨论,并有一些想法付诸实践。在比特币之前,有很多失败的尝试。在这里我们简要列举一些之前探路者。[1]

  • 亚当·贝克(Adam Back)是一位英国的密码学家,1997年,他发明了哈希现金(hashcash),其中用到了工作量证明机制(proof of work)。这个机制的原型是用于解决互联网垃圾信息问题的。工作量证明机制后来成为比特币的核心要素之一。

  • 哈伯和斯托尼塔(Haber and Stornetta)在1997年提出了一个用时间戳的方法保证数字文件安全的协议,这个协议成为比特币区块链协议的原型。

  • 戴伟(W Dai)是一位兴趣广泛的密码学专家,他在1998年发明了B-money,B-money强调点对点的交易和不可更改的交易记录。不过在B-money中,每台计算机各自单独书写交易记录,这很容易造成系统被账本的不一致。戴伟为此设计了复杂的奖惩机制以防止作弊,但是并没有能从根本上解决问题。中本聪发明比特币的时候,借鉴了很多戴伟的设计,并和戴伟有很多邮件交流。

  • 哈尔·芬尼(Hal Finney))是PGP公司的一位顶级开发人员,也是密码朋克运动早期和重要的成员。2004年,芬尼推出了自己版本的电子货币,在其中采用了可重复使用的工作量证明机制(RPOW)。哈尔·芬尼是第一笔比特币转账的接受者,在比特币发展的早期与中本聪有大量互动与交流。由于身患绝症,哈尔·芬尼已于2014年去世。

名词解释一:工作量证明 & 哈希现金

And so, my fellow Americans, ask not what your country can do for you; ask what you can do for your country.

PoW(Proof-of-work,工作量证明)是一个经济学名词,简而言之,就是想得到,先付出。这套系统一般用来应对垃圾邮件或DoS攻击,其中有两个角色:工作者和验证者,两者需要具有以下特点:

  • 工作者需要完成的工作必须有一定的量,这个量由工作验证者给出。
  • 验证者可以迅速的检验工作量是否达标。
  • 工作者无法自己”创造工作”,必须由验证者发布工作。
  • 工作者无法找到很快完成工作的办法。

hashcash作为一套典型的PoW解决方案,被应用于反垃圾邮件的工作中。垃圾邮件的特征是,发送邮件方可以几乎无成本的将邮件批量发出。如果能够引入成本,比如对cpu的消耗,就能极大降低垃圾邮件的发送速度。当然引入成本之后,正常用户发送邮件也会增加成本,但只要成本在一定范围内,比如1到2秒,那正常用户收到的影响就是可接受范围内的(毕竟写一封邮件花的时间比这个长多了)。具体的方式如下:

1、 邮箱服务器要求发件方提供一个签名(hashcash),签名的对象包括收件人地址,发送时间和一个counter,counter的来源是任意数字。签名算法是sha1
2、 sha1的签名结果是160bit的二进制串,服务器方强制要求结果里前20位必须是0.
3、 由于sha1的hash结果完全随机,发件方在发件前就开始以穷举的方式去寻找符合要求的counter,找到后将这个签名附在邮件里提交给服务器方(需要寻找xxxx次)
4、 服务方收到邮件时首先根据对方提供给的收件人地址、发送时间、counter去验证hash是否正确,正确则继续执行,失败则丢弃。(只需要验证一次)

关于sha1是否一定可以获得前20位为0的结果,这里不再详细描述。本节主要摘自文章《可信前端之路-pow工作量证明》[2],具体的数学证明可去该文章查看。

加解密算法 & 数字签名

天知,神知,子知,我知

对称加密和非对称加密,略。只提一句,比特币中采用的是非对称加密中的椭圆曲线算法(Elliptic curve cryptography,ECC)。

类似在纸质合同上签名确认合同内容,数字签名用于证实某数字内容的完整性(integrity)和来源(或不可抵赖,non-repudiation)。一个典型场景,A 要发给 B 一个文件,流程如下[3]:

1、 A首先生成公钥和私钥,并将公钥提供给B
2、 A对要发送的文件进行摘要,并使用私钥对摘要进行加密,然后将文件和加密结果一起发送给B
3、 B收到后文件和加密串,用A的公钥来解密加密串,得到原始的数字摘要,跟对文件进行摘要后的结果进行比对。如果一致,说明该文件确实是 A 发过来的,并且文件内容没有被修改过。

分布式系统 & 拜占庭将军问题

上常从容与信言诸将能不,各有差。上问曰:“如我能将几何?”信曰:“陛下不过能将十万。”上曰:“於君何如?”曰:“臣多多而益善耳。”

分布式系统,不解释。Point2Point,不解释

分布式系统作为单机系统的替代品,面临的永恒问题便是一致性问题,如数据一致性、结果一致性等等。1985年,Fischer, Lynch和Patterson三位作者发表论文,提出了“FLP不可能性原理”,该论文后来获得了Dijkstra(就是发明最短路径算法的那位)奖。这篇论文从数学的角度说明了一件事:在网络可靠,存在节点失效(即便只有一个)的最小化异步模型系统中,不存在一个可以解决一致性问题的确定性算法。

一般来说,科学家负责说明原理。而工程师的责任就是在原理下实现功能。FLP不可能的前提下,分布式系统依然可以运转的很好,下面举两个例子

  • 低可用性系统(99.7%以下)的方法是将发生一致性问题发生的概率降低,然后假装这件事没有发生,比如webserver集群,mysql集群。
  • 高可用性系统(99.99%+)的方法是牺牲性能,在关键节点将系统简化为单点,并且将系统的功能原子化,也就是将分布式系统强行降级为单机系统,然后通过复杂逻辑建立主备切换体系和其他灾备预案,保证系统永远一致且不会宕机。如库存、金融系统。

下面来引出一个更为复杂的分布式系统:拜占庭将军问题。[4]

拜占庭帝国想要进攻一个强大的敌人,为此派出了10支军队去包围这个敌人。这个敌人虽不比拜占庭帝国,但也足以抵御5支常规拜占庭军队的同时袭击。基于一些原因,这10支军队不能集合在一起单点突破,必须在分开的包围状态下同时攻击。他们任一支军队单独进攻都毫无胜算,除非有至少6支军队同时袭击才能攻下敌国。他们分散在敌国的四周,依靠通信兵相互通信来协商进攻意向及进攻时间。困扰这些将军的问题是,他们不确定他们中是否有叛徒,叛徒可能擅自变更进攻意向或者进攻时间。在这种状态下,拜占庭将军们能否找到一种分布式的协议来让他们能够远程协商,从而赢取战斗?

我们先来细化解决这个问题的一些先决条件

  • 两军之间的通信不会被打断
  • 同一时间只会有一个将军发起建议,可以是忠诚将军也可以是叛徒。
  • 忠诚将军在通讯时不会撒谎,叛徒会撒谎,但不能伪造别人进行通信

问题的抽象:定义一个变量vi,作为其他将军收到的第i个将军的命令值;i将军会将把自己的判断作为vi。可以想象,由于叛徒的存在,各个将军收到的vi值不一定是相同的。之后,定义一个函数来处理向量(v1,v2,…,vn)代表了多数人的意见,各将军用这个函数的结果作为自己最终采用的命令。至此,我们可以利用这些定义来形式化这个问题,用以匹配一致性和正确性。

  • 一致性:每一个忠诚的将军必须得到相同的(v1,v2,…,vn)指令向量或者指令集合。
  • 正确性:若i将军是忠诚的,其他忠诚的将军必须以他送出的值作为vi。

因为忠诚将军的处理向量的函数必然是相同的,所以只要得到了相同的指令向量,那他们必然可以得到一致的结果;另外,由于叛徒的存在,所以将军不会轻易信任其他人发来的指令,但是忠诚的将军之间如果因为叛徒的误导而出现错误判断,那最后大家肯定无法达成一致。我们可以将上述两个目标转述为下面的形式:

  • 一致性:每个忠诚的将军遵循同一个命令
  • 正确性:如果发起建议的将军是忠诚的,那么其他忠诚的将军必须遵循他的指令

解决方案一:口头协议

首先,我们明确什么是口头协议。我们将满足以下三个条件的方式称为口头协议:

  • A1:每个被发送的消息都能够被正确的投递
  • A2:信息接收者知道是谁发送的消息
  • A3:能够知道缺少的消息

简而言之,信道绝对可信,且消息来源可知。但要注意的是,口头协议不能溯源,就是说并不会告知消息的上一个来源是谁。原生算法如下:

OM(0)算法
(1)司令将他的命令发送给每个副官。
(2)每个副官采用从司令发来的命令;如果没有收到命令,则默认为撤退命令。

OM(m)算法
(1)司令将他的命令发送给每个副官。
(2)对于每个i,vi是每个副官i从司令收到的命令,如果没有收到命令,则默认为撤退命令。副官i在OM(m-1) 中作为发令者将之发送给另外n-2 个副官。
(3)对于每个i,和每个j ≠ i,vj 是副官i 从第2步中的副官j (使用OM(m-1)算法)发送过来的命令,如果没有收到第2步中副官j 的命令,则默认为撤退命令。最后副官i 使用majority(v1,…,vn-1)得到命令。

其中,m是叛徒的数量,m>0时采用的是递归算法。majority是处理指令向量的函数,采用多数优先、无绝对多数则给默认值的处理方式。

先说明结论,假设将军总数为n,叛徒总数为m,当n>=3m+1时,口头协议一定能达成一致且正确的结果。下面进行举例说明,由于递归层数太多会比较混乱,下面以7个将军其中有2个叛徒为例进行说明。

七个将军分别是x1,x2,x3,x4,x5,y1,y2。其中x是忠诚的,y是叛徒。x1首先提出命令。a表示进攻,d表示防守

1、x1的命令是a,并发送到其他所有将军。(OM(2))
2、由于不确定x1是否忠诚,x2收到建议后将a发送给其他五位将军。并接收其他五位将军发送来的命令。这些人中,x系列的将军会告知其他人自己收到的是a,y系列的可能发a,也可能发d。(OM(1))
3、第二轮里,x2收到了x3发来的a,但是x2不确定x3是否忠诚,所以x2询问x4,x5,y1,y2,x3发给他们的是什么,将这些结果和自己收到的x3发来的信息综合在一起,执行majority函数,以此作为x3发来的命令。
4、上面步骤完成后,x2获取了x3,x4,x5,y1,y2的所有命令,再加上自己从x1获取的命令,执行majority函数,以此作为自己的最终行动。

解决方案二:书面协议

书面协议比口头协议多了一个条件,

A4:(a)签名不可伪造,一旦被篡改即可发现,而叛徒的签名可被其他叛徒伪造;(b)任何人都可以验证签名的可靠性。

这个条件使命令在传送的过程中可以溯源。溯源显然可以使叛徒的迹象更为明显,让命令的传播更为清晰。这里不再说明具体的算法,直接说结论:在书面协议下,叛徒只要小于总数的一半,忠诚的将军就能够实现正确且一致。

Merkle tree

羽望见良麾盖,策马刺良於万众之中,斩其首还,绍诸将莫能当者,遂解白马围

默克尔树是一种二叉树,由一组叶节点、一组中间节点和一个根节点构成。最下面的大量的叶节点包含基础数据,每个中间节点是它的两个子节点的哈希,根节点也是由它的两个子节点的哈希,代表了默克尔树的顶部。[5]

在bt之类的p2p下载应用里,我们往往将一个大文件分割为多个小文件,并分别计算文件的hash,形成一个hash list,用以进行分块下载。这种case下我们可以认为是一个扁平的默克尔树,查找一个hash是否在集合中的时间为o(n).将hash组成二叉树结构,查找过程与二分查找略有一些相似,只需 要log(n)的复杂度就能够完成运算。

一般的使用流程如下:

1、在可以信任的节点获取merkle root,即根节点的哈希值
2、通过系统中的其他节点获取merkle树的其他节点,之后通过上述规则校验这些节点的正确性
3、对于某一个具体叶子节点的可信性,不需要获取完整的merkle tree,只需要得到与其相关联的节点值

区块链是什么

认识你自己

这里采用英文版维基百科的定义:A blockchain is a distributed database that maintains a continuously growing list of ordered records called blocks. Each block contains a timestamp and a link to a previous block. By design, blockchains are inherently resistant to modification of the data — once recorded, the data in a block cannot be altered retroactively. Blockchains are an open, distributed ledger that can record transactions between two parties efficiently and in a verifiable and permanent way. The ledger itself can also be programmed to trigger transactions automatically.

定义看起来很长的原因是,区块链是一个技术合集

  • 使用密码学的不对称加密保证参与者身份的安全
  • PoW提高作恶的门槛
  • 拜占庭将军问题确保系统的自运行能力的极限
  • 博弈论确保参与者有动机维护系统运行,使作恶行为的成本高于收益

交易

天下熙熙,皆为利来;天下壤壤,皆为利往

上面讲到的很多项技术,都是业界里的成熟技术被直接应用到区块链中,而UXTO是区块链中比较独特的技术方案。银行一般采用的都是基于账户的设计模式,就是说系统里存储着某账户的当前余额,支付的时候直接从余额扣除。而区块链采用的是基于账单的设计模式,系统里存储的是一条条输入输出。UXTO,全称是unspent transaction outputs,记录的是违背花费的输出。每一次比特币的交易,都包含输入和输出两部分,其中的输出部分,就可以用于后续交易的输入。从技术角度讲,比特币账本可以被认为是一个状态转换系统,该系统包括所有现存的比特币所有权状态和“状态转换函数”。状态转换函数以当前状态和交易为输入,输出新的状态。

交易流程可以简述如下:

1、a挖矿得到了12.5个比特币
2、a发起转账,转账的输入是上一步的输出,转账的目的是b,金额是5个比特币
3、收到的请求方校验a的UXTO是否合法,确认后告知a交易成功,并将这条交易记录下来,然后广播到整个网络中
4、矿工收到交易消息,并将消息打包进新的区块链中

另外一个和传统交易的区别是,交易结果是可编程的。区块链里对这个的描述叫“脚本”,交易的输入输出都是用脚本来描述的。顾名思义,既然是脚本,当然就可以写代码了。下面用语言描述两个简单的例子:

  • 转账给a,但是必须以a、b两人的签名才能使用这笔钱。
  • 延迟7天后,转账给a

这种可编程的特性,极大的丰富了区块链技术的具体应用场景,而不再仅仅限制为货币系统,如智能合约等。

应用领域

形而上者谓之道,形而下者谓之器

早年的比特币是相对冷清的,但当大家了解到区块链的各项特点,就发现原来这是一项可以颠覆很多行业的神器。这里要引用一段2014年的神往事

2014年4月12日,凌晨,北海29岁的摩的司机小裴(化名)目睹了一起抢夺案后,佯装兜客跟上劫匪,问对方是否要搭车吗。在劫匪上车后,司机直接将车开至派出所,并和民警一同将该名劫匪抓获。事后,该劫匪在录笔供时,表示“心好累,人和人之间最起码的信任都没有了。”

契约精神,一向被认为是西方文明得以崛起的重要基石。人与人之间最基础的信任,其实是我们平时生活中遇到的最大的问题。区块链技术能够让互相之间完全不信任的人可以互相信任,这就是它的最大价值。可以认为,凡是由于信任问题存在较大成本的行业,都是区块链可以大有作为的行业。

  • 跨行清算系统,国际贸易结算系统
  • 总统大选投票系统
  • 数字资产系统
  • 慈善捐款系统

君子不器

至今为止,除了比特币,区块链还没有出现其他的爆点应用。这其中既有区块链自身的一些技术缺陷,有是由于它解决的问题领域过于复杂,想真正实用起来问题重重。但显然,这只是一个时间问题,未来会走向何方,让我们拭目以待。

引用

[1] http://www.infoq.com/cn/articles/bitcoin-and-block-chain-part01

[2] http://liyangready.github.io/2016/08/21/%E5%8F%AF%E4%BF%A1%E5%89%8D%E7%AB%AF%E4%B9%8B%E8%B7%AF-pow%E9%AA%8C%E8%AF%81/

[3] https://yeasy.gitbooks.io/blockchain_guide/content/crypto/signature.html

[4] http://www.8btc.com/baizhantingjiangjun

[5] http://www.cnblogs.com/fengzhiwu/p/5524324.html