比特币白皮书中文翻译

比特币:一个点对点的电子现金系统

摘要:本文提出了一种完全通过点对点技术实现的电子现金系统,它使得在线支付能够直接由一方发起并支付给另外一方,中间不需要通过任何的金融机构。虽然数字签名部分解决了这个问题,但是如果仍然需要一个可信的第三方的支持才能防止双重支付的话,那么这种系统也就失去了存在的价值。我们在此提出一种解决方案,使现金系统在点对点的环境下运行,并防止双重支付问题。该网络通过随机散列对全部交易加上时间戳,将它们合并入一个不断延伸的基于随机散列的工作量证明的链条作为交易记录,除非重新完成全部的工作量证明,否则形成的交易记录将不可更改。最长的链条不仅将作为被观察到的事件序列的证明,而且被看做是来自CPU计算能力最大的池。只要大多数的CPU计算能力都没有打算合作起来对全网进行攻击,那么诚实的节点将会生成最长的、超过攻击者的链条。这个系统本身需要的基础设施非常少。信息尽最大努力在全网传播即可,节点可以随时离开和重新加入网络,接收最长的工作量证明链条作为在节点离线期间发生的交易的证明。

1. 引言

互联网上的贸易,几乎都需要依赖金融机构作为可资信赖的第三方来处理电子支付信息。虽然这类系统对绝大多数交易都运作良好,但是这类系统仍然内生性地受制于“基于信用的模式”(trust based model)的弱点。我们无法实现完全不可逆的交易,因为金融机构总是不可避免地会出面协调争端。而金融中介的存在,也会增加交易的成本,并且限制了实际可行的最小交易规模,也限制了日常的小额支付交易。并且潜在的损失还在于,很多商品和服务本身是无法退货的,如果缺乏不可逆的支付手段,互联网的贸易就大大受限。因为有潜在的退款的可能,就需要交易双方拥有信任。而商家也必须提防自己的客户,因此会向客户索取完全不必要的个人信息。而实际的商业行为中,一定比例的欺诈性客户也被认为是不可避免的,相关损失视作销售费用处理。而在使用物理现金的情况下,这些销售费用和支付问题上的不确定性却是可以避免的,因为此时没有第三方信用中介的存在。

所以,我们非常需要这样一种电子支付系统,它基于密码学原理而不基于信用,使得任何达成一致的双方,能够直接进行支付,从而不需要第三方中介的参与。杜绝回滚支付交易的可能,这就可以保护特定的卖家免于欺诈;而对于想要保护买家的人来说,在此环境下设立通常的第三方担保机制也非常轻松。在这篇论文中,我们将提出一种通过点对点分布式的时间戳服务器来生成依照时间先后排列并加以记录的电子交易证明,从而解决双重支付问题。只要诚实的节点所控制的计算能力的总和,大于有合作关系的攻击者的计算能力的总和,该系统就是安全的。

2. 交易

我们定义一枚电子货币是一串数字签名。每一位所有者通过对前一次交易和下一位拥有者的公钥 签署一个随机散列的数字签名,并将这些信息附加在这枚电子货币的末尾,电子货币就发送给了下一位所有者。收款人通过对签名进行检验,就能够验证该串数字签名的所有者。


image.png

这其中的问题是收款人无法核实其中一个所有者没有将货币重复使用。一种常见的解决方案是引入一个受信任的中央权威机构或者铸币厂,检查每笔交易是否存在重复支出。每笔交易完成后,必须将货币退还铸币厂,才能发行一枚新货币,而且只有直接从铸币厂发行的货币才能保证不会被重复使用。这种解决方案的问题在于,整个货币系统的命运取决于铸币厂的运营公司,每笔交易都必须经过铸币厂,就像银行一样。

我们需要一种方法让收款人知道以前的所有者没有签署任何早期的交易。就我们的目的而言,最早的交易才是最重要的,所以我们不关心以后的重复消费尝试。确认没有交易的惟一方法是了解所有的交易。在基于造币厂的模型中,造币厂知道所有的交易,并决定哪个先到达。为了在没有受信任方的情况下实现这一点,交易必须公开宣布,我们需要一个系统,让参与者同意接收交易的顺序的单一历史记录。收款人需要证明在每次交易时,大多数节点都同意它是第一个收到的。

