# 以太坊白皮书中文翻译加详解【全文汇总版-1】

By [Jef](https://paragraph.com/@jef) · 2021-10-19

---

**1、【标题】**

标题：一个下一代的智能合约和去中心化应用平台。

首先，以太坊是next generation，下一代，那么上一代是谁，当然是Bitcoin比特币。

以太坊自称下一代，于是人们把它称为区块链2.0，而比特币就成了区块链1.0。

然后，以太坊是一个platform，是一个平台，Vitalik把以太坊定义成一个平台，而没有定义成一个application应用，或者像中本聪那样，定义成一个system系统。

平台是干嘛的，在互联网领域，平台泛指平台指进行某项工作所需要的环境或条件，也就是我们常说的，计算机硬件或软件的操作环境、运行环境，是承载各种软件或者应用的基础设施。

比如，操作系统windows是个平台，工程师在windows上面开发出各种应用，比如QQ，然后我们终端用户，也就是C端用户，在windows平台上来使用QQ。同样的，ios是苹果手机的系统平台，程序员在ios上开发出各种app，比如手机百度、手机淘宝、微信，然后我们用户在苹果手机上使用这些app。而以太坊做的，就是类似windows和ios这样的平台。

那以太坊这个平台拿来干嘛的？拿来跑smart contract和decentralized application，即智能合约和去中心化应用。

smart contract智能合约是什么？

首先看合约是什么？

合约，即合同，《合同法》定义是，双方或多方当事人（自然人或法人）关于建立、变更、消灭民事法律关系的协议。合同有时也泛指发生一定权利、义务的协议，又称契约，如买卖合同、师徒合同、劳动合同以及工厂与车间订立的承包合同等。

也就是说，平等的合同主体经过意思表示一致，达成了某种受法律保护的权利义务关系。

合约怎么又“智能”了呢？

传统的合约关系，依靠的是国家法律强制力的保障，即当其中一方违约时，有第三方权威机构比如法院、仲裁机构，对违约方按照合约约定进行制裁和惩罚。

而“智能”，就体现在，合约无需依靠权威第三方来担保和执行，而是依据代码和程序的预先设定，在某种行为发生或者某些条件达成时，由程序或系统自动执行合约约定。

举个最简单的例子，我把房子抵押给你，向你借了一笔款，结果借款到期我不还，你要收我的房子的产权，但我就是老赖。你怎么办？传统办法是，你向法院提起诉讼，由法院来强制执行。但这时我玩起人间蒸发呢？这事儿会不会永远拖下去呢？

而智能合约智能的地方，就在于，我向你借款时，就把我的抵押物即房子所对应的产权归属预先通过程序设置好，当达到我逾期不还钱这个条件时，程序就自动把我房子的产权划到你名下，我们去房管局查房产证，就发现妈蛋这房子已经写上了你的名字，就不是我的了，这就不需要法院等第三方权威机构来介入了。

这里，我们看，执行这种智能合约，需要有先决条件，比如，第一，我的房子对应的产权要在这个系统这个平台上通过数字资产或者其他形式表现出来。第二，条件的预设，必须是双方意思表示一致的，而不是某一方单方面去预设某些条件而对方不知情。第三，我的产权对应的数字资产或其他形式的资产，上链时就必须准确无误。因为不可篡改是区块链的核心特征，要是一开始数据就错了，后面又改不了，怎么办。

decentralized application去中心化应用是什么？

decentralized application简称Dapp。我们知道app是各种应用，微信、QQ、支付宝什么的，我们电脑上、手机上各个小图标，就是各种app。这些app又称中心化应用，中心化，就是这些app是某个公司开发的，受控制与某个公司的。公司，就是中心。

那Dapp呢？举个例子秒懂！

把微信app的程序写在区块链上，开源，让全世界参与的节点共同来维护微信所有数据，腾讯对微信没有了控制权，任何人也别想对微信有控制权，微信社区完全开放、自治，微信所有数据加密后存在区块链上，整个微信社区中流通着wcc\[WeChatCoin，微信币\]……

之前市面上的区块链DAPP主要有游戏和挖矿等。比如2017年出现的以太猫CyptoKitties，之后又出现的蹭热度的百度莱茨狗、小米加密兔等区块链宠物游戏。

那Dapp究竟有什么用？

这不全世界最聪明的码农都还在探索嘛，别急！

**2、【前言】**

当中本聪在2009年一月第一次启动比特币区块链时，他同时引入了两个激进的未经测试的概念。

第一个是“比特币”，一种去中心化的点对点在线货币，这种货币能够维持一种价值，在什么条件下维持价值呢，在没有任何支持，本身又没有任何固有价值，又没有中心化发行方的情况下。

> 就是说，比特币生产出来时本身不具备任何价值，也没有中央银行来发行它，也没有任何权威或者中心来给它背书，但它就能维持一种价值。这种价值当然不是指它的固有价值，比如黄金，它是贵金属，开采出来它就有固有价值。而这种比特币这种价值是指它的使用价值，流通价值。

当目前为止，“比特币”作为一种现金单位，已经吸引了大量的公众注意，在哪些方面引人注意呢，在两方面都引人注意，一，在政治层面上，这种现金没有中央银行发行；二，它的价格巨幅波动。

但是，\[与比特币\]同样重要的是，中本聪伟大实验的另一方面：即，基于工作量证明的区块链让人们对交易顺序达成共识，这样一个概念。

作为一种应用，比特币可以被描述为一种先申请\[first-to-file\]系统：如果一个人有50个比特币，同时发送这50个比特币给A和B，那么只有第一笔得到确认的交易会被处理。

没有一种固有的方法来决定两笔交易哪一笔先到，这个问题阻碍了去中心化数字货币发展很多年。

中本聪的区块链是第一个可信的去中心化解决方案。

那么现在，注意力迅速开始转向比特币技术的第二部分，即区块链概念如何被用于货币之外的事情。

通常被提及的应用，包括使用区块链的链上数字资产来代表定制货币和金融工具 ("颜色币")，相关物理设备("智能资产")的所有权，非同质资产例如域名 ("域名币")，以及更多先进的应用例如去中心化交易所、金融衍生品、点对点赌博和区块链的链上身份和信誉系统。

> 看懂木有啊？梳理一下吧。  
> 以下这些，都是Vitalik说的，经常提到的应用：  
> 1、区块链的链上数字资产来代表定制货币和金融工具 ("颜色币")  
> 这是神马玩意儿？这是指，可以和实物相联系的币被称为彩色币。比特币脚本语言允许存储少量的metadata(信息)，这段信息可以用来代表现实生活中的实物，也就是说现实生活中的实物和区块链上的彩色币联系起来。  
> 大体是在比特币协定之上叠加新的协定，有点像互联网协议栈中，HTTP叠加于TCP/IP之上的方式。比如，彩色币发行者确定一个给定的交易输出 H:i(H为交易的杂凑值，i为输出序号)，代表一种特定的资产，并且发布一个所谓的“色彩定义”，就是指定该交易输出代表什么(例如H:i中的1聪 = 1盎司可由[http://amagimetals.com](https://link.zhihu.com/?target=http%3A//amagimetals.com)兑付的黄金)。然后用户在彩色币用户端装色彩定义档。当该“色彩定义”首次发布的时候，输出H:i是拥有该彩色的唯一交易输出。  
> 彩色币这部分在白皮书下面的History的Alternative Blockchain Applications部分会再次提到。  
> 2、相关物理设备("智能资产")的所有权  
> 这就是智能合约里面对应的实体物理资产的产权  
> 3、非同质资产例如域名 ("域名币")  
> 稀缺的、难以复制的、独一无二的、有唯一性的、用户享有绝对所有权的资产  
> 4、去中心化交易所、金融衍生品、点对点赌博和区块链的链上身份和信誉系统

另一个咨询到的重要领域是“智能合约”——能够根据随意预先设定的规则，自动转移数字资产的系统。

例如，一个人可能有一份存储合同长这样：“A每天可以提取X个单位的现金，B每天可以提取Y个单位的现金，A和B一起来的时候可以任意提取没有限制，并且A可以关闭B的提现权”。

这个合约符合逻辑的扩展就是去中心化自治组织 (DAOs)——长期智能合约，这个智能合约包含这个组织的所有资产，并且将组织的规章制度编成代码。

> 解释一下，一个去中心化的组织(DAOs)，这个组织的一切行为都是基于数字化的，组织的所有运行规则都是按代码设置执行的，组织的所有资产也都是数字资产。它实际上是一个硬编码规则体系，而那些不是DAOs的组织，虽然也是基于区块链平台，但是决策和行为可能是由持有一定数量的代币或智能合约的“股东”来制定和执行的。  
> DAOs的一大优势在于，部署的代码和智能合约不容易被操纵或访问，这样可以最大程度地减少欺诈、作假、腐败等风险，但是如果规则需要与时俱进，或者优化升级，想要调整代码就难了，因为它的决策是通过电子方式，通过代码规则或所有成员投票来决定的。

以太坊想要提供的是这样一个区块链，它内置成熟的图灵完备的编程语言，能够被用来创建“合约”，这种合约可以被用来对任意状态转换功能进行编码，从而允许用户创建以上所述的任意系统，以及许多其他的我们还没有想象到的系统，这些只需要写几行代码来实现这些逻辑就OK了。

> 图灵，以Alan Mathison Turing阿兰·图灵（1912年6月23日－1954年6月7日）的名称命名的。阿兰·图灵是英国计算机科学家、数学家、逻辑学家、密码分析学家和理论生物学家，被视为计算机科学与人工智能之父。  
> 图灵完备，如果一门编程语言或者一个指令集，可实现图灵机模型里面全部的功能，或者说能够满足任意数据按照一定顺序计算出结果；我们就可称其具有图灵完备性。以太坊是一个图灵完备的区块链系统，虚拟机可运行智能合约，理论上能够解决所有的可计算问题。

合约可以被用来对任意状态转换功能进行编码之后，用户才可以创建出以上所述的各种系统。

**3、【历史】**

去中心化数字货币的概念，以及像财产登记之类的替代应用，已经被提出来很多年了。

1980年代和1990年代的匿名电子现金协议，很大程度依赖一种叫乔姆盲签名的密码学原语，这种匿名电子现金协议为货币提供了高度的隐私性，但是这种协议没能大规模地应用起来，因为它依赖一个中心化的媒介。

> **盲签名**  
> 发布消息人先将消息盲化，让签名人对盲化的消息进行签名，最后，消息接收人对签字除去盲因子，得到签名者关于原消息的签名。盲签名就是接收人在不让签名人获取所签署消息具体内容的情况下，采取的一种特殊的数字签名技术。签名人对其所签署的消息是不可见的，即签名人不知道他所签署消息的具体内容，而签名消息也不可追踪，即当签名消息被公布后，签名人无法知道这是他哪次签署的。  
> 打个简单的比方，A要寄一封信，封在信封里，但是要让B在信上签名，又不要B看见内容。怎么办？在信封里同时加入一张复写纸，于是B在信封上签名，信封里面的信上就同时印下了B的签名，这时B既没有看见信的内容，同时又在信上签了名。  
> 另一点，A寄了很多信，都有B的盲签名，当公布出其中一封信时，B也不知道这是他哪次签的名。  
> \[翻译注意：1、provided指的是e-cash protocols provided，不是指cryptographic primitive provided或者Chaumian blinding provided，2、mostly reliant on a cryptographic primitive known as Chaumian blinding这句话只是插入语，修饰一下anonymous e-cash protocols，真正的谓语是provided。这里网上有的翻译有点小错误\]

1998年，Wei Dai的b-money第一次提议了通过解决计算难题和去中心化共识来创造货币的思想，但是这个提议在细节上还有缺陷，即去中心化共识如何去实施。

2005年，芬尼（Hal Finney）介绍了“可重复使用的工作量证明”这一概念，即一个采用了两种方案的系统，哪两种方案？1、b-money的理念；2、亚当贝克（Adam Back）的通过有计算难度的哈希现金难题来创造加密货币的概念。但是\[芬尼的这个概念\]还是不够理想，因为它依赖可信的计算来支持。

> Wei Dai的b-money和亚当贝克（Adam Back）的Hashcash在比特币白皮书翻译与详解里面都有，不累述。

因为货币是一种先申请应用，\[上一篇说了，first-to-file先申请是指，假如如果一个人有50BTC，并且同时向A和B发送这50BTC，只有被首先被确认的那笔交易才会有效\]，那么这种先申请应用，交易顺序通常就至关重要，去中心化货币就需要解决达成去中心共识的问题。

比特币之前的货币协议遇到的主要障碍是，尽管多年以来已经有大量的关于创造安全的拜占庭容错多方共识系统的研究，但是所有的协议都只解决了部分问题。

> **Byzantine-fault-tolerant拜占庭容错**  
> 拜占庭帝国进攻敌国，敌国能抵御5支拜占庭军队，拜占庭帝国派出10支军队，这10支军队任何一支单独去进攻都毫无胜算，除非有至少6支军队（一半以上）同时进攻，才能攻下敌国。  
> 10支军队分散在敌国的四周，依靠通信兵骑马相互通信来协商进攻意向及进攻时间。问题来了！他们不确定他们中是否有叛徒。叛徒可能擅自变更进攻意向或者进攻时间。在这种状态下，拜占庭将军们怎么才能保证有6支以上军队在同一时间发起进攻，从而攻下敌国？假定军队之间的通信毫无问题。  
> 没有叛徒情况下：  
> 假如一个将军A提出一个进攻提议（比如：明天上午9点进攻，你愿意加入吗？）由通信兵分别告诉其他的将军。  
> 如果幸运，A将军收到了其他5位将军以上的同意，发起进攻。  
> 如果不幸，其他将军在此时发出不同的进攻提议（比如：明天上午10点、11点进攻，你愿意加入吗？）。由于时间上的差异，不同的将军收到并认可的进攻提议可能是不一样的，这是可能出现A提议有3个支持者，B提议有4个支持者，C提议有2个支持者等等。  
> 有叛徒情况下：  
> 一个叛徒通信兵会向不同的将军发出不同的进攻提议（比如，通知A明天上午9点进攻， 通知B明天下午1点进攻）。  
> 而一个叛徒将军也可能同意多个进攻提议（即同意明天上午9点进攻又同意明天下午1点进攻）。  
> 这种发送前后不一致的进攻提议，被称为“拜占庭错误”。而能够处理拜占庭错误的这种容错性，就称为拜占庭容错，Byzantine fault tolerance，简称为BFT。  
> 这些协议假设系统里所有的参与者是已知的，并且产生安全边界，什么安全边界呢，即“如果N方参与，那么系统可以容忍N/4的恶意参与者。”  
> 也就是说，比特币出现之前的那些电子现金协议，都设置了一个多方参与多方共识的容错机制，即假设N个人参与进来，他们不是匿名的，而是已知的，那么系统最多可以容忍四分之一的人搞破坏。只要搞破坏的人不超过四分之一，那么这个系统还会运行良好。  
> 但问题是，在一个匿名的环境里，这样的安全边界对**女巫攻击**是脆弱的，也就是容易受到女巫攻击，因为一个单一的攻击者可以在服务器或**僵尸网络**上创造上千个冒充节点，然后用这些节点来单方面控制大多数份额。  
> **sybil attack 女巫攻击**  
> 在P2P网络中，因为节点可以随时加入或退出，那么为了维持网络稳定，同一份数据通常需要备份到多个分布式节点上，这叫做数据冗余机制。  
> 如果网络中存在一个恶意节点，它可以通过控制多个虚假身份，然后利用这些身份控制或影响网络的其他正常节点。比如，原来需要备份到多个节点的数据被欺骗地备份到了同一个恶意节点（该恶意节点伪装成多重身份），这就是女巫攻击。  
> 女巫攻击出自Flora Rhea Schreiberie在1973年的小说《女巫》（Sybil）改编的同名电影，讲的是一个化名Sybil Dorsett的女人被诊断为分离性身份认同障碍，兼具16种人格，分裂出16种身份。  
> **botnet 僵尸网络**  
> 互联网上受到黑客集中控制的一群计算机，被黑客用来发起大规模的网络攻击，比如分布式拒绝服务攻击（DDoS）、发送海量垃圾邮件等，同时黑客控制的这些计算机所保存的信息也都可被黑客随意“取用”。  
> 前面那句话就是说，在匿名环境下，比特币出现之前的那些电子现金协议，都是不可靠的，太脆弱。

中本聪的创新之处在于，他的这个想法结合了两样东西，哪两样呢？1、一个非常简单的去中心化共识协议，基于节点每10分钟打包交易进入区块来创造一条持续延长的区块链；2、节点通过获取记账权来才能参与系统的工作量证明机制。

当拥有大量计算能力的节点确实有了相应的更大影响力，那么你要是想搞出比全网算力加起来还大的计算能力，就比仿照100万个节点还难。

> 也就是说，当诚实节点控制了大系统多数，那这时你想搞出更大的算力来超所有诚实节点的算力，或者说超越全网算力，这个太难了，比你搞100万个假节点还难。  
> 也就是，中本聪的创新之处在于，当诚实节点控制了大多数，系统就会安全。因为系统基于两点来运行，1、认可最长链；2、通过竞争工作量来获得记账权。（不明白仔细看[比特币白皮书翻译加详解](https://zhuanlan.zhihu.com/p/46226505)）

尽管比特币区块链模型很简单粗糙，但是它已经被证明足够好，并且可能在未来五年成为全世界超过200种数字货币和协议的基石。

**3.1【比特币作为一种状态转换系统】**

从技术角度讲，比特币账本可以被看作一个状态转换系统，这个系统里面有一种“状态”，包含了：1、所有现存比特币的所有权状态，2、一个“状态转换函数”，这里面就包含了一种状态和一笔交易，然后可以输出为一种新的状态作为结果。

![](https://storage.googleapis.com/papyrus_images/477302cf9574b4205aa684bd1ae7d1fcbbf20e9a307a6b32006ccc95e75a3054.jpg)

> 上图，State是前一种状态，里面包含若干地址，中间是一个状态转换系统，也就是交易过程，在原地址上进行增减和签名， State'是交易后得到的原地址新状态，因为交易后账户余额有变化了。

例如，在标准的银行系统内，状态就是一本资产负债表，一笔交易就意味着一个请求，即把X元钱从A转给B，同时状态转换系统在A的账户减掉X元，在B的账户增加X元。

如果A的账户余额不足X元，状态转换函数就会返回错误提示。

因此，正式定义如下：

APPLY(S,TX) ­> S' or ERROR

这个函数的意思是，检查交易的格式是否正确（即有正确数值）、签名是否有效、随机数是否与发送者账户的随机数匹配。如是，通过；如否，返回错误。

而在银行系统内定义如下：

APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30, Bob: $70 }

But:

APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR

当Alice和Bob的账上各有50美元时，如果Alice转给Bob20美元，返回结果为Alice账上有30美元，Bob账上有70美元。

但当Alice和Bob的账上各有50美元时，如果Alice转给Bob70美元，返回结果为错误。

“状态”在比特币系统中是所有已经挖出来但是没有被花费的币的集合(技术上讲，是没有花费的交易输出，unspent transaction outputs，简称UTXO) ，每一个币都有一个面值和一个所有者(由一个20字节的地址，实际上是一个密码学公钥所定义)\[1\]

> 注释\[1\]：一个聪明的读者可能会注意到事实上比特币地址是椭圆曲线公钥的哈希，而非公钥本身。然而事实上从密码学术语角度把公钥哈希本身称为公钥是完全合理的。这是因为比特币密码学可以被认为是一种定制化的数字签名算法，公钥由椭圆曲线公钥的哈希组成，签名由椭圆曲线签名连接的椭圆曲线公钥组成，而验证算法包括用作为公钥提供的椭圆曲线公钥哈希来检查椭圆曲线公钥，以及之后的用椭圆曲线公钥来验证椭圆曲线签名。

TX : Transaction（交易）

TXO : TX output（交易输出）：包含一个value值和一段脚本，该脚本规定了谁有权使用这笔交易（比如需要私钥签名）。

UTXO： Unspent TXO（未花费的交易输出）：只有对“尚未使用过”的交易签名才能是有效签名。

数字货币无法像金属货币（比如黄金）那样，仅靠物理转移即可转移所有权，即当A将一份黄金交给B后，A必然不再拥有这份黄金。

而A将一份数字货币转给（签名）B后，A仍可以把同一笔交易转给C，因为A掌握私钥，这两份签名均为有效签名，这就构成了“双花”。因此必须有一种机制来确保每笔交易只能使用一次，即只有对“尚未使用过”的交易签名才能是有效签名。

UTXO，未花费的交易输出，是比特币交易生成及验证的一个核心概念。因为所有比特币交易构成了一组链式结构，每笔交易都可以回溯到一个或多个交易的输出，而这些链条的源头实际上都是挖矿奖励，末尾则是当前未花费的交易输出。所有的未花费的输出即整个比特币网络的UTXO。

因为比特币每一笔新的交易的输入必须是某笔交易未花费的输出，每一笔输入同时也需要上一笔输出所对应的私钥进行签名，并且每个比特币的节点都会存储当前整个区块链上的UTXO，整个网络上的节点通过UTXO及签名算法来验证新交易的合法性。这样，节点不需要追溯历史就可以验证新交易的合法性。

一笔交易包含一个或多个输入，每笔输入包含一个对现有UTXO的引用和一个由关联所有者地址的私钥产生的密码学签名。而一个或多个输出，每个输出都包含一个被加入到状态里面的新的UTXO。

状态转换函数APPLY(S,TX) ­> S'可以就被大致定义为：

1、对每个交易输入：

i. 如果被引用的UTXO不在状态S内，返回错误；

ii. 如果签名与UTXO所有者不匹配，返回错误；

2、如果所有输入的UTXO面值总额比所有输出的面值总额小，返回错误；

3、返回状态S当所有UTXO输入被移除及所有UTXO输出被增加时，即当不存在以上错误时，返回到新状态S'，S'里面就已经移除了所有输入的UTXO，增加了所有输出的UTXO。

第一步的前一半防止交易发送者花不存在的币，后一半防止交易发送者花其他人的币，第二步来确保交易前后价值守恒。

为了将此应用与支付，协议如下：

假设Alice想发送11.7个币给Bob。

首先，Alice将寻找一套她已有的UTXO，总数至少要等于11.7个比特币。

事实上，Alice不可能刚好有11.7个比特币，如果假设她能得到的最小数量是6+4+2=12个币的话。

然后她用6+4+2这三笔输入来创建一笔交易，这笔交易有两个输出。

第一笔输出是11.7个币，这11.7个币在Bob的地址上，因为Bob成了这11.7个币的所有者。第二笔输出是剩下的0.3个币，“找零”，所有者还是Alice自己。

**3.2【挖矿】**

![](https://storage.googleapis.com/papyrus_images/e182ea3f4f350be0d69db067905a2945505e303e21961c6353423af95f706110.jpg)

如果我们已经接入了一个可信的中心服务，这个系统可能部署起来就普普通通的，它可以轻松通过编码来实现。

但是，比特币呢我们想把它建成一个去中心化的系统，因此我们需要结合状态转换系统和共识系统这两者，以此确保每个人都认可里面的交易顺序。

比特币的去中心化共识处理，需要网络中的节点持续地尝试产生交易包，称之为“区块”，就是持续地把交易打包到区块中。

网络大约每10分钟产生一个区块，每个区块包含一个时间戳、一个随机数、一个对上一区块的引用 (例如hash值)，和一个自上一个区块开始已经发生的全部交易的清单。

如前面的图所示。

这就随时间创造了一个持续的不断延长的“区块链”，它不断的更新，以此代表最新的比特币账本状态。

范例中所表达的，检查一个区块是否有效的算法，如下：

1、检查本区块引用的前一个区块是否已经存在且有效；

2、检查本区块的时间戳晚于前一个区块的时间戳，且早于未来2小时；

3、检查本区块的工作量证明是否有效

4.、用S\[0\]表示前一个区块的最终状态

假设TX是本区块的交易清单，清单里一共有n笔交易。当i=0……n-1时，对所有的i进行状态转换，S\[i+1\] = APPLY(S\[i\],TX\[i\]) 。如果任何又一次转换返回错误，则退出转换，返回错误提示。

如果返回正确，则将S\[n\]视为本区块的最终状态。

本质上，区块里每一笔交易必须有一个有效的状态转换。

注意，状态不是用任何方式去编码进区块的，它纯粹是一个被验证它的节点所记住的抽象概念，从创世状态开始就只能被 (牢牢地) 计算出来，把每一笔交易按顺序加入每一个区块。

另外，要注意矿工把交易打包进区块的顺序；如果在一个区块中有两笔交易A和B，B花了一个由A创建的UTXO，那么如果A在B前面，这个区块有效，否则区块无效。

区块验证算法有趣的部分是“工作量证明”这个概念：情况是这样，对每个区块进行SHA256哈希处理，得到一个256比特的数字，这个数字必须小于一个动态调整的目标数字，写这个白皮书的时候，这个目标数字大概是2的190次方。

这样做的目的是让创建区块从计算上变得困难，从而防止女巫攻击，防止攻击者按对他们有利的方式重造区块链。

因为SHA256被设计为了一种完全不可预测的伪随机函数，创建一个有效区块的唯一办法，就是简单粗暴的不断试错，重复地增加随机数，来看是否新的hash值能匹配上，也就是新的hash值是否小于目标数值。

当前的目标数值是2的192次方，这意味着平均要尝试2的64次方这么多次，才能产生一个有效区块。通常，每过2016个区块后网络会调整这个目标数值，因此网络中的节点会平均每10分钟产生一个区块。

为了补偿矿工的计算工作，每个区块的矿工有资格拿到一笔凭空付给他们的25个比特币。

另外，如果任何一笔交易的输入比输出面值更大，那么之间的差额也就作为了给矿工的“交易费”。

顺便一提，\[对矿工的补偿\]这是比特币发行的唯一渠道，创世状态根本不包含比特币。

为了更好地理解挖矿的目的，让我们看看恶意攻击时会出现什么状况。

因为比特币的底层密码学被认为是很安全的，因此攻击者会攻击比特币系统中没有密码学直接保护的部分：交易顺序。

攻击者的策略很简单：

1、发送100个比特币给商家，买一些商品(特别是一些可以快速传输的数字商品)

2、等待商品寄出

3、发起另一笔交易，把那100个比特币发给他自己

4、试图让网络相信，他的给自己发出的交易是最先发出的

一旦步骤1发生，几分钟后一些矿工会打包交易进入一个区块，假设打包到270000号区块。

大约1小时后，在270000号区块后面有5个区块被加到链上，这5个区块每个间接指向步骤1那笔交易，然后确认它。

这时，商家将接受这笔支付作为最终的，即商家认可支付成功了，然后发货，我们假设卖的是数字商品，秒发货秒收货。

现在，攻击者创建另一笔交易，将这100个比特币发给自己。

如果攻击者只是简单广播这笔交易，交易将不会被处理；矿工将运行(S,TX) 函数，并且注意到这笔交易花费的UTXO已经不再状态中。

那么相反，攻击者会分叉这个区块链，开始把269999号区块作为父区块，在后面挖另一个版本的270000号区块，在此区块中用新的付给自己的这笔交易代替旧的付给商家的那笔交易。

因为区块数据不同，这就需要重做工作量证明。

另外，攻击者挖的270000号新区块的hash值也不同，因此原来的270001到270005号区块不“指向”它，所以，原来的链和攻击者的新链完全是分离的。

规则是，发生分叉时，最长链 (有最大工作量证明支持的链)被认为是真实的，所以合法的矿工会沿着270005号区块继续工作，只有攻击者孤零零的一个人在270000号区块后工作。 (此处画面感十足！)

攻击者为了将他的区块链变成最长链，他将需要拥有比除他之外的全网其余算力更大的算力来追赶(即发起 "51%攻击")。

**3.3【默克尔树】**

左图：这充分表明，在默克尔树里面只要少量的节点就能证明分支的有效性。

右图：企图改变默克尔树任意部分，都将最终导致链上某部分的前后不一致。

![](https://storage.googleapis.com/papyrus_images/62caa0c3901322295a50ff3ff7a91c11d2cb646cf4aabf7af3950a842ed10d91.jpg)

原图

> 结合图梳理一下上面两句话：  
> 每笔交易信息经过hash之后都自下而上串起来，那么从最顶端往下，都能追溯到最初那笔交易，也就意味着，只需要顶部少量的节点，就能往前去追溯到过去的全部交易信息，而不必再保留之前的多余信息，只保留最新的一部分就好了，从而节省硬盘空间。这也是比特币白皮书里，回收硬盘空间那部分提到的内容。  
> 那么这时如果有人企图修改里面某个交易信息，比如右图红色部分，后面的节点就会验证到前后不一致，从而提示错误，不予验证通过。

比特币一个重要的可扩展的特点是，区块存储在一个多层次的数据结构中。

一个区块的hash值只能是这个区块头的hash值，即一段大约200字节的数据，包含了时间戳、随机数、前一个区块的hash值和一个数据结构的根hash，这个根hash就叫做默克尔树，默克尔树存储着区块上所有的交易信息。

默克尔树是一种二叉树，这样构成的：1、一组在默克尔树底部的包含基础数据的大量叶节点，2、一组中间节点，每个中间节点是它两个子节点的hash值，3、一个单一的根节点，也是也是有它的两个子节点构成，代表默克尔树的“顶部”。

默克尔树的作用是，让区块里的数据可以被逐条传输：一个节点可以从一个源头只下载一个区块的区块头，从另一个源头下载相关的默克尔树的其他小部分，并且仍然可以确定所有数据是正确的。

能这样实现，原因是hash值都是向上扩散的：如果一个恶意用户试图在默克尔树的底部伪造一笔交易，这个改变将导致上面节点的调整，然后再上面节点也要调整，最终改变默克尔树的根以及这个区块的hash值，这导致协议会把这个区块记录为一个完全不同的区块（几乎肯定是无效的工作量证明）。

默克尔树协议对\[比特币的\]长期的稳定性来说，无疑是极其重要的。

在2014年4月，比特币网络中的“全节点”，一个“全节点”完整地存储和处理全部区块，需要15G的硬盘空间，并且按每月1G的速度增加。

现在，这样的数据量处理，台式电脑还行，但手机搞不了了。未来不久，只有商业机构和爱好者才会来参与当全节点。

一个被称为“简化支付验证” (SPV) 的协议可以让其他档次的节点也能玩耍，这些节点可以称为“轻节点”，“轻节点”只下载区块头，用区块头验证工作量证明，然后只下载跟他的交易有关的“分支”。

这就让轻节点只需要下载整个区块链的一小部分，就可以安全地确认任意一笔比特币的交易状态，以及他们自己的当前余额。

**3.4【其他区块链应用】**

把区块链思维应用到其他概念上的想法早就有了。

2005年，Nick Szabo提出了“所有权人授权的安全资产”的概念，在他的文档里，描述了“可复制的数据库技术的新进展”如何让基于区块链的系统来存储土地所有权的登记，创建一个包含房产权、违法占地和乔治亚州土地税的详细框架。

但是，不幸的是，那时并没有一个有效的可复制数据库系统，因此该协议并没有被付诸实践。

不过2009年后，随着比特币的去中心化共识被开发出来，大量的其他应用就迅速出现了：

● Namecoin，2010年被创造出来，被描述为一个去中心化的名称注册数据库。

在像Tor、Bitcoin和BitMessage这样的去中心化协议中，需要某些验证账户的方法人们才能互相交互，但是在现有的解决方案中，唯一的账户验证方式是用伪随机的hash值，如1LW79wp5ZBqaHW1jL5TCiBCrhQYtHagUWy。

理想情况下，一个人可能希望有个叫“george”的账户名称。

但是，问题是如果他用“george”这个名字注册了一个账户，然后其他人也可以通过同样的方式再注册叫“george”的账户，然后假装自己是真的“george”。

唯一的办法是用先申请原则，即第一个注册“george”的可以注册，第二个注册“george”的就不能注册了——这个问题可以用比特币共识协议完美解决。

Namecoin是最早，也是最成功的一个使用比特币理念来实施名称注册的系统。

● Colored coins，颜色币，目的是，可以提供服务，提供什么服务，让人们可以在比特币区块链上创建他们自己的数字货币，或者重要的一般意义上有单位的货币即数字令牌。

在颜色币协议里，人们可以通过对一个特定的比特币UTXO公开指定一种颜色，来“发行”一个新的货币，协议能够递归定义其他UTXO的颜色跟交易输入颜色相同 (有一些特定的规则来防止颜色混合输入)。

这就可以让用户的钱包里只含有某种颜色的UTXO，而且像通常发送比特币一样发送这些UTXO，并且通过回溯区块链来验证他们收到的任意UTXO的颜色。

● Metacoins，元币，元币的理念是，元币在比特币之上，用比特币的交易上存储元币的交易，但是有另一种不同的状态转换函数，叫APPLY'。

因为元币协议不能阻止比特币区块上无效的元币交易，因此加入了一个规则，如果APPLY'(S,TX)函数返回错误指令，协议将默认APPLY'(S,TX) = S。

这个先进的特点没能在比特币本身部署，但正是这个特点，为创建一个任意的加密货币协议提供了简单机制，并且开发成本很低，因为复杂的挖矿和网络已经在由比特币协议处理好了。

因此，创建一个共识协议通常有两种方法：1、创建一个独立网络；2、在比特币网络上创建一个协议。

前一种方式，虽然在像Namecoin的应用上相当成功，但是实施起来很困难；每个独立的实施需要一个独立的区块链，以及创建和测试所有必要的状态转换和网络代码。

另外，我们预测，运用去中心化共识技术的一组应用都将遵循一种幂律分布，即大多数应用太小以至于不能保证区块链\[的安全性\]，我们也注意到，现有的大规模的去中心化应用，特别是去中心匿名组织，都需要相互交互。

另一方面讲，基于比特币的办法也有瑕疵，它没有继承比特币可以简化支付验证的特点。

简化支付验证\[SPV\]在比特上管用，因为它用区块链深度作为验证的代理器。从一定程度上讲，一旦一笔交易的祖先离这笔交易足够远时，即被认为这笔交易是状态的合法部分，也即一旦对应这一笔交易的很早的一笔交易来源离这笔交易足够远时，就可以认为它们是合法交易。

另一方面，基于区块链的元币协议，不能强制区块链不去包含那些在他们自身协议里面被认作为非无效的交易。

因此，一个完全安全的简化支付验证\[SPV\]元币协议实施，需要向后扫描全部的区块链直到比特币区块链的开头，来决定某些交易是无效的。

当前，所有基于比特币的“轻”的元币协议，都需依靠一个可信服务器提供数据，，所有基于比特币的元币协议的“轻”实施都依赖可信任的服务器提供数据，可以说这对主要目的之一是消除信任需要的密码学货币而言，只是一个次优\[不是最优\]的结果。

**3.5【脚本】**

即便不进行扩展，比特币协议也可以使一个“智能合约”概念的脆弱版本变得容易实现。

> 即，比特币协议即便不进行扩展，也可以比较容易地实现“智能合约”。

比特币的UTXO不仅能被一个公钥所掌握，也可以被一种更复杂的脚本所掌握，这种更复杂的脚本是用一种简单的堆栈式编程语言表达。

在这种的表达式里面，一笔花费UTXO的交易，必须提供满足脚本的数据。

事实上，即便是基础的公钥所有权机制，也是通过脚本来实现的：脚本将一种椭圆曲线签名作为输入，来验证其是否匹配交易和拥有这个UTXO的地址，如果验证成功，则返回1，如果验证不成功，则返回0。

另外，更为复杂的是，脚本存在于其他不同的使用情况。

> 即，脚本用于其他不同情况则更为复杂一些。

例如，可以创建一个这样的脚本，要求验证交易必须集齐给定三个私钥中的两个私钥的签名("多重签名")，这样的设置对于企业账户、安全储蓄账户和一些商业托管情况，都是非常有用的。

脚本还可以被用于向可计算问题的解决方案支付赏金(也就是向解决计算问题的人支付赏金)，人们甚至可以创建这样一个脚本，就像“如果你可以提供一个简化支付验证证明(SVP证明)，证明你发送了一定面值的Dogecoin狗狗币给我，那么这个比特币UTXO就是你的”，本质上这允许去中心化的跨币兑换(即不同数字货币之间的兑换)。

但是，比特币的脚本语言有一些严重限制：

● 缺乏图灵完备性——就是说，尽管比特币脚本语言支持大量的计算，但它不支持一切计算。

不支持的类型主要是循环语句。

这主要为了避免交易验证过程中出现无限循环；理论上，脚本程序员可以克服这个障碍，因为任何循环语句都可以被轻易模仿，只需多次重复if表单语句的基础代码，但这会导致脚本低效率的利用空间。

例如，实施一个代替性椭圆曲线签名算法，就可能需要256次重复乘法，而每一次都需要单独编码。

● 价值盲——UTXO脚本无法精密地控制取款额度。

例如，oracle contract预言机合约一个强大的应用案例可能是对冲合约，即A和B都发送价值1000美元的比特币给合约，30天后合约脚本发送价值1000美元的比特币给A，把剩下的发给B。

这虽然要求预言机来判定一个比特币值多少美元，但在如今完全中心化的解决方案环境里，这已经是在信任和基础设施需求方面的巨大进步了。

但是，因为UTXO是一个不可分割的整体，要实现UTXO all-or-nothing的整体性，只能通过拥有多种面值的UTXO这种低效的手段(例如，每k最多为30对应一个2^k的UTXO，) ，以及让预言机选择把哪个UTXO发给A，把哪个UTXO发给B。

● 状态缺失——UTXO要么已花，要么没花；那么包含除此两状态之外其他内部状态的多级合约或者脚本就实现不了。

这让多级期权合约、去中心化互换要约或者两级加密承诺协议(有必要用于确保计算赏金的协议)实现起来变得困难。

这意味着UTXO只能被用于创建简单的一次性合约，而不能被用来创建更复杂的“状态”合约例如去中心化组织，UTXO也让元币协议难以实现。

二元状态加上价值盲特征也使得另一种重要应用，取款限额，不可能实现。

● 区块链盲——UTXO看不到区块数据，例如随机数和前一个区块的哈希值。

这个缺陷，剥夺了脚本语言随机性的潜在价值，严重限制了赌博应用和其他类型的应用。

因此，我们看见了在加密货币上创建高级应用的三种方式：1、创建一个新的区块链，2、在比特币系统上使用脚本，3、在比特币系统上创建元币协议。

创建一个新的区块链可以无限自由地实现各种特性，但是开发时间和推进进度都是成本。

使用脚本很容易实现，并且可以标准化，但是能力有限，然后元币协议虽然也很简单，但受制于其可扩展性。

使用Ethereum以太坊，我们就可以创建一个通用框架，同时具有这三种方式的优点。

**4【以太坊】**

以太坊的目的在于，基于脚本、竞争币和链上元币协议三者概念进行整合和提高，让开发者可以创建任意的、基于共识的应用，这些应用具有由以上三种不同范本同时提供的可扩展性、标准化、特性完备、易于开发和协同等特征。

以太坊如何来实现这些的？通过建立本质上是终极抽象的基础层：即一个内置图灵完备编程语言的区块链，这个区块链可以使任何人都能编写智能合约和去中心化应用，并在此之上可以设定他们自己的关于所有权、交易方式和状态转换函数的任意规则。

域名币的基本框架写两行代码就能实现，其他协议例如货币和信誉体系等二十行代码以内也能实现。

智能合约，即包含价值且只能在满足某些条件下才能解锁的加密“箱子”，也能在我们的平台上创建，并且比比特币脚本所能提供的智能合约更为强大，因为它具备图灵完备性、价值知晓特性、区块链知晓特性以及状态。

**4.1【以太坊账户】**

在以太坊中，状态是由被称为“账户”的对象组成的，每个账户有一个20字节的地址，还有可以在账户之间直接传输价值和信息的状态转换器。

一个以太坊账户包含四个部分：

● 随机数，即一个用来确认每笔交易只能被处理一次的计算器

● 账户的当前以太币余额

● 账户的合约代码，如有的话

● 账户的存储空间(默认为空)

“以太币”是以太坊内置的主要加密燃料，用来支付交易费。

通常来讲，有两种账户类型：私钥控制的外部账户，和，合约代码控制的合约账户。

外部账户没有代码，一个人可以通过创建和签名一笔交易来从外部账户发送信息；而在合约账户内，每次合约账户接收到一条信息，代码就会被激活，允许合约账户对内部存储空间进行读取和写入，并且允许发送其他消息或者依次创建合约。

**4.2【消息和交易】**

以太坊里面的“消息”类似比特币里面的“交易”，但是有三点重要不同。

第一，一条以太坊消息既可以被外部实体创建，也可以被合约创建，而一笔比特币交易只能由外部创建。

第二，以太坊消息可以明确选择是否包含数据。

最后，以太坊消息的接收，如果是合约账户，它可以选择回应；这意味着以太坊消息也包含了函数的概念。

以太坊里面的“交易”这个术语是指，被签名的数据包，这个数据包存储了从外部账户发送的消息。

交易包含了消息接收，对发送者签名的验证，以太币的数量和待发送的数据，以及STARTGAS和GASPRICE燃料价格。

为了防止代码的指数级增加和无限循环，需要对每一笔交易设置一个执行代码所引起的计算步骤数量的限制，包括初始消息和代码执行期间引起的任何的其他消息。

STARTGAS就是这个限制，而GASPRICE是按每个计算步骤给到矿工的费用。

如果执行交易过程中“gas用完了”，那么所有的状态将恢复原状——除了已经支付的交易费，而如果交易执行停止还有剩余的gas，那么剩余的gas将返还发送者。

创建合约也有一种独立的交易类型和相应的消息类型；合约地址是基于账户随机数的哈希值和交易数据计算出来的。

消息机制的一个重要的结论是，以太坊的“一等公民”财产——即合约与外部账户在发送消息和创建其他合约等方面拥有同等效力的理念。

这可以使合约同时充当许多不同角色：例如，可以使一个去中心化组织 (这是一个合约) 的一个成员成为一个第三方托管账户 (这是另一个合约)，这个第三方托管账户为偏执地使用定制量子证明兰伯特签名的个人 (这是第三个合约)和一个自身用五把密钥来确保安全使用账户的共同签名实体 (这是第四个合约)提供第三方托管服务。

梳理一下这句话：

这可以使合约同时充当不同的角色：

1、一个去中心化组织，这是一种合约，比如叫A

2、第三方托管，这也是一种合约，叫B，

3、非要使用量子兰伯特签名的偏执狂，这也是一种合约，叫C

4、用五把密钥来共同管理账户的人或者组织，这也是一种合约，叫D

> 以上句子的逻辑是，以太坊合约可以让为A里面的一个成员变成B，然后这个B为C和D提供托管或居间服务。大致是这么个意思。

以太坊的优势在于，去中心化组织和托管合约无需关心合约每个参与方都是什么账户类型。

**4.3【以太坊状态转换函数】**

![](https://storage.googleapis.com/papyrus_images/4e4c4eed5ca7f3551df717f4adbd1f12b9c5204d19d2165851d677f0bfdeffb8.jpg)

原图

以太坊状态转换函数，APPLY(S,TX) -> S'，可定义为如下：

1\. 检查交易格式是否正确（比如有正确的数值），签名是否有效，和随机数是否与发送者账户的随机数相匹配。如否，返回错误。

2\. 计算交易费为，交易费=STARTGAS \* GASPRICE，并从签名中确定发送地址。从发送者的账户余额中减去交易费并增加发送者的随机数。如果余额不足，返回错误。

3\. 设定初值GAS = STARTGAS，并在交易中按每字节减去一定量的gas来支付。

4\. 从发送者的账户转移交易价值到接收者账户。如果接收账户还不存在，则创建该接收账户。如果接收账户是一个合约，则运行合约代码直到代码运行结束或者gas用完。

5\. 如果因为发送者没有足够的钱，或者代码执行中用完了gas，而导致价值传输失败，则恢复原状，不过还是需要支付交易费，并将交易费加到矿工账户。

6\. 否则，将所有剩余gas返还给发送者，将已消耗掉的gas作为交易费用发送矿工。

例如，假设合约的代码如下：

> if ![contract.storage](https://link.zhihu.com/?target=http%3A//contract.storage)\[[msg.data](https://link.zhihu.com/?target=http%3A//msg.data)\[0\]\]:  
> [contract.storage](https://link.zhihu.com/?target=http%3A//contract.storage)\[[msg.data](https://link.zhihu.com/?target=http%3A//msg.data)\[0\]\] = [msg.data](https://link.zhihu.com/?target=http%3A//msg.data)\[1\]

需要注意的是，在现实中，合约代码是用底层以太坊虚拟机（EVM）代码写成的；而为了清晰起见，上面这个合约例子是用我们的高级语言Serpent语言写成的，它可以被编译成EVM代码。

假设合约存储开始为空，一笔价值10以太币的交易，gas为2000，gas价格为0.001以太币，并且两个数据字段\[ 2, 'CHARLIE' \]。注：第一个三十二字节代表号码2，第二个代表CHARLIE。这样一笔交易发送后，

. 状态转换函数的处理过程如下：

检查交易是否有效，格式是否正确。

2\. 检查交易发送者至少有2000\*0.001=2个以太币。如果有，从发送者账户中减去2个以太币。

3\. 初始设定gas = 2000，假设交易为170字节长，每字节的费用是5，减去850所以还剩1150 gas。

4\. 从发送者账户再减去10个以太币，给合约账户增加这10个以太币。

5\. 运行代码。在这个例子中，运行代码很简单：它检查索引2处的合约存储是否已使用，注意到它未被使用，然后将检查索引2处的合约存储的值设为CHARLIE。假设这消耗了187gas，于是剩余的gas为1150 - 187 = 963。

6\. 向发送者的账户增加963\*0.001=0.963个以太币，然后返回结果状态。

如果没有合约接收交易，那么所有的交易费仅仅等于GASPRICE乘以交易的字节长度，交易数据就与交易费用无关了。

另外，需要注意的是，合约发起的消息可以对它们产生的计算分配gas限额，如果子计算的gas用完了，它只恢复到消息发出时的状态。

因此，就像交易一样，合约可以通过对它产生的子计算设置严格的限制，来保护它们有限的计算资源。

**4.4【代码执行】**

以太坊合约里面的代码是用低级的、基于堆栈的字节码语言写的，被称之为“以太坊虚拟机代码”或“EVM代码”。

这些代码由一系列的字节构成，每一个字节代表一种操作。

通常来讲，代码执行是一个无限循环，该循环包含程序计数器（初始值为零）重复执行操作，每次操作都给程序计数器增加一，直到代码执行完毕或者检测到错误、STOP或者RETURN指令。

执行操作可以访问三种数据存储空间：

● 堆栈，一种后进先出的存储，32字节的数值可以入栈出栈

● 内存，可无限扩展的字节队列

● 合约的长期存储，一个秘钥/数值的存储，其中秘钥和数值都是32字节。与堆栈和内存在计算结束就重置不同的是，存储是长期保存的。

代码可以访问数值、发送者和接受到的消息中的数据，就像访问区块头数据一样，代码还可以返回数据的字节队列作为输出。

EVM代码的正式执行模型极其简单。

当以太坊虚拟机运行时，它的完整的计算状态可以由元组(区块状态、交易、消息、代码、内存、堆栈、程序计数器、gas)来定义，这里block\_state区块状态是全局状态，包含所有账户及余额和存储。

每轮执行时，通过调用代码的pc-th（程序计数器）某个字节来发现当前指令，每个指令自行定义如何影响元组。

例如，ADD将两个元素出栈并将它们的和入栈，将gas减1并将程序计数器加1，SSTORE将顶部的两个元素出栈并将第二个元素插入到由第一个元素定义的合约存储位置，同样减少最多200的gas并将程序计数器加1。

虽然通过即时编译有很多方法来优化以太坊，但以太坊基础部署用几百行代码就可以实现。

**4.5【区块链和挖矿】**

![](https://storage.googleapis.com/papyrus_images/c44fa181aaed1d14966739baa22c15056dfdbbb346abc804f7f3482b80344cf0.jpg)

原图

虽然有一些不同，但以太坊区块链在很多方面类似于比特币区块链。

以太坊和比特币主要的区别在于区块链架构。不像比特币，以太坊区块包含交易记录和最近的状态。

此外，还包含两个值，区块序号和难度值。以太坊的区块确认算法如下：

1、检查引用的前一个区块是否存在和有效。

2、检查区块的时间戳是否比引用的前一个区块的时间戳大，而且小于未来15分钟

3、检查区块序号、难度值、 交易根，叔根和gas限额（许多以太坊特有的底层概念）是否有效

4、检查区块的工作量证明是否有效

5、将S\[0\]赋值为上一个区块的STATE\_ROOT

6、将TX赋值为区块的交易列表，一共n笔交易。对于0……n-1，进行状态转换S\[i+1\] = APPLY(S\[i\],TX\[i\])。如果任何一个转换返回错误，或者程序执行到此区块时所花费的gas超过了GAS限制，返回错误。

7、用S\[n\]给S\_FINAL赋值，但向矿工支付区块奖励。

8、检查S-FINAL是否与STATE\_ROOT相同。如果相同，则区块有效。否则区块无效。

这种方法第一眼看起来似乎效率很低，因为它需要存储每个区块的整个状态，但是事实上这种确认效率可以与比特币相当。

原因是状态存储在树结构中，每增加一个区块只需要改变树结构的一小部分。

因此，通常来讲，在两个相邻区块中的树结构绝大部分应该是相同的，因此一次存储数据可以用指针（子树哈希）引用两次。

一种被称为“帕特里夏树”的特别树结构被用来实现这一点，包括了对默克尔树概念的调整，这种调整不仅允许改变节点，还可以很有效率的插入和删除节点。

另外，因为所有的状态信息是最后一个区块的一部分，所以没有必要存储全部的区块历史——这一方法，如果能应用到比特币，经计算可以节省5-20倍的存储空间。

---

*Originally published on [Jef](https://paragraph.com/@jef/1)*
