比特币白皮书 个人翻译+注解

作为bitcoin区块链的《圣经》,我终于在除夕当天翻译完成了。

然后今天对其做出了个人的注解。

毕竟英语太渣,翻译部分我都采取了直译,力求不丢失原文信息,所以看起来很别扭。。但是至少还是读得懂的。还有整篇文章都是赶出来,自己还没检查一遍,很多地方读不通顺甚至有错误,请大家见谅。

自己的注解部分全部以引文的方式体现,主要包含了技术构成分析以及区块链系统的个人思考。

英文链接

Bitcoin: A Peer-to-Peer Electronic Cash System

比特币白皮书作为区块链的始祖,区块链神教的《圣经》,分析全文的过程我中充满了对中本聪的钦佩。

以下即为我个人的翻译:

请注意:区块链是比特币实现的技术,比特币是区块链的第一个应用。

Bitcoin: 一个点对点电子现金系统(翻译+注解)

摘要:一个纯粹的p2p版本的电子现金(cash)货币允许在线支付能够让一方直接发送到另一方而不通过一个金融机构。数字签名提供的这个场景的部分解决方案,但是如果在面对阻止双重支付(双花)的场景下仍然需要一个信任的第三方那么现有的方案仍然是缺少主要利益(不够好)的。这个网络加盖时间戳到交易上通过对这些交易做hash变为一个持续增长的基于随机算列的(hash-based)的工作量证明(pow)的链上。最长的的链不止提供证明对被观察的发生的事件顺序,并且提供证明这条链来自最大的CPU计算力的池。只要主要的CPU算力是不被那些有攻击网络性质的节点所控制,他们会成长为最长的链并超过那些攻击者。这个网络自身只需要很小的结构。信息被最有效率的方式广播,并且节点可随时离开或加入网络,这些节点接受最长的Pow链作为他们(节点)离开网络后发生事情的证明。

摘要指出,现有的技术让p2p的发送一个交易是可靠的,方法是通过数字签名的方法,这里暗含指出比特币在这个方面使用的也是数字签名的方式保证交易传递。但是随后就指出,数字签名的是无法解决双重支付的,因为数字签只能保证这个东西是属于发送方的,但是没有办法保证这个东西发给一个人以后不会再发给其他人,因为数据是可以复制的。现有的方案就是发送方和接收方都信任一个第三方作为中介。由这个第三方记录A有一个东西,并把这个东西给了B完成了一笔交易。也就是这个第三方具有绝对上帝的权利,而A和B都是因为“信任着”这个第三方交易才能成立。之后给了区块链系统一个很大概的介绍,其中指出区块链的几个关键点:时间戳,hash作为标识,使用hash的工作量证明,链在一起。提供发生事件的顺序表明区块是“记录历史的”,链来自最大CPU算力是说明其在CPU算力证明的规则下是唯一的,不可被颠覆的。最后说明区块链的结构精简,节点灵活,暗含这是一个多节点智能共同协作的智能系统。(就是虽然每个节点智能有限,但是所有节点都遵从一套简单的规则,则整个系统能体现出巨大的力量)

1.介绍

现在internet上的贸易绝大多数都要依靠一个金融机构提供第三方信任来处理电子支付。尽管这个系统对多数交易都工作的很好,但是它依然面对与生俱来的基于信任模型的缺陷。完全的不可逆交易不是真正可能的,因为金融机构不能避免纠纷协调处理。协调调解的成本增加了交易的成本,限制了最小的实际交易规模并且切断了小型临时交易的可能。并且在对不可逆服务进行不可逆付款的弱项方面存在更大的成本。因为存在撤销的可能性,对信任的需要就被分散了。商户需要对他们的客户提高警惕,所以收集他们比起需要的更多信息。一定比率的欺诈被视为是可能的。这种成本和不确定的交易是可被避免的当一个人是通过现实现金交易的方式,但是没有一个存在的机制来确保交易是通过一个没有可信方的通信通道进行支付的。

这段体现出区块链是为了解决信任问题,因为第三方机构的存在,信任问题是一种天然存在的问题。现有的机制在维护这种信任会付出很大的成本。另一方面区块链体现出不可逆和不可篡改性,并指出这两个特性是区块链天然具有的。准确的来说这里体现出来就是区块链出现的颠覆性理由。回顾目前为止的科技发展,由计算机引领了第三次信息革命,使得信息能够在网络中快速流动。但是互联网虽然能够使信息快速流动,但是却没法实现类似现实世界中的物质转移。因为信息是虚拟的,但是现实中的物质是实实在在的实体。正是因为互联网中是虚拟的,所以如果在一个虚拟的世界中模拟一个物体,就可以无限制的复制这个物体,但是同时是没法模拟现实中的物质转移的。举例来说就是假设A要给B一个物品,那么在现实世界中是实实在在的物品转移,而在虚拟世界中就是一条消息记录,而这条消息记录是由A记录,还是由B记录,还是由一个第三方记录呢?显然不管是A记录还是B记录都不可能让A和B都同时认同,因为他们都可以私自更改这个记录而违约,所以就会找一个第三方来做担保(如公证处,中介等),A和B都把自己的信任交给了这个第三方机构做担保,所以整个体系才能共运作起来。所以目前对这样的模拟都是引入了第三方可信机构,人们把信任交给这个第三方,并相信由这个第三方保证模拟物品的唯一性和转移(不可复制)。而这个第三方是否真的可信,就是现在运行这套体系所付出的成本。这是目前这套体系的“天然缺陷”。