3. 时间戳服务器

我们建议的解决方案从一个时间戳服务器开始。时间戳服务器的工作方式是对要加盖时间戳的项目块进行hash,并广泛地发布hash,例如在报纸或新闻网络中。显然,时间戳证明数据必须在当时存在,以便进入hash的计算。每个时间戳在它的hash中包含前面的时间戳,形成一个链,每个额外的时间戳都加强前面的时间戳。


image.png

4. 工作量证明

要在点对点基础上实现分布式时间戳服务器,我们需要使用类似Adam Back的Hashcash的工作量证明系统,而不是报纸或网络新闻帖子。工作量证明涉及到查找hash时的值,例如SHA-256,hash后的值以多个零开头。所需的平均工作量是零比特数量的指数,可以通过执行单个hash来验证。

对于我们的时间戳网络,我们通过在块中递增一个随机数来实现工作量证明,直到找到一个为块的hash提供所需零位的值。一旦花费了CPU的算力使其满足工作量证明,那么在不重做工作的情况下就不能更改块。由于后面的块在它之后被链接,更改块的工作将包括重做在它之后所有的块。


image.png

工作量证明也解决了多数决策中确定代表的问题。如果“多数”是基于一个ip地址一票的方式,那么任何能够分配许多ip的人都可以颠覆这种方式。工作量证明本质上是一个CPU一票。多数决策由最长的链表示,它在其中投入了最大的工作量证明工作。如果大多数CPU算力由诚实的节点控制,诚实的链将增长最快,并超过任何竞争链。要修改过去的块,攻击者必须重做块的工作量证明,以及块之后的所有块,然后才能赶上并超过诚实节点的工作。稍后我们将展示,随着后续块的添加,攻击速度较慢的攻击者迎头赶上的概率呈指数级下降。为了补偿硬件速度的提高和运行节点的利益随时间的变化,工作量证明的难度由针对每小时平均块数的移动平均值决定。如果区块生成得太快,难度就会增加。

5. 网络

运行网络的步骤如下:
1)新交易被广播到所有节点
2)每个节点将新交易收集到一个区块
3)每个节点都尝试在自己的区块中找到一个具有足够难度的工作量证明
4)当一个节点找到一个工作量证明时,它会将这个区块块广播给所有节点
5)只有当区块中的所有交易都是有效的且尚未使用时,其他节点才接受这个区块
6)节点通过在这个区块所在的链上创建新的区块来表示它们接受该区块,将被接受区块的hash作为新区块的前一个hash

节点始终将最长的链视为正确的链,并将继续工作和扩展它。如果两个节点同时广播下一个区块的不同版本,一些节点可能首先接收其中一个。在这种情况下,它们在收到的第一个分支上工作,但是会保存另一个分支,以防它变成更长的链。当发现下一个工作量证明,其中一个分支变长时,僵局就会打破,在另一个分支上工作的节点将切换到较长的分支。

新的交易广播不一定需要到达所有节点。只要它们到达足够多的节点,就会很快进入一个区块中。区块的广播对被丢弃的信息是具有容错能力的。如果一个节点没有接收到一个区块,它将在接收到下一个块时意识到它错过了一个区块,然后请求下载该区块。

6. 激励

我们约定:每个区块的第一笔交易进行特殊化处理,该交易产生一枚由该区块创造者拥有的新的电子货币。这增加了节点支持网络的激励,并提供了一种将电子货币分发到流通领域中的方法,因为没有发行电子货币的中央权威机构。这种将一定数量新货币持续增加到货币系统中的方法,非常类似于淘金者耗费资源去挖掘金矿并将黄金注入到流通领域。在我们的例子中,消耗的是CPU时间和电能。

另一个激励来源也可以是交易费用。如果一个交易的输出值小于它的输入值,那么差额就是交易费,该交易费将被加到包含该交易的区块的激励中。一旦预定数量的电子货币进入流通领域,激励可以完全转换为交易费用,该系统完全没有通货膨胀。

