Blockchain区块链的通俗解释

来源:互联网 发布:aes java 编辑:程序博客网 时间:2024/05/04 08:50

以交易为例,逐步理解blockchain

本文基本复制于简书(简书:“白羊Jerry”提到的英文原文是googleweb工程师写的,需要翻墙,请恕我才疏学浅,英文原文中关于不对称加密的描述我没有理解透彻,感觉该工程师的逻辑有点乱。如果今后你有看到关于鲍勃和爱丽丝的例子,那很可能出自这篇文章。。。幸好简书的译文很通俗易懂。为尊重作者,白羊Jerry的原文地址:http://www.jianshu.com/p/64469b2abea6?mType=Group)

 

区块链的概念首次在2008年末由中本聪(SatoshiNakamoto)发表在比特币论坛中的论文《Bitcoin:A Peer-to-Peer Electronic Cash System》提出。论文中区块链技术是构建比特币数据结构与交易信息加密传输的基础技术,该技术实现了比特币的挖矿与交易。中本聪认为:第一,借助第三方机构来处理信息的模式拥有点与点之间缺乏信任的内生弱点,商家为了提防自己的客户,会向客户索取完全不必要的信息,但仍然不能避免一定的欺诈行为;第二,中介机构的存在,增加了交易成本,限制了实际可行的最小交易规模;第三,数字签名本身能够解决电子货币身份问题,如果还需要第三方支持才能防止双重消费,则系统将失去价值。基于以上三点现存的问题,中本聪在区块链技术的基础上,创建了比特币。


基于第三方认证的交易系统

假设小A(卖)和小B(买)是朋友,也可以不是朋友。有一天,小B准备花100元买小A的游戏机。为了记录本次交易,他们要记账。

于是找来小C作为第三方见证人,签署了一个合同:

小B花100元买小A的游戏机 2016.12.21 签字:小A 小B 见证人:小C

一式三份,人手一张,基于这份合同:

1.      小A,小B,或第三方都无法否认合同的存在,因为这里有小C的一份存根

2.      如果一个合同在小C这里没有存根,那么对于本次交易来说一定是伪造的

如果小C撕毁了合同,或者不承认,小A完全可以说,游戏机是借给小B玩的,还要收回的。这就对小B造成了欺诈(小B花了100元却没有买到游戏机)。第三方的信用在这个体系中扮演重要角色,小C的信用一定要很好才可以。

 

基于加密认证的交易记录

过了不久,小A和小C结婚了!两人都否认这个交易没有发生,小B手头的合同是假的。小B交还了游戏机,白白浪费了100元。但小B特别想要这个游戏机,于是他不要找别人做见证了,找了一个新的交易认证方式,公钥加密算法(不要纠结算法细节,先肤浅地了解一下blockchain吧):

公钥加密算法,又称为不对称加密。指的是加密时需要用到一对密钥,公钥和私钥。用私钥加密的内容,可以用公钥很轻松的解开,但是想要加密出同样的内容,不知道私钥几乎是不可行。

接着,小B又来用100元买小A的游戏机了:

1.      双方约定各自持有一对密钥

2.      小A、小B互相告知了自己的公钥,用于解密对方的私钥

3.      小B花100元买小A的游戏机

4.      小A写收据,记录本次交易。然后用自己的私钥加密,发送给小B

现在这段内容就成了合同,如果这段合同用小A的公钥解密之后,是一段合法的合同(别人的公钥解密后可能存在乱码等不合法的地方),那么一定是小A签发的。除非小A口头上不承认。。。(这样很可能会被暴打一顿)

双方不断买卖游戏机,产生了很多记录,有的小A签发的,有的是小B签发的。总之按顺序走一遍交易记录,就知道各自手上的游戏机和资金数量。

他们的交易链看起来是酱紫的:

1.      小B花100元买小A的游戏机,时间:xxxx

2.      小A花100元买小B的游戏机,时间:xxxx

3.      小B花100元买小A的游戏机,时间:xxxx

4.      小B又花100元买小A的游戏机,时间:xxxx

5.      ….

用两人的公钥解密以上收据,就知道每条收据是谁签发的了。由于小A和小B的公钥是公开的,任何人都可以计算出他俩的账户余额,也不需要第三方证明数据真伪了。

 

多方交易&认证机制

接下来,小C也加入到交易中来。他也准备用这个方法做交易认证。假设,现在的状态是,小B花100元买了小A的游戏机。交易过程如下:

1.      小B花100元买小A的游戏机,时间xxxx

表示目前小B账面上有游戏机,小A账面上有100元。

因为小C也加入了交易,他拿到一份当前交易记录链的拷贝。这时候,小A找到小C说:“之前我把游戏机100元卖给小B了,现在我花100元买你的游戏机。你要是还想用游戏机,就用这100元去找小B买吧。”交易链变成了:

1.      小B花100元买小A的游戏机,时间xxxx

2.      小A花100元买小C的游戏机,时间xxxx

趁小B和小C还没沟通,小A立刻找到小B说:“我把100元还给你,你把游戏机还给我吧。”小B说,行啊。(实际上小A账目上只有游戏机,没有100元,但是在小B看来,小A有100元。于是小B写了收据,标明小A账目划去100元,加入游戏机,小B账目加入100元,划去游戏机。小B的游戏机就给了小A了。)于是交易记录变成了:

1.      小B花100元买小A的游戏机,时间xxxx

2.      小A花100元买小B的游戏机,时间xxxx

当小C来找小B兑换游戏机时,才发现小A账目上并没有更多的100元买小B的游戏机了。小B损失了游戏机,账目上也没有被划入100元。而这时,小A已经跑了。

虽然数据记录都是由本人签发,但是由于账单的不统一,仍然给了小A钻空子的机会。这个问题怎么解决呢?

最简单的办法,每次更新账单的时候,要求所有人都在场,这样所有人都会同步更新账单了。但是,这样太麻烦了,有没有更好的方案?

 

分布式共识网络机制

如果我们想把这套机制用全球邮票交易上,那么每次交易都需要所有人在场是不可能的。

我们需要一个系统,让全世界的人,不管地理和时区差异,都能够利用非对称加密在不需要第三方认证的情况下可靠交易。计算机网络可以解决地理和时区差异,剩下的问题,就是如何保证全网的账单一致性。一个方案是采用一个中心数据库记录所有交易,这样刚才的例子中,小A在向小C买了游戏机后,再找小B时,小B对照中心数据库,就会说:“你已经把我买游戏机的100元转到小C账户下了,你已经没有100元买我的游戏机了。”

但是这个中心数据库不就又是一个第三方了吗,如果数据库被攻击或者管理员恶意修改怎么办?

为了去中心化,需要一个P2P网络,也就是节点之间的地位是平等的,每个节点都可以存储一份全局账单。现在问题是如何保证各个节点之间账单的一致性。研究表明,P2P网络能保证一个“弱一致性”,于是我们的需求稍微退一步,就变成了:

1.      会有部分节点的账单暂时与全网账单不同步

2.      整个系统最终会统一到一个账单下来

3.      当出现账单冲突时(像刚才的例子,小A分别和小B、小C各做了一份账单),最后会按照一个可预计的方式解决(比如时间在前面的才有效)

4.      系统必须可以低于Sybil攻击

 

防御Sybil攻击

在分布式系统中取得一致性的方法,本质都是“少数副总多数的投票制”,大部分节点认为正确的当前账单就是最后的合法唯一账单。这个环节会有很多问题,哪些人可以参与投票?每个人投票的权重一样吗?

假设所有人都可以投票的话,按照之前的机制,只需要一对密钥就可以试图修改那个全局账单了,如果某一个恶意参与者通过程序伪造大量密钥对,试图达到大多数然后修改账单呢?这就是Sybil攻击。

就好像淘宝交易刷单一样,通过程序,大量伪造的客户可以下很多假单,然后刷信誉,怎么办?有一个办法,就是让刷单的行为变得“昂贵”,例如每次下单,淘宝要收一块钱交易费,这样刷一万个信誉是要付出一万元的成本的。

 

工作量证明机制

在这个P2P交易网络里,任何人都可以很容易生成一对密钥参与到交易中,但提交交易记录成了一个很难的事情,它需要消耗大量的计算力。这又是怎么回事?

我们前面提到,要提交一段交易,参与者只需要用自己的私钥签署内容发到网上就可以了。现在不是这样了我们要求内容里必须包含一些签发者目前所知的全网账单的摘要信息,另外,加密后的内容里,必须前N位是0.为了达到这个目标,消息内容里有一个填充字段,加密者必须不断地试着用各种填充值去试验,使得最后加密的结果前N位是0.现在常用的加密算法是SHA-256,具有相当的随机性,也就是说,内容发生了一点点变化,加密结果都会大相径庭,没有规律可循,参与者只能不停地去尝试直到成功为止。

这个机制的结果导致加密一个交易记录是一个非常费时间的工作,但是认证消息仍然非常简单,首先查看加密内容前N位是不是0,然后用签发者的公钥解开就可以看到内容了。

这个机制如何确保全网账单的一致性?只是大家提交记录变得费劲了而已,那如何识别出哪些是伪造的记录呢?

 

建立区块链

在区块链网络中有很多地位相同的节点,每个节点都有自己维护的当前账单,最终以大多数人持有的账单作为全网一致性的账单。那么区块链技术是怎么保证全网账单会收敛到一个统一的账单上的呢?

首先我们来了解一下区块链账单的数据结构到底是是什么样子。为了防止Sybil攻击,区块链中每个交易记录都要花很多计算力才能生成,普通交易者没有足够的计算能力,只能将账单内容签名后,发送到网络中,寻求别人的帮助,这时候,著名的“矿工”登场了。

矿工一般是有足够计算能力的节点,他们会收集很多条交易记录装在一起,然后用矿工自己的密钥,尝试各种填充位进行加密,直到符合前述的数据要求,然后就立刻向全网广播这个block,让其他节点知道一个新的block产生了。每个block里除了包含收集到的交易数据之外,还要带上这个block基于的上一个block的ID,这样所有的block组成一个blockchain,就是全网账单,这也就是“区块链”这个名字的由来。

那么矿工消耗成本区计算block是为了什么?

其实很简单,每一个交易者发出交易请求时,需要指定一定的交易费,矿工在组装完交易记录后,还会增加一个新的交易记录到block里,声明该block里的所有交易费归自己所有。在比特币的协议中有一个巨大的比特币池,每一个block的第一条记录还可以声明从这个池中划出固定量的比特币归该矿工所有,这些利益是矿工的动力来源。

接下来,再看看之前描述的场景:

1.      小A和小C完成了一个交易,小A花100元买了小C的游戏机。小A账户扣除100元、加入游戏机。小C账户加入100元、扣除游戏机。

2.      趁着小B和小C没有沟通,小A又找到小B,要用100元换回游戏机。

为了说明整个系统的运作流程,假设小B同意了。小B要求小A先向全网发出一条用小A的密钥签名的交易记录,内容是“小A用账目下的100元买小B的游戏机,时间xxxx”。于是小A向交易网络里发出交易记录,指定交易费,请求别人帮忙将其挂载到全局账单上。

网络上的矿工收集到交易记录(包括该条),并开始打包这些交易记录成block,将该记录附加在他们所认为的最新的系统账单末尾,然后向全网广播这条新block的产生。

这里有好几种情况:

1.      这个人的系统账单是最新的,也就是,他所知道的全局账单里,已经包含了小A和小C的交易记录。

小B收到新的block,组成blockchain,计算之后发现小A并没有100元,他已经用100元买了小C的游戏机。

2.      这个人的系统账单不是最新的,他不知道小A买了小B的游戏机。他将小A与小B的交易记录加在新block里,然后添加到他所知道的全网账单链里,然后广播出去。

现在网络里的全网账单出现分叉了。假设在小A和小C的交易之前,全网账单链为b1, b2,…bi, 收到小C广播的交易记录和之后小B的交易记录的人,往下构造的账单是b1,b2, …bi, bz, bh. 而没有收到小C记录的人,构造的账单是b1,b2, … bi, bh(漏掉了bz)

3.      这个人的账单是最新的,他构造了一个blockA,发到全网,与此同时,另外一个人持有的账单也是最新的,他也构造了一个blockB发到全网。哪一个block才会被承认?注意,因为AB两个block里都有一条声明交易费的记录,所以只有最后承认的block的生成者才能获得这个交易费用。

这里有好几个问题,先来澄清一下全网账单挂载的方式。

 

竞争机制

1.      任何人都可以在全网帮别人确认交易,这也就是类似比特币的矿工,通过帮人计算确认交易,获得交易费用。

2.      个体之间没有互相协调机制,每个人算出一个block之后都要立刻发送给他所知道的其他参与者,而其他参与者收到block时,首先用block里附带的公钥检验内容是否正确,如果正确,将该block加到他们的账单里,然后通知全网。

3.      如果收到block的人正在生成block,他们只能放弃当前工作,将收到的block挂到自己的全网账单里,并且重新生成新的block(记得前面我们提到过,block的内容里包括它基于的上一个block,现在最新的block已经被收到的block替换了,所以得重新根据最新的block再次去计算填充值,直到加密结果符合要求—前面有N个0)。

这个时候有人要问了,我干嘛要丢弃我自己算了半天的成果,我不能无视新收到的block吗?

另外,如果两个人同时发给我block怎么办?

甚至有人发给我他以为正确其实错误的block怎么办?

 

解决blockchain冲突

解决方案很简单:哪个blockchain最长就用哪个。如果节点收到多个block,并且他们的blockchain长度是一样的,就需要同时保存这几个blockchain,在多个chain上同时工作,并且不断地监听新的block消息,添加到对应的chain上,知道最后它知道哪个更长,就立刻转到该chain上工作,其他的被废弃掉。

这里就涉及到一个概念,每个节点目前维护的blockchain,可能是错的!也许过了一段时间,它会看到一个更长的chain,那时候它才知道它需要换到哪个chain上了。

是不是有点不靠谱?每个节点维护自己的chain,互相广播新的block,感觉会是一团乱啊?但是根据推算,这个链会较快的收敛到一个结果上来。所有节点不停的废弃链和在链尾添加新的block,但是链身总会稳定的收敛到一个一致性的结果。。。。哲学家应该懂。。。

于是在前面的例子中,小A发出交易,小B开始监听新来的block,首先小B要找到包含该交易记录的block,然后为了保险起见,他会继续坚挺block,直到发现有好几个block链接在那一条block之后(一般来说,后面接上5个block就基本稳定了)也就是说,该block被全网节点接受了,小B可以开始真正算算自己和小A的账单了。

1.      如果矿工拿到的chain不是最新的,漏掉了小A和小C的交易,小B监听到小A发出的block后,又继续听了后面的block,跟收到的其他矿工发出的block一比就发现这个chain比较短,该链就被放弃了,那么小A也没法忽悠小B了,以为他账目上并没有100元。同样,因为被废弃了,该矿工声明的交易费也拿不到了。

2.      矿工P和矿工Q都发出了正确的block,这个时候就要看谁的更快被多数节点接受了,这也就是为什么比特币挖矿这么费机器的原因,算得越快,越容易被接受,也就能得到更多比特币。

3.      无视别人发来的block的人,很明显他们的block生产速度慢于别人,如果不立即转到新的block上,只会导致自己剩下的全部都是无用功。请与时俱进!

这个时候,小A还可以耍诡计,钻漏洞。他可以在和小C的交易记录的block(设为blockP)被接受后,也就是很多个block挂载到该block之后,构造一个假的block链接在blockP之前的block后,并且不停的构造block使得这个假chain的长度超过目前全局链的长度。这样他的chain就是公认的了,并且没有他跟小C的交易记录。这个方案可行,但是全网里其他人一收到小A最早的交易信息后就开始往下扩充了,小A要欺骗他们换到自己的假chain上来,就需要比他们算的都快,快到什么程度呢?目前数学给出的答案是,要能战胜全网50%的计算力才行。一旦P2P网络到了成千上万个节点的时候,想达到这个计算力是不可能的,这也是比特币自称去中心化的基础。

 

结尾

刚刚这个交易网络,其实就是blockchain的原型。它的价值不仅仅是比特币这个产物,话句话说,如果我们在每个block里存储的内容不是transaction,而是别的东西呢?它就演化成了一个分布式的,无法被伪造的存储系统,特别是,在blockchain上演出的新功能“智能合约”,就将合约的执行融合到了分布式网络中,比如,小A和小B打赌,如果明天是晴天,小A就给小B100元。于是小A和小B认定了一个权威的天气机构,生成了一个交易信息放到blockchain里,不过该交易是有条件的,等到第二天,是晴天,该权威机构就用自己的私钥签发一个晴天的消息到blockchain里,网络里无数的确认者就用该天气机构的公钥确认了晴天的消息后,执行了小A向小B的转账,并且将该block提交到网络中。这个过程完全不可逆,不可伪造。

这样就是为什么很多银行和金融机构开始对blockchain感兴趣的原因。在这个机制下,很多交易的中间环节可以被省掉,极大节省了金融体系运作的成本。

0 0