所以如果想要使用互联网来模拟现实中的物质转移,使现实中的物品和虚拟世界中的物品挂钩,而不需要一个第三方作为这个转移的担保,那么就需要引入区块链机制。区块链可以让物质的转移像信息流动一样快速便捷,同时又由全网的人一起来担保(全部参与的人一起担保就相当于天然存在存在不可证伪,除非其中51%的人统一口径违约),来保证在虚拟世界中的物质转移的可靠。我认为这就是“区块链”技术有望成为引领“第四次技术革命”的核心原因。

现在需要的就是一个电子支付系统基于密码学加密证明来替代信任,允许任何两方能够直接交易在不需要一个可信的第三方的场景下。计算上保证的不可逆交易将会保护卖方免受欺诈,并且常规的托管机制可以很容易的被实现来保护买方。在这篇论文里,我们提出一种方案来解决两次支付问题使用一种p2p分布式的时间戳服务来生成交易的时间顺序的计算证明。整个系统是安全的只要诚实节点比合作攻击的节点控制了更多的CPU计算力。

这里指出,实际上信任问题是由原来的国家强制力(银行),企业大小(微信,支付宝)这种感觉或者其他的信任转移到了“密码学加密”的数学体系上,变为了是否相信数学是可靠的问题。但是后一句的语言表达上实际上暗含了区块链这个体系实际上是支付方比接收方更具备一点优势,不是绝对平等的地位,所以接收方需要担心支付方的攻击(二次支付)。最后说明,区块链解决两重支付,基础的拓扑结构是p2p,时间戳是确认交易顺序的方式。

2.交易(Transaction)

我们定义一枚电子币(electronic coin)作为一个数字签名链(as a chain of digital signatures)。每一个拥有者(owner)交易货币(coin)给下一个人通过数字签署(私钥签署) 上一个交易和下一个人的公钥 的hash 并且把这个签署的结果附加在了这个货币的末尾。一个收款人可以验证这个签名来确保这个链的所有权(chain of ownership)

这段话在原文表述的过程中直观来说有点反直觉。因为在第一句话原文是We define an electronic coin as a chain of digital signatures,也就是说define coin as chain。这是一个很奇怪的东西,因为直观来说,coin应该是一个一个的,但是chain是一个链条,很难把coin和chain联系在一起。但是比特币本质上确实就是一个链条,这个链是由一条一条交易按照发生的顺序组成的,而coin反而是不存在的,coin是由链条上的交易(transaction)推算出来的,本身并没有直接的coin出现。同时这里看到,根据前文的描述,把一个coin给下一个人是通过数字签名的方式,也就是说通过公私钥的方式证明coin的来源与去处。假设现在A要给B一个coin,那么这个过程成为一个交易(transaction)(比如下图中的中间那个Tx),这个交易记录给B多少coin,和B的公钥(指明目的地),同时提供A可以操作上一个交易(如图中的第一个Tx。比如这个Tx记录的是X给了A一笔钱,那么相当于A可以操作X给A的这个交易的输出),对这两个共同hash后,付款者A用自己的私钥签署这个hash,然后加在交易的上面。之后这个交易被广泛地广播道其他地方。此时作为一个旁观者(矿工),是在自己本地具有第一个交易之前的所有交易的,所以看到这个交易(中间这个Tx)的时候,就可以用付款者A的公钥(指代的是图中第一个交易,A的公钥从第一个交易中获得)去验证这个交易(中间这个交易)的签名以证实这个交易是不是由付款者A本人发出的(因为私钥只有A持有,只有用A的私钥进行签署的签名才能和上一个交易(第一个交易)进行验证通过,证明A可以操作第一个交易,具备这笔从X转到A的钱)。这样就证明了这个交易是由付款人A发起的。