这种激励可以有助于鼓励节点保持诚实。如果有一个贪婪的攻击者能够调集比所有诚实节点加起来还要多的CPU计算力,那么他就面临一个选择:要么将其用于诚实工作产生新的电子货币,或者将其用于进行二次支付攻击。那么他就会发现,按照规则行事、诚实工作是更有利可图的。因为该等规则使得他能够拥有更多的电子货币,而不是破坏这个系统使得其自身财富的有效性受损。

7. 回收磁盘空间

如果最近的交易已经被纳入了足够多的区块之中,那么就可以该交易之前使用的数据以节省磁盘空间。为了在不破坏区块随机hash的情况下实现这一点,交易信息被随机散列时,被构建成一种Merkle树的形态,只有根包含在区块的随机hash中。通过将该树(tree)的分支拔除(stubbing)的方法,老区块就能被压缩。而内部的随机散列值是不必保存的。

image.png

不包含交易的区块头大小约为80字节。如果我们设定区块生成的速度为每10分钟1个,那么每一年产生的数据大小为80 bytes * 6 * 24 * 365 = 4.2M。2008年,计算机系统通常的内存容量为2GB,按照摩尔定律的预言每年增长1.2GB,即使将全部的区块头存储于内存之中都不是问题。

8. 简化的付款确认(Simplified Payment Verification)

在没有运行完整网络节点的情况下,也可以对支付进行验证。一个用户仅需要保留最长的工作量证明链条的区块头的拷贝,它可以不断向网络发起询问,直到它确信自己拥有最长的链条,并能够得到通过它被加上时间戳并纳入区块的那次交易的Merkle分支。节点想要自行检验该交易的有效性原本是不可能的,但通过追溯到链条的某个位置,它就能看到某个节点曾经接受过它,并且于其后追加的区块也进一步证明全网曾经接受了它。


最长的工作量证明链

像这样,只要诚实的节点控制了网络,检验机制就是可靠的。但是,当全网被一个计算力占优的攻击者攻击时,将变得较为脆弱。因为网络节点能够自行确认交易的有效性,只要攻击者能够持续地保持计算力优势,简化的机制会被攻击者伪造的交易欺骗。那么一个可行的策略就是,只要他们发现了一个无效的区块,就立刻发出警报,收到警报的用户将立刻开始下载被警告有问题的区块或交易的完整信息,以便对信息的不一致进行判定。经常收到付款的企业可能仍然希望运行自己的节点,以获得更独立的安全性和更快的验证。

9. 价值的组合与分割

虽然可以单个地对电子货币进行处理,但是对于每一枚电子货币单独发起一次交易将是一种笨拙的办法。为了使得价值易于组合与分割,交易被设计为可以包含多个输入和输出。一般而言是某次价值较大的前次交易构成的单一输入,或者由某几个价值较小的前次交易共同构成的并行输入,但是输出最多只有两个:一个用于支付,另一个用于找零(如有,则返回给发送者)。


image.png

需要注意扇出,当一笔交易依赖于之前的多笔交易时,这些交易又各自依赖于多笔交易,但这并不存在任何问题。因为这个工作机制并不需要展开检验之前发生的所有交易历史。

10. 隐私

传统的银行模式通过限制相关方和可信的第三方获得信息,从而达到一定程度的隐私。公开声明所有交易的必要性排除了这种方法,但是仍然可以通过在另一个地方中断信息流来维护隐私:通过保持公钥匿名。公众可以看到有人向其他人发送了一笔一定金额的货币,但没有将交易链接到任何人的信息。这类似于证券交易所公布的信息水平,即公开单个交易的时间和规模,但不透露交易双方是谁。

image.png

作为一个额外的防火墙,应该为每个交易使用一个新的密钥对,以防止它们链接到一个公共所有者。对于多输入的交易,某些链接仍然是不可避免的,这必然表明它们的输入属于同一个所有者。风险在于,如果密钥的所有者被暴露,链接可能会暴露属于同一所有者的其他交易。

11. 计算

