介绍
加密货币,特别是比特币曾经红极一时,不过现在更加热门的,是它们的底层技术框架BlockChain(区块链),在其提出的论文(作者是传说中的中本聪)中说:
我们提出了一种通过P2P网络来解决double-spending的方案。通过将交易记录加密(该操作相当费时)到一个不断增长的区块链上,使得造假者需要巨大的成本(主要指计算力)以至于不可能。
要了解区块链技术,我们必须要了解它在比特币的体系中,到底发挥了什么作用,又是如何做到的?
基于第三方认证的交易系统
假设小王和小红是邮票收集者,经常交换邮票。有一天,小王有了一张小红很想要的邮票,但是小红手头可以交换的。所以他们开始记账,小王把邮票给小红,等小红有了好邮票再还给小王。
小王拉来了小张作为第三方见证人,签署了一个合同:
来自 | 小王 | 给 | 小红 | 红色邮票 | 时间 | 2016.03.24 |
---|---|---|---|---|---|---|
小王签名 : | 小王 | 小红签名: | 小红 | 小张签名: | 小张 |
一式三份,人手一张,基于这份合同:
-
小王,小红,或者恶意的第三方,都无法否认该合同的存在。因为小张这里有一份存根。
-
如果一个合同在小张这里没有存根,那么肯定是伪造的。
第三方的信用在这个体系中扮演了重要角色,小张一定要是一个双方都可信的人才行。
基于加密认证的交易记录
小红和小张结婚了!他俩一起说这个交易没有发生过,小王手头的那份合同成了废纸。
痛定思痛,小王决定找一个新的交易认证方式,人太不靠谱了!他找到了公钥加密算法:
公钥加密算法,又称为不对称加密。指的是加密时需要用到一对密钥:公钥和私钥。用私钥加密的内容,可以用公钥很轻松的解开,但是想要加密出同样的内容,不知道私钥几乎是不可行。
小王又和小红做交易了(别问我为啥。。。),过程如下:
-
双方各自持有一对密钥。
-
小王和小红互相告知对方自己的公钥。
-
小王给了小红一张邮票。
-
小红把经过自己的私钥加密的收据发给小王。
现在这个收据就成了合同。用小红的公钥解密之后内容格式合法,就一定是小红签发的。不再需要第三方,除非小红死不承认。。(那就是公安局的问题了)。
双方不断地交易产生了很多收据,把这些收据顺序过一遍,就可以算出现在到底谁欠谁邮票。
为了方便交易,小王和小红约定了一个价值参照,比如红色邮票,计数为1,黄色邮票,计数为2,蓝色为3。他们的交易记录链看起来像是这样:
From | 小王 |
---|---|
加密内容 | 发送给小红,时间2016年3月25日,价值 1 |
From | 小红 |
---|---|
加密内容 | 发送给小王,时间2016年3月27日,价值 2 |
....
由于小王和小红的公钥是公开的,任何人都可以用这段交易记录算出小王和小红现在的账户余额,不需要第三方证明了。
多方交易 & 认证机制
小张也要参与到交易中。也用这个方法做交易认证。小王刚给了小红一个价值2的邮票,在小王和小红的数据账单上,小王账户余额为2, 小红账户为-2,数据账单内容大致如下:
From 小红 To 小王 Value: 2 (小红签发)
表示小王给了小红价值2的邮票,小红签了一个2个单位的收据,小红的账户变成了-2, 小王变成了2。
小张加入交易,他拿到了一份当前交易记录链的拷贝。这时小王找到小张:“你看,小红欠我两个,你把你手头那个黄色邮票给我,我把这两个单位给你,到时候你找小红要。”
小张说行啊,就给了小王,于是小张这儿的数据记录变成了:
From 小红 To 小王 Value : 2 (小红签发)
From 小王 To 小张 Value : 2 (小王签发)
趁小张和小红还没沟通,小王找到小红:“上次欠我的邮票,还我吧,我要那张黄色的。”
小红说行啊,于是小红这里的数据记录变成了:
From 小红 To 小王 Value:2 (小红签发)
From 小王 To 小红 Value:2 (小王签发)
最后小张找到小红时才发现俩人都被小王耍了。这时候,小王已经脚底抹油,跑了。
对此,我只能说,小王,你太丧(gan)心(de)病(piao)狂(liang)了。
虽然数据记录都是由本人签发,但是账单的不统一给了小王钻空子的机会。这个问题怎么解决呢?
最简单的办法,每次更新账单的时候,所有参与人都在场,这样大家都会同步更新账单了。但是,这样太麻烦了,有没有更好的方案?
分布式共识网络机制
如果我们想把这套机制用全球邮票交易上,那么每次交易都需要所有人在场是不可能的。我们需要一个系统,让全世界的人,不管地理和时区差异,都能够利用非对称加密在不需要第三方认证的情况下可靠交易。
计算机网络可以解决地理和时区差异,剩下的问题,就是如何保证全网的账单一致性。
一个方案是采用一个中心数据库记录所有交易,但是这个中心数据库不就又是一个第三方了吗,如果数据库被攻击或者管理员恶意修改怎么办?
为了去中心化,我们需要一个P2P网络,也就是节点之间的地位是平等的,每个节点都可以存储一份全局账单。现在问题是如何保证各个节点之间账单一致性。研究表明,P2P网络能保证一个“弱一致性”,它可以满足:
-
会有部分节点的账单暂时与全网账单不同步
-
整个系统最终会统一到一个账单下来
-
当出现账单冲突(像之前的例子,小王分别和小张小红各做了一套账单),最后会按照一个可预计的方式解决(比如时间在前面的才有效)
对于只是想了解大概的读者,到这里已经可以收工了。
简单说,在全世界都跑着区块链节点的情况下,大家最后总是会统一到一个一致的账单下。
如果想了解账单如何一致的可以继续阅读。
如何保证账单一致 ?
防御sybil攻击
在分布式系统中取得共识(一致性)的方法,本质都是“少数服从多数的投票机制”。这个机制里有很多设计,哪些人可以参与投票?每个人投票的权重一样吗?
假设每个参与者只需要一对密钥就可以投票,如果某一个恶意参与者通过程序伪造大量密钥对,试图达到大多数然后修改账单呢?这就是sybil攻击。
就好像淘宝交易刷单一样,通过程序,大量伪造的客户可以下很多假单,然后刷信誉,怎么办?有一个办法,就是让刷单的行为变得”昂贵“,例如每次下单,淘宝要收一块钱交易费,这样刷一万个信誉是要付出一万元的成本的。
工作量证明机制
为了增加难度,我们要求内容里必须包含一些签发者目前所知的全网账单的摘要信息,另外,加密后的内容里,必须前N位是0。为了达到这个目标,消息内容里有一个填充字段,提交者可以改这个字段使得加密结果合格。
现在常用的加密算法是SHA-256,具有相当的随机性,也就说,内容发生了一点点变化,加密结果都会大相径庭,没有规律可循,参与者只能不停的去尝试直到成功为止。
这个机制的结果导致加密一个交易记录是一个非常费算力的工作,但是认证消息仍然非常简单,首先查看加密内容前N位是不是0,然后用签发者的公钥解开就可以解密然后验证内容。
这个机制如何确保全网账单的一致性?只是大家提交记录变费劲儿了而已,那如何识别出那些是伪造的记录呢?
建立区块链
在区块链网络中有很多地位相同的节点,每个节点都有自己维护的当前账单,最终以大多数人持有的账单作为全网一致性的账单。那么区块链技术是怎么保证全网账单会收敛到一个统一账单上的呢?
首先我们了解一下区块链账单的数据结构到底是什么样子。上一章节我们讲了,为了防止sybil攻击,区块链中每一个记录要花很多计算力才能生成,普通交易者没有足够的计算能力,只能将账单内容签名后,发送到网络中,寻求别人的帮助,这时候,著名的“矿工”登场了。
矿工一般是有足够计算能力的节点,他们会收集很多条交易装在一起,然后用矿工自己的密钥,尝试各种填充位进行加密,直到符合前述的数据要求,然后就立刻向全网广播这个block,让其它节点知道一个新的block产生了。每一个block里除了包含收集到的交易数据之外,还要带上这个block基于的上一个block的ID,这样所有的block组成一个blockchain,就是全网账单,这也就是“区块链”这个名字的由来。
那么矿工耗费成本去计算block是为了什么?
其实很简单,每一个交易者发出交易请求时,需要指定一定的交易费,矿工在组装完交易记录后,还会增加一个新的交易记录到block里,声明该block里的所有交易费归自己所有。在比特币的协议中有一个巨大的比特币池,每一个block的第一条记录还可以声明从这个池中划出固定量的比特币归该矿工所有,这些利益,就是矿工的动力来源了。
接下来,我们再看看之前描述的那个场景:
-
小王和小张完成了一个交易,把小红欠自己的两个单位邮票记在了小张的账户下。
-
现在趁着小张还没跟小红沟通,小王又找到小红,要小红还他两个单位的邮票。
为了说明整个系统运作流程,假设小红同意了,她要求小王先向全网里发出一条用小王的密钥签名的交易记录,内容是给2个单元给小红(货到付邮票)。于是小王向交易网络里发出交易记录,指定交易费,请求别人帮忙将其挂载到全局账单上。
网络上的矿工收集到交易记录(包括该条),并开始打包这些交易记录成block,将该记录附加在他们所认为的最新的系统账单末尾,然后向全网广播这块新block的产生。
这里有好几种情况:
-
这个人的系统账单是最新的,也就是,他所知道的全局账单里,已经包含了小王将小红的欠账转到小张名下的记录。
小红收到新的block,组织成blockchain,计算之后发现现在反而是小王欠了她两个单位,她一把揪住小王:“骗子,你已经把我的欠账转到小张名下了!” -
这个人的系统账单不是最新的,他不知道小王转了小红的欠账到小张那儿。他将小红这条交易记录加在新block里,然后添加到他所知道的全网账单链里,然后广播出去了。
现在网络里的全网账单出现分叉了。假设在小王和小张的交易发生之前,全网账单链为b1, b2, .. bi, 收到小张广播的交易记录和之后小红的交易记录的人,往下构造的账单是b1, b2 ... bi, bz, bh。而没有收到小张的交易记录的人,构造的账单是b1, b2, ... bi, bh (漏掉了bz)。 -
这个人的账单是最新的,他构造了一个block A,发到全网,与此同时,另外一个人持有的账单也是最新的,他也构造了一个block B发到全网。哪一个block才会被承认?请注意,因为A B两个block里都有一条声明交易费的记录,所以只有最后承认的block的生成者才能“得到”这个交易费用。
这有好几个问题,所以我们先要澄清一下全网账单挂载的方式:
竞争机制
-
任何人都可以在全网帮别人确认交易,这也就是类似比特币的矿工,通过帮人计算确认交易,获得交易费用。
-
个体之前没有互相协调机制,每个人算出一个block之后都要立刻发送给他所知道的其它参与者,而其它参与者收到block时,首先用block里附带的公钥检验内容是否正确,如果正确,将该block加到他们的账单里,然后通知全网。
-
如果收到block的人正在生成block,他只能放弃当前工作,将收到block挂到自己的全网账单里,并且重新生成新的block(记得我们前面提到过,block的内容里包括它基于的上一个block,现在最新的block已经被收到的block替换了,所以得重新根据最新的block再次去计算填充值,直到加密结果符合要求---前面有两个0)。
这时候有人要问了,我干嘛要丢弃我自己算了半天的成果,我不能无视新收到的block嘛?
另外,像之前提到的,如果两个人同时发给我block咋办?
甚至有人发给我他以为正确其实错误的block(前述例子里的某些人的blockchain都错了)咋办?
这里就引入了下一个话题
解决BlockChain冲突
解决方案很简单:哪个blockchain最长就用哪个。如果节点收到多个block,并且他们的blockchain长度是一样的,就需要同时保存这几个blockchain,在多个chain上同时工作,并且不断的监听新的block消息,添加到对应的chain上,直到最后它知道哪个更长,就立刻转到该chain上往下工作,其它的则被废弃掉。
这里就涉及到一个重要概念了,每个节点目前维护的blockchain,可能是错的! 也许过了一段时间,它会看到一个更长的chain,那时候它才知道它需要换到那个chain上了。
是不是听起来很不靠谱?每个节点维护自己的chain,互相广播新的block,感觉会是一团乱啊?但是根据推算,这个链会较快的收敛到一个结果上来。所有节点不停的废弃链和在链尾添加新block,但是链身总会稳定的收敛到一个一致性的结果,这都有点哲学的味道了,不是么?
于是,在之前的例子中,小王发出交易,小红开始监听新来的block,首先她要找到包含该交易记录的block,然后为了保险起见,她又会继续监听block,直到发现有好几个block链在那一条block之后(一般来说,后面接上5个block就基本稳定了),也就是说,该block被全网节点接受了,她可以开始算算自己和小王的账单了。
-
如果矿工拿到的chain不是最新的,漏掉了小王和小张的交易,小红监听到他发出的block后,又继续听了几个后续的block,跟收到的其它矿工发出的block一比就发现这个chain比较短,该链就被废弃了,那么小王也没法忽悠小红了。同样,因为被废弃,该矿工声明的交易费也拿不到了,选择大于努力啊。。。
-
矿工A和B都发出了正确的block,这个时候就看谁的更快被多数节点接受了,这也就是为什么比特币挖矿这么费机器的原因,算得越快,越容易被接受,也就能得到更多的比特币。
-
无视别人发来的block的人,很明显他们的block生产速度慢于别人了,如果不立刻转到新block上,只会导致自己剩下的全部都是无用功。。嗯,这好像也跟哲学吻合了,请不要闭门造车,掩耳盗铃了。。
在这个情况下,小王如何耍诡计呢?他只能在他给小张2个单位的交易记录的block(假设为Block A)被接收后(也就是说,已经有了多个block挂载在该block后了),构造一个假的block链在Block A之前的block后,并且不停的构造block使得这个假chain的长度超过目前全局链的长度。这样他的chain就成了公认的,并且没有他跟小张的交易信息。
这个方案可行不可行呢?可行,但是全网里其它人一收到小王最早的交易信息后就开始往下扩充了,小王要欺骗他们换到自己伪造的chain上来,就需要比他们算的都快,快到什么程度呢?目前数学给出的答案是,要能战胜全网50%的算力才行。一旦P2P网络到了成千上万个的节点时,想达到这个算力是不可能的,这也就是比特币自称去中心化的基础。
结尾
刚刚这个交易网络,其实就是blockchain的原型。它的价值绝不仅仅是比特币这个产物,换句话说,如果我们在每个block里存储的内容不是transaction,而是别的东西呢?它就演化成了一个分布式的,无法被伪造的存储系统,特别是,在blockchain上演化出的新功能“智能合约”,就将合约的执行融合到了分布式网络中,比如,小王和小红打了赌,如果明天是晴天,小王就给小红4个单位。于是小王和小红认定了一个权威的天气机构,生成了一个交易信息放到blockchain里,不过该交易是有条件的,等到第二天,是晴天了,该权威机构用自己的私钥签发了一个晴天的消息到blockchain里,网络里无数的确认者就用该天气机构的公钥确认了晴天的消息后,执行了小王向小红的转账,并且将该block提交到网络中。这个过程完全自动不可逆,不可伪造。
这也就是为什么很多银行和金融机构开始对blockchain感兴趣的原因。在这个机制下,很多交易的中间环节可以被省掉了,这将会极大的节省金融体系运作成本,提高工作效率。