我们来以中间那个Tx(交易)作为参照物。这个Tx是由Owner 1发起的,由图中可以看出,hash的input是上一个Tx(prev Tx)和下一个接收者的公钥(next owner's pub key),这hash的结果被Owner 1的私钥进行签署,并附加在了当前的这个交易上。目前不要和下一个Tx连起来看,当Owner1签署完这个Tx后,Ta把这个交易广播出去,则一旦有矿工(miner)将这个交易打包进入区块并链在诚实链(最长的链)上,则表示这个Tx是成立的。所以可以看出此时Owner2是不会像正常交易那样立即知道有没有成功的,而是需要过段时间去"查看"(这里是很朴素的说法,也可表示有个东西去轮询,只要交易被打包了就通知Owner2)这笔交易有没有被打包,是的话就代表交易成功了。

这个过程的问题是收款人不能验证付款人中(one of the owners)没有双重支付货币。一个通常的解决方案是引入一个可信的中央认证,或铸币厂(mint),来对每一笔交易检查是否被双重支付。在每一笔交易后,这个货币必须被返回到铸币场(mint)来发行一个新的货币(coin),并且只有货币被直接的从可信的铸币厂发行才能保证不被双重支付。这个解决方案的问题是全部货币(money)的命运都依靠在这个公司运作的铸币厂(mint)上,每一笔交易都必须通过他们,就像一个银行一样。

这里的铸币厂一开始很难理解是什么意思,其实这个是个很简单的现象,只是这个过程实在是太朴素了以至于没人注意到现在的体系就是这样运作了。比如现在的网上银行(或者支付宝),当A给B转账100块钱,实际上是银行开启了一个事物(transaction),让A的账户上-100块,然后让B的账户上+100块。这个-100块和+100块实际上就是银行这个“铸币厂”,销毁了A的100块钱,然后又生产了100块钱给了B(只不过整个流程都只是体现在信息的流动上)。正因为如此,所以才要保证这个“货币”只能从这个“铸币厂”(银行)发行,并且这个“铸币厂”被双方都共同信任,每一笔交易都“必须”通过这个“铸币厂”而没有其他途径。现有的体系也正是由银行"铸币厂"(唯一信任方)来保证A的账户-100的同时只有B的账户+100而不会同时C的账户也+100(双重支付)。(当然要是银行有内鬼和A暗地沟通,当A转账给B 100块的同时给C也加上了100块,就发生了双重支付了。当然现在看起来是不会发生的,这是因为银行自身的“监督”体制保证的,如每天的对账,银行内部的监管等等。而这些监督的代价,就是维护这个体系的成本)

另一方面,之所以银行能知道一笔钱是否被双重花费了,是因为这个银行具备了当前交易之前的所有的“历史交易”,它验证一个交易是否合法的方式就是去检查之前的所有交易的结果是否满足当前这笔交易的要求。

我们需要给收款人(payee)一个方法去知道之前的拥有者们(owners)没有签署过更早的交易。对于这个目的,最早(earliest)的交易才是重要的,所以我们不必关心后面的交易是否尝试去双重支付。唯一的确保一个交易存在性的方法就是拥有查询所有的交易。在基于铸币厂模型中,这个铸币厂拥有所有的交易并且决定哪一个交易最新到达(which arrived first)。为了在没有一个可信任方的情况下完成这件事情,交易必须被公共公告,并且我们需要一个系统让所有参与者对只对在一个单链顺序历史(which they were received)上达成共识。收款人需要证明在每一次交易的期间,大多数节点都同意这是他们第一次收到的(was the firstreceived)。

这里指出首先是付款人才会发生双重支付,而收款人是担心付款人会不会干这件事情(废话,因为利益是由付款人转移到收款人上的)。“最早的交易才是重要的”这句话是说,双重支付发生的基础是,首先要已经发生过一个交易,然后付款人想无视这笔交易,再次使用这个交易已经用过的货币发起另一次交易。所以这个最早的交易指代的是“已经发生过的交易”。铸币厂并不关心想要发起双重支付的人的两笔(或以上)的交易哪笔是这个付款方认为先发生的,他只关心此刻这个付款方发起的这个交易是否“合法”(也就是之前这个人有没有已经用过这笔钱了)。所以是铸币厂确认哪个交易在前,而不是由付款人决定哪个在前的。那么此时的这个铸币厂并不归属任何一个第三方,那么这个交易就必须被“广而告之”,让所有参与进来的人都知道这件事情发生了,并且所有人都知道以前发生的所有“历史事件”来验证此时被广播的这个交易是否是合法的。但是我们知道,要让所有参与的人都保持一致是一件相当相当困难的事情,这也就是区块链所解决的问题。而最后一句话就是说收款人需要大多数人(超过51%)都认为那个交易是合法的了,那么才能说明这个交易是合法的。

3.时间戳服务器(Timestamp Server)

我们建议的解决方案从时间戳服务器开始。一个时间戳服务器的工作是通过把一组数据(items)形成的区块(blocks)的hash结果(taking a hash)加盖上时间戳(to be timestamped)并广泛的广播(publishing)这个hash,就像在报纸或者世界性新闻组网络(Usenet)的发帖一样[2-5]。这个时间戳证明在那个时间这个数据一定是存在的,明显的,要得到这个hash(就只能在这个时间)(inorder to get into the hash)。每一个时间戳包含了上一个时间戳在它的hash中(includes the previous timestamp in itshash),形成了一个链条,随着每个新增的时间戳都加强(reinforcing)了这个新增之前的所有时间戳。

从这部分开始说明的就是矿工(miner)所干的工作。这里的一组数据就是指很多笔交易,然后把这一组数据打包成了一个区块(block),并把这个区块加盖上时间戳并做hash,以此来保证时间的先后顺序,也就是要完成第2部分所介绍的“确保历史顺序”。而因为要得到这个hash是和当时的时间戳联系在一起的,所以这个hash就标识着时间了。因为这些区块是形成一个链条的,而区块的增长是CPU算力的证明(后文会描述),所以因为hash->体现了时间戳->hash被链在一起->链上一个新的区块需要耗费CPU->所以之前的hash就一定是正确的(不断被加强可信度)。

这个图就是为了说明时间和区块挂钩,区块和hash挂钩,和这些hash因为区块链的性质连在一起,所以之前挂钩的时间戳是不可被篡改的。

4.工作量证明(Proof of Work)

为了实现一个基于p2p的分布式时间戳服务器,我们将会需要使用一个类似于Adam Back's Hashcash[6]的工作量证明系统,而不是使用报纸或者世界新闻网络组。工作量证明机制引入对一个值的扫描(scan)在hash的时候,例如在SHA-256下,这个hash从一串0bits开始。需要的平均工作是所需0bit数的指数,并且可以通过执行单个hash来被验证。

该部分就是bitcoin区块链的另一个核心部分,就是广泛被人所知的PoW。在前面章节提到过首先A与B发生了一笔交易,然后这笔交易被广播,由于没有第三方,所以参与的人就是全网的所有节点。这些节点在收到这个交易和其他好多交易后,打包成为一个区块并加盖上了hash。那么现在的问题就来了,如果这些旁观的矿工都分别收到了很多交易消息并打包出了自己的区块,那么怎么保证全网达成共识呢?也就是假设C,D,E三个矿工都收到交易消息了,然后因为他们收到的交易消息不完全一致,收到的时间也不完全一致,那么产生的区块的hash肯定天差万别,有p2p经验的人都知道此时就需要保证C,D,E三个人最后需要达成共识,这样才能保证整个网络都认同同一个区块链所发生的“历史事件的顺序”,否则整个体系将会毫无用处。而中本聪在这里的方式就是引入了POW来让C,D,E三个人用付出”CPU算力“的途径去以概率性成功的方法去抢夺记录区块的权利(也就是俗称的”记账权“)。原文中的scan就是指暴力枚举。因为对于SHA-256来说,以目前的密码学来说,要达到某个符合的条件,只有进行暴力枚举的方式去获得,显然,”暴力“的快慢,是由CPU的计算能力决定的,而要暴力的规模,就是这个POW机制的”难度“。因为要枚举出这个值是以”概率性“的事件(想象一下去猜测一个不知道密码的压缩文件会怎么暴力破解),但是因为要经过相当多次枚举,最后平均下来,得到的结果确实可衡量的(也就是概率的期望值,在有些矿池把这个近似的叫幸运值?不太确定)。

对于我们的时间戳网络,我们实现这个工作量证明通过在区块中增加一个nonce,直到一个给出块的hash所需要的0-bits值(位数)被找到。一旦CPU效率被花费来作为工作量证明,这个区块不能再被改变去重做相应的工作。之后区块被链在它之后,要改变这个区块说需要的工作将会包含这个块之后所有块所需要的工作量。

对于这个区块”猜测“得到的那个满足要求的值的方式就是改变这里的nonce。(因为对于散列函数来说,只要做一点小的改动,结果就会完全不同。获得满足要求值得方式就是不断变换nonce使得整个区块的hash满足难度要求)所以这个nonce就代表了当前这矿工,为了夺取到这一轮区块的”记账权“,所付出的劳动(CPU算力,电费)的”证明“。所以可以直接把nonce看作是”劳动(工作量)的证明“。而后半部分是说明,假如区块中有更改,那么这个hash就被更改了,那么就需要重新计算这个区块的nonce,也就是要改变前面的区块,那么你要把要改的这个区块一直到目前这轮所需要的区块全部都计算过来(付出需要的全部劳动)才可做到。

这个图实际上和上一个图一样,只是这里着重体现出每个区块的内容,指明一个区块是包含上一个hash的(Prev Hash),并且Nonce是区块中的一个部分。一旦更改Nonce,Prev Hash, Tx其中任意一个,那么这个区块的Hash也会改变,之后的区块也全部都要改。

工作量证明同时解决了多数决策中决定代表的问题。如果大多数人只根据一人一ip进行投票(one-IP-one_vote),这样会被任何能够分配很多ip的人破坏。工作量证明本质上是一CPU一票(one-CPU-one-vote)。主要的(大多数)的决定是由最长的链所代表,最长链拥有最大的工作量花费在其中。如果一个大多数CPU算力都被诚实节点所控制,那么最诚实的链就会增长的最快且超过其他任何计算链。想要改变一个过去的区块,攻击者需要重做这个区块和所有在这个块后的区块的工作量证明,之后还要追赶上并超过现在所有诚实节点的工作。我们之后会展示,一个慢速的攻击者能够追赶上(catching up)的可能性将会指数级的减少,但后续的块被添加时。

这段补充说到PoW实际上就是共同决策选择代表的问题,等价于抢夺记账权问题,因为抢到了记账权,就是选出了代表。这里附加上说到为什么中本聪没有考虑使用IP作为决策的原因,是因为他认为IP作为投票权比CPU作为投票权容易的多(是否是最好的选择不知道,但是目前看来是最好的,不过现在的CPU投票权都被”矿池“所把控,一定程度上产生了动摇性(但仍然比控制IP好的多),当然也有一些矿池公开宣布自己的算力不超过一个值以维持整个体系的稳定(找到这个新闻我就补充上链接))。随后文章再次强调,想要更改区块,那么攻击者将要付出极大的代价,而诚实的链因为是规则所倡导的,会在博弈中自然的变为最长的链(后文将会描述)。

为了补偿不断增长的硬件速度和随着时间推移不断变化兴趣的运行节点(vrayinginterest),工作量的困难度是由一个移动的平均目标决定,就是每一个小时的平均区块(就是这个平均目标)。如果这些计算力增长的太快,这个困难度就会增加。

这里指出这PoW的难度是随整个系统的难度而一起提升的,因为计算机计算的硬件能力是不断提升的,想想现在的CPU挖矿->显卡挖矿->矿机挖矿,这就是PoW的精妙之处。但是这同样也带来了一个对bitcoin不看好的一个理由:现在的计算机算力因为参与的人太多,而难度提升的很大,整体的算力也水涨船高,近年更是呈指数增长。那么要是过了若干年后,bitcoin的激励(后文提到)所产生的效果不能承受这么高算力的代价,是否会造成算力的断崖式下跌?随之带来的是bitcoin信用的崩溃(能够被掌控算力的人攻击)而导致bitcoin最后突然崩盘?

5.网络(Network)

运行这个网络的步骤如下:

  1. 新的交易被广播到全部的节点。

  2. 每一个节点把新的交易收集进入到一个区块

  3. 每一个节点都为自己的那块区块进行工作去找到那个工作量证明

  4. 当一个节点找到了这个块的工作量证明,它把这个块广播给所有的节点

  5. 节点们只能当这个区块中的所有的交易都是合法的并且都没有被花费过才会接受这个块

  6. 节点们通过转向下一个块的工作量证明并使用这个块的hash作为(下一个块的)前一个hash来表示接收这块。

节点们总是只考虑最长的链是正确的并且不断为扩展它进行工作。如果2个节点同时广播不同版本的下一个块,一些节点会首先收到其中一个块,在这种情况下,他们为收到第一个块而工作,不过另一块保存下来以防它会变得更长。这个平衡(tie)将会被打破当下一个工作量证明被发现的时候并且这个时候一条分支会变得更长。在其他分支工作的节点们将会转换到这个最长的分支上。

这段实际暗含了bitcoin的”最大规则“,也就是所有人都默认最长链是正确的。如果这条不能保证,那么可想而知整个系统是不能工作的。而这个最长链是正确的是由后文的”激励机制“所保证的,所以这里就出现了一个博弈场景:如果现在要创建一个区块链应用,那么要么要所有人能够公认一个规则(强制力),那么要用某些方法使人们能够自主的认同一个规则(激励),但是总之因为争夺区块是要产生代价的,如何在对这个代价进行”强制力/激励“进行博弈,就是一个区块链是否能健康成长的关键。

后半部说明一个区块真正能够被承认的关键:有矿工(大部分)以这个区块为prev区块,并为它构成的hash纳入新的一个区块并为新的区块工作,那么这个区块才是被承认的。所以这里指明,只有产生的下一个区块,当前的这个区块才是”合法的“。这条相当关键,因为所有的攻击都会指向这个问题,同时收款者与付款者的不平衡点也是这里所导致。同时这里也是区块链运用博弈论的精华体现。

后半部说明一种特殊情况,就是说因为分布式网络的特点,信息沟通不是实时性的,所以会出现一些节点认可一个区块而另一些节点认可另一个区块而造成了区块链的分叉问题,但是这里解释了因为所有节点都认为只以最长的链为唯一链,所以这种情况会在多链几个区块后被打破,发生区块重组

新交易的广播到所有的节点上是不必要的。只要交易到达了许多节点上,它们就会进入到一个区块中(在最长的区块中(beforelong))。区块广播是有容忍丢失信息的能力的。如果一个节点没有收到一个块,它就会在收到下一个块的时候发现缺失了它并请求这个丢失的块。

这段是对上段的一个补充,说明了51%(大多数)的重要性,这个大多数并不会以一个直观的数字体现,而是因为所有人都认可最长链,随着时间的迭代而慢慢迭代出来。

同时这里提到一个关键的地方是:“新交易的广播到所有节点是不必要的”,这里旗帜鲜明地表明白了交易是不需要泛洪的。因为想扩散交易本身的信息,在区块链系统中可以不止扩散交易,还扩散区块。而区块被扩散是系统中的“规则”(达到最长链)。我认为这可以带来分布式系统中的一些新的思考。

6.激励机制(Incentive)

按照惯例(进行约定),一个块中的第一个交易是一个特殊交易,它由这个块的创造者拥有一个新货币起始。这样提供了一种激励机制让节点们能够支撑这个网络,并且提供了一个方式来初始化的分发货币进入整个系统当中。因为没有一个中央授权机构来发布他们(货币)。稳定增加一定数量的新货币类似于黄金矿工花费资源开采黄金并引入循环系统当中。在我们的情境下,CPU时间和电力就是被花费的。

这段终于说明前面一直回避的一个问题:货币从哪来?在bitcoin的系统中,中本聪已经规定了总量就是2100W个bitcoin。而这些bitcoin的产生是每产生21000个区块就减半(以现在约定大约每10分钟产生一个区块的速度大约到2140年产生为0)。而bitcoin产生的方法就是给抢到记账权的人凭空给予一定量的货币,这样就同时解决的货币发行和矿工记账的奖励(就像现实中挖黄金的黄金矿工一样)。这这种凭空奖励的方法,就是每个区块的第一交易,是一个特殊的交易,这个交易就是只有Input,且对于输入这个input的output(前一个交易的output)是个空(后文会提到)。因为在第2章的注解中已经说到,coin是不存在的,coin是由tx推断出来的。就像A给B 100块钱,在记录这个信息的时候可以记录A的“账户-100,B的账户+100”这个事物,也可以记录”A给了B 100块钱“这一条交易信息。区块链选择了后者。而这个凭空出现的钱,就是一条特殊的交易信息,

这种激励机制同样可以以交易手续费的方式奖励。如果一个交易的输出值小于其输入值,那么这个差值就是交易的手续费,手续费被附加到包含这个交易的区块的奖励中。一旦一个已决定数目的货币(所有货币)进入这个循环中,这个激励机制就可完全的转变为交易手续费并且本系统可以完全避免通货膨胀(货币总数一定,没有发行货币)。

这部分就解释激励机制的另一个部分,就是除了凭空奖励以外,手续费也是矿工的一个收入来源。

激励机制可能会帮助鼓励节点们保持诚实。如果一个贪婪的攻击者能够收集到比起所有诚实节点更多的CPU算力,他就面临 一个选择:要么用这个算力来用于二次支付来欺骗别人,或者使用算力来生成更多的货币。他应该会发现跟着规则来能获得更多的利益,这样的规则支撑他比起其他加入进来的人能够拥有更多的货币,而不是破坏这个系统使得自己的财富受损。

这里就体现出前文讨论的博弈关系。

7.回收硬盘空间(Reclaiming Disk Space)

一旦一个货币最新的交易收入(buried)进入足够的区块中,那么在这个交易前面被消费过的交易就能够被抛弃来节省硬盘资源。为了同时确保不损害区块的hash,交易被hash为一棵Merkle Tree7[5],这个Merkel Tree只有root节点被包含进了这个区块的hash。老的区块能够被压缩通过将这个树的分支进行拔除(stubbing off branches of thetree)。而内部的hash是不必被保存的。

这段是针对区块链系统会不断产生的区块问题的一个解决方案。如截止目前为止(2017/1/28),区块链总数已经超过了90G,虽然存储是越来越不值钱了,但是要普通公众使用是不可能的,因为信息在一直膨胀。这里就体现出区块链系统的精妙之处,它不存储交易,而是使用Merkel Hash Tree的方式存储Root Hash,达到”0知识证明“。个人并不一定需要这个区块,而是具有这个区块的”hash“(索引)就足够了,有IPFS,公共节点,信任度高节点帮助存储这些区块。”0知识证明“保证了区块是绝对正确的而不是伪造的。

一个剔除交易的区块头大概会是80byte大小。如果我们假设区块每10分钟就生成一个,那么80bytes * 6 * 25 * 365 = 4.2MB 每年。2008 年PC系统通常的内存容量为2GB,按照摩尔定理预言的每年增长1.2GB的大小,即使将全部的区块头存储在内存之中都不是问题。

原文中已经论述的相当清楚了。

8.简化支付认证( Simplified Payment Verification )

认证支付不需要运行所有的网络节点是可能的。一个用户只需要保存最长工作量证明链的区块头部的拷贝就行,这条链他只需要查询网络节点直到他确信他拥有最长链为止,并能够通过merkle的分支连接到它(这个用户的交易transaction)被加上时间戳的那个区块中的那次交易。他无法自己检查这笔交易(因为只有hash),但是通过连接到链中的位置,他可以看到一个网络节点曾经接受过它(那笔交易),并且在它后面增加的区块也进一步证明网络曾经接收过它。

而回收硬盘空间所带来的问题就是简化支付认证的问题,因为有些节点已经不会持有全部区块信息,这里相当于是一个博弈了,使用空间换认证的便捷。但总之是不会再信息的安全性上出问题的。因为只要持有了hash作为标识,无论什么节点总是能从其他节点上请求到原始信息。

该图表明只要有hash链就行。

这样的情景下,如要诚实节点控制了网络,那么这个验证就是可靠的,但是当一个算力占优的攻击者控制网络的时候就变得更容易受攻击了。因为网络中的节点能够自己进行验证的时候,这个简化的方法能够被攻击者伪造的(fabricated)的交易欺骗,当这个攻击者能够持续保证超过全网的算力的时候。一种保护的策略是接受网络节点们的警告,当这些网络节点监测到一个非法的区块,提醒用户软件去下载这个有问题的全部区块,并警告交易去检查确认一致性。频繁收到支付信息的商业机构可能会仍然运行他们的全节点以保持更加独立的安全性和更快的验证。

这种机制感觉有点像是打补丁的方式。。但是好像确实是要削减硬盘存储的一个解决方案,是存储与安全便捷的一个博弈结果。很可能有机会在这里做文章,或许是区块链运用推广的一个障碍。因为要是保留区块的节点太少了就有可能造成问题。虽然不能窃取篡改网络,但是却可导致崩溃。(当然不是说bitcoin网络,是说一些小型区块链网络)

9.组合和分割价值(Combining and Spliting Value)

虽然可以独立的处理货币,但是在一次转账中为每一分钱都成为一个分离的交易是不明智的(就是说coin不是由元单位组合起来的)。为了允许价值能够分割和组合,交易包含了多个输入和输出。正常情况下会有一个从前面一大笔交易而来的一个单笔输入或者包括很多更小总数的多笔输入,然后最后会有两笔输出,一个是付款,另一个是找零,不管有多少,全部都返回购买者。

这里段终于说到了一个交易(Tx)的构成,前面的论述已经说了很多,只要抓住一个关键点就新:一个交易是由前面的交易进行验证,加上转移的数目和目的地构成。inputs就是之前的交易的outputs。对所有的inputs进行验证,就可得到该交易的付款者的余额是否大于要转移的数目。inputs关联的所有Tx就是之前的”历史信息“,节点可检索自己的区块获得结果。每个区块的第一个交易(激励交易)就相当与只有Input而没有output。

这里要注意的额外一点就是:每次的交易必须被花完,只不过是所有input的综合,其中一部分给了收款方,而找零则是全部返回到购买者上(回想下前文阐述的铸币厂的工作流程)。这种机制在数目的分割上有天然优势。现有的货币总是有一个最小单位作为”元“单位(比如人民币:1分),但是bitcoin却没有这样的限制,它只关心差额,而不关心最小元单位。所以这就是价值的组合和分割。

应该被注意到那个全部分配(fan-out),这里一个交易依托几个交易,然后这里交易又依托于更多的。这不是个问题。这里是没有必要去提取交易历史的完整独立副本。

这里略难翻译,我不是很清楚这里的 fan-out 指代的是什么。

10.隐私(Privacy)

传统的银行模型实现隐私的等级是通过限制访问信息给相关的参与者和第三方。当需要将全部交易公开广播的时候,就不能使用这种方法了。但是隐私仍然能够被维护通过打破在另一个地方的信息流:通过使公钥匿名的形式。公众可以看到有一个人发送了一笔数目给另一个人,但是没有信息能把交易和人联系在一起。这和股票交易中释放的信息等级类似,在股票交易中公开发布的时间和个人的交易是记录在案的"tape",但是是不会告知是谁参与进来。

这里指出使用公私钥的机制是一种伪匿名化。

作为附加的防火墙(防范机制),在每次交易中都使用一个新的密钥对能够保证把这些密钥和一个人联系起来。一些多笔输入的交易的联系仍然是不可避免的,因为在这点(多笔输入)揭示了上这些输入是属于同一个人的。风险就在于,如果只要其中一个key的拥有者被发现了,那么相关联的属于这个人的其他交易也会被揭示。

这里原文中推荐这样做是相当有道理的。因为椭圆加密算法是能被量子暴力破解的,在整个系统中要是产生的转账公钥是被公开的。虽然从密码学上不应该从公钥推导到私钥,但是还是有例外嘛。所以这里中本聪强烈建议,一次转账就使用一对新的密钥对(因为交易只要被作为inputs后那么作为inputs的交易也就没用了(注意9提到的找零机制,每笔都花完)),那么就可以保证每次都是新的公私钥进行交易。

后半段是说对于公私钥和现实中的人的对应关系(匿名性失效)的问题,换钥匙同样可以防止这点发生,但是要注意因为所有的记录的全网可查的,所以要是其中一个公私密钥和人对应起来了,那么所有关联的公私密就能和这个人对应起来。

11 计算(计算)

我们考虑这样一个场景:一个攻击者尝试去生成一个比现在最诚实链还长的替换链。即便这样是可完成的,这也不会抛出这个系统就被任意控制了,比如像凭空创造价值或者拿去本来不属于攻击者的钱。节点是不会接受无效的交易作为支付的,并且最诚实链从不会接受一个包含无效信息的区块。一个攻击者只可以尝试去改变他自己的一个交易去拿回他最近花掉的钱。

最诚实链和攻击者链的竞争可以看作是一个Binomial RandomWalk(二叉树随机漫步)。成功事件是最诚实链扩大了一个区块,使其+1领先(lead),同时失败事件是攻击者链扩大一个区块,使得-1差距(gap)。

攻击者赶上给定的亏损的可能性可以看作是一个 Gambler's Ruinproblem(赌博破产问题)。假定一个有无限的信用赌徒从一个亏损开始并且进行潜在无限次的尝试想要追上保本。我们可以计算他达到保本的可能性(概率),就是一个攻击者要追上最诚实链,如下所示:

P=诚实链发现下一个区块的概率

q=攻击者发现下一个区块的概率

qz=攻击者花费了z个区块追赶上了

我们假设p>q,那么攻击者追上的概率就会随着区块的增加而指数型下降。因为胜算是和他相违背的,如果他不能相当幸运的在早期就赶上,他成功的几率就会变得更小随着他落后更多。

我们现在考虑一个新的交易能够被充分的确认让发送方不能再更改交易的情况要等多久。我们假设付款方就是一个攻击者,他想要要收款方认为他已经付过款了并且之后把这个钱在付款后拿回来,收款方当这件事情发生的时候会被通知警告,但是付款方希望这件事情很久才发生。

接收方生成了一个新密钥对并把这个公钥给了付款方在付款方前面前很短的时间。这样就阻止了付款方能够事先准备好一个在时间之前的区块链,通过持续的工作直到他足够幸运的走到了很前面,然后在那时执行了这个交易。一个这个交易被发送,这个不诚实的发送者开始为包含替换他交易的版本的并行链 秘密工作。

接收者一直等到这个交易被加入到区块中并且之后z个区块被附加到着之后。他不知道攻击者已经做的确切的过程总数(已经做了多少个块),但是假设诚实链耗费可预期的平均时间产出一个区块,那么攻击者的潜在进展就是一个泊松分布,分布的期望值是:

为了得到攻击者能追上的概率,我们将泊松密度乘以他可以从该点追上的概率的每个进展数

为了避免求无穷极速我们重新整理

转换成c代码:

#include<math.h> 
doubleAttackerSuccessProbability(double q, int z){
      double p= 1.0 - q;
      doublelambda = z * (q / p);
      doublesum = 1.0;
      int i, k;
      for (k =0; k <= z; k++)
      {
             doublepoisson = exp(-lambda);
             for (i = 1; i <= k; i++) 
                   poisson *= lambda / i; 
                   sum -= poisson * (1 - pow(q / p, z - k));
      }    
      return sum; 
}

运行得到结果,我们可以看到概率随z的指数下降。

q=0.1

z=0 P=1.0000000

z=1 P=0.2045873

z=2 P=0.0509779

z=3 P=0.0131722

z=4 P=0.0034552

z=5 P=0.0009137

z=6 P=0.0002428

z=7 P=0.0000647

z=8 P=0.0000173

z=9 P=0.0000046

z=10 P=0.0000012

q=0.3

z=0 P=1.0000000

z=5 P=0.1773523

z=10 P=0.0416605

z=15 P=0.0101008

z=20 P=0.0024804

z=25 P=0.0006132

z=30 P=0.0001522

z=35 P=0.0000379

z=40 P=0.0000095

z=45 P=0.0000024

z=50 P=0.0000006

求解令P<0.1%的z值:

P <0.001

q=0.10 z=5

q=0.15 z=8

q=0.20 z=11

q=0.25 z=15

q=0.30 z=24

q=0.35 z=41

q=0.40 z=89

q=0.45 z=340

这里就是指明,等6个区块是绝对稳妥的方法。

12.结论

我们提出了一种不依赖信任的电子交易系统。我们从由数字签名构成的通常的货币框架开始,这提供了一个拥有关系的强控制,但是没有办法解决双重支付的问题。为了解决这个问题,我们提出一种使用工作量证明机制的p2p网络来记录一个公共的交易历史,这种机制变为了当大多数节点控制主要的CPU算力,那么攻击者想要改变是在计算上不可能的。网络在其非结构化简单性方面是鲁棒的。节点只需要很少的协同就可以共同工作。他们不需要被认证,因为信息不需要被路由到某个特定的地方而是只需要被尽可能的被发送出去。节点可随意离开或重加入网络,接受工作量证明链作为当这个节点离开后发生事件的证明即可。他们根据CPU算力投票,表示接受合法的区块通过扩展这个区块,拒绝接受非法的块通过拒绝在这个块后工作。任何需要的规则和激励都可以通过这种共识机制来执行。

这个等有空补吧。。



终于完了,现在都超过时间了,总之算不上食言吧,4条我已经完成了3条了,还是有点小激动的hhhhhhh

学习bitcoin源码--写在开头
编辑于 2017-06-16