我们考虑攻击者试图生成一个比诚实链更快的备用链的场景。即使实现了这一点,它也不会让系统对任意更改开放,比如凭空创造价值或拿走从未属于攻击者的钱。节点不会接受无效的交易作为支付,诚实的节点永远不会接受包含它们的块。攻击者只能尝试更改自己的一个交易以收回最近花费的钱。

诚实链和攻击链之间的竞争可以用二叉树随机漫步来描述。成功的事件是诚实链延长了一个区块,使其领先性+1,而失败的事件则是攻击者的链被延长了一个区块,使得差距-1。

攻击者成功填补既定差距的可能性类似于赌徒的破产问题。假设一个赌徒拥有无限透支的信用并且一开始有一定的亏损,那么他为了回本可能会进行无限次数的尝试。那么我们可以计算他填补上亏空的概率,也就是该攻击者赶上诚实链,如下所示 [8]:

p = 一个诚实节点找到下一个区块的概率
q = 攻击者找到下一个区块的概率
qz = 攻击者从后面的z个区块追上来的概率
q_z = \begin{cases} 1 \quad 如果 p \leq q \\ (\frac{q}{p})^{z} \quad 如果 p > q \\ \end{cases}

假设p > q,随着攻击者必须赶上的块数的增加,概率呈指数级下降。由于他的胜算不大,如果他不尽早幸运地向前冲,随着他进一步落后,他的机会就会变得微乎其微。现在,我们考虑新交易的接收方需要等待多长时间才能充分确定发送方不能更改交易。我们假设发送者是一个攻击者,他想让接收者相信某一段时间支付了费用,然后在一段时间后将其转换为向自己支付。当这种情况发生时,接收方会收到警报,但发送方希望为时已晚。

接收方生成一个新的密钥对,并在签名前不久将公钥交给发送方。这可以防止发送者通过不断地工作来提前准备一个区块链,直到他足够幸运地提前完成足够多的工作,然后在此时执行交易。一旦交易被发送,不诚实的发送者就开始在包含其交易的另一个版本的并行链上秘密工作。

接收者等待,直到交易被添加到一个块中,并且z块在它之后被链接。他不知道攻击者已经取得了多少进展,但是假设诚实的块花费了每个块的平均预期时间,那么攻击者的潜在进展将是一个带有期望值的泊松分布:
\lambda = z\frac{q}{p}
为了得到攻击者现在仍然可以追赶的概率,我们用攻击者从那一点开始追赶的概率乘以他本可以取得的每一次进步的泊松分布的概率密度:
\sum_{k=0}^{\infty}\frac{\lambda^k e^{-\lambda}}{k!}\cdot \begin{cases} (\frac{q}{p})^{(z-k)} 如果 k \leq z \\ 1 \quad 如果 k > z \\ \end{cases}

重新排列以避免对分布的无限尾求和…
1-\sum_{k=0}^{z}\frac{\lambda^k e^{-\lambda}}{k!}(1-(\frac{q}{p})^{(z-k)})

转化为C代码...


   #include <math.h>
   double AttackerSuccessProbability(double q, int z)
   {
       double p = 1.0 - q;
       double lambda = z * (q / p);
       double sum = 1.0;
       int i, k;
       for (k = 0; k <= z; k++)
       {
           double poisson = 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%...

   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

12. 结论

我们建议建立一个不依赖信托的电子交易系统。我们从通常的货币的数字签名框架开始,它提供了对所有权的强大控制,但如果没有防止重复消费的方法,它是不完整的。为了解决这个问题,我们提出了一个点对点网络,它使用工作证明来记录交易的公共历史,如果诚实节点控制了CPU的大部分能力,那么攻击者很快就会发现改变记录在计算上是不切实际的。该网络以其非结构化的简单性而健壮。节点几乎不协调地同时工作。它们不需要身份,因为消息不路由到任何特定的位置,只需要在最佳的基础上传输。节点可以随意离开并重新加入网络,接受工作量证明链作为它们离开时发生的事情的证据。他们使用CPU算力投票,通过扩展有效块来表示接受有效块,通过拒绝处理无效块来拒绝处理无效块。任何必要的规则和奖励都可以通过这种协商一致机制得到执行。

推荐阅读更多精彩内容