Bitcoin: A Peer-to-Peer Electronic Cash System——MIT6-824

Bitcoin: A Peer-to-Peer Electronic Cash System

一个纯粹的p2p电子支付能够绕过第三方金融机构直接从一方发到另外一方。数字签名能解决部分场景问题,但还不够好,因为仍旧需要一个信任的第三方去防止双重支付。因此论文提出一种解决方案来解决双重支付问题,即使用了一个点对点网络。

Introduction

目前网上的电子支付越来越依赖金融机构来充当可信的第三方机构,但这种基于信任的第三方机构具有天生的缺点:由于不可逆的交易并不存在,金融机构需要协调买卖双方的争端,产生的成本最终会转嫁到买家头上。而通过使用现金,由于可以一手交货一手交钱,这些成本可以进一步避免,但由于交易双方天生互不信任,在没有可信第三方机构的前提下,仍旧缺乏一个可靠的机制来保障交易的进行。总结来说,第三方的可信与否,现在的这套体系需要付出巨大的成本来处理,这是目前这套体系的“天然缺陷”。

论文提出的电子支付系统就是一个基于密码学证明而非信任的系统,允许双方在不需要第三方机构的前提下进行直接的交易。计算上的不可逆性能保证卖家不被欺骗,而常规的第三方托管机构可以轻松地被使用来保护买家(卖家比买家更有优势?)。在论文里提出了一种方案来解决双重支付问题:使用一种p2p的分布式时间戳服务,生成交易的时间顺序的可计算证明。只要诚实节点共同控制的算力比攻击节点组织控制的算力大,那么整个系统就是安全。

Transactions

论文对电子货币的定义就是一个带有数字签名的链表,每一个货币拥有者交易给下一个人时,先是通过对上一个交易的输出和接受者公钥进行hash后,然后货币拥有者再用自己的私钥对hash值进行数字签名,这样收款人就可以通过验证签名来进行溯源。

但这个过程有一个问题就是,无法验证付款人有没有双重支付,即这个付款人有没有同时转账给了另一个人。一个可靠的方法是引入一个中央机构,在每一笔交易后,这个货币必须被中央机构回收从而发行一个新的货币,并且只有货币是被直接从可信的中央机构发行才能保证不被双重支付,但这又回到了前面的银行老路了。

论文的做法是,每一笔交易必须被公开广播出来,收款人需要确保,这笔交易是大多数节点所公认的第一次出现,第一次被接收。因为需要一个系统让所有参与者公认一个唯一的历史序列。

Timestamp Server

论文提出的解决方案先从时间服务器开始,其工作过程是把一组数据形成的区块hash结果加盖上时间戳并广播这个hash。这个时间戳就证明,这些数据在这个时刻一定是存在的。每一个时间戳在hash过程中都包含前面一个时间戳,随着每个新增的时间戳加强了可信度,让每一个区块都包含了前面所有区块的时间戳,这样构成了一个链条。

Proof-of-Work

为了实现一个基于p2p的分布式时间戳服务器,将会需要使用一个工作量证明系统。在hash的时候,工作量证明机制将参与扫描一个值,这个hash从一串0bits开始,平均工作量随着0的增长将呈指数级增长,然而只执行一个hash运算就能验证这个hash值。

对于时间戳网络,我们通过在区块中增加一个随机数来实现这个工作量证明,直到一个指定块的hash所需要的0-bits值被找到。只要CPU效率被花费来作为工作量证明,除非重新做一遍相当的工作量,否则这个区块就不能再被改变。简单来说就是做的工作越多,找到这个随机数的概率就越大,这样就构建了一个工作量证明机制。

工作量证明机制同时解决了大多数代表的问题,论文解释了不考虑一个IP一票的这种模式,因为这个机制很容易被拥有大多数IP的给颠覆。工作量证明本质上是一CPU一票,最长的链就表示了大多数,同时也有最大的工作量。如果一个大多数CPU的算力都被诚实节点所控制,那么该链就会增长得最快且超过其他任何链。想要改变一个过去的块,攻击者需要重做这个块和所有在这个块后的块工作量证明,之后还要追赶上并超过现在所有诚实节点的工作。一个更慢的攻击者想要追上不断延伸的区块链,可能性是呈指数级下降的。

同时为了抵消硬件速度提升和节点变化的影响,工作量的困难度是由一个变化的平均目标决定的——每一个小时的平均区块,全网只按一个平均时间来生成一个区块。如果块生成的速度更快了,单位时间所需要的工作量就会变得更大,在同等算力下,计算随机数的难度更大了。

Network

网络运行的步骤如下:

  1. 新的交易被广播到所有节点;
  2. 每一个节点都把新交易收集进入到一个块;
  3. 每一个节点都为自己的块去找到那个工作量证明;
  4. 节点找到后,将块广播给所有的节点;
  5. 其他所有节点认可这个块的所有交易合法,并且接受这个块;
  6. 节点开始使用该块的hash作为prev hash,开始转向下一个块的工作量证明;

节点总是只认可最长的链,如果2个节点同时广播不同版本的块,一些节点会首先收到其中一个块,并为第一个收到块工作,但同时也保存下另一个块。当下一个工作量证明被发现的时候且这时另一条分支会变得更长,在其他分支工作的节点们也将会转换到这个最长的分支上,即块重组。

新交易是没必要广播到所有的节点上,只要交易到达了许多节点上,它们就会进入到一个区块中。并且块的广播能够容忍被丢失的信息,节点意识到那一块缺失就可以进行请求。

Incentive

一般来说,这里存在两种激励。

一个块里面第一笔交易信息是一个特别的交易,它开始了一个新的币,这个币属于这个块的创造者,这就是系统对这个节点的激励,提供了一个方式来初始化货币进入到整个系统当中。

另一种激励就是手续费了。如果一个交易的输出值小于输入值,那么这个差值就是交易的手续费,手续费被附加到包含交易信息的块中。一旦所有货币进入流通,这个激励机制就可完全地转变为交易手续费,并且可以完全避免通货膨胀。

另外,激励可以帮助鼓励节点保持诚实。如果一个贪婪的攻击者能够收集到比所有诚实节点更多的CPU算力,他就面临一个选择:要么用这个算力进行二次支付来欺骗别人,或者使用算力来生成更多的货币。后者的收益更大,这就是一个博弈关系。

Reclaiming Disk Space

一旦一个货币最新的交易收入进入足够多的块中,那么在这笔交易之前的交易信息就能够被抛弃来节省硬盘资源。为了不损害块的hash,交易信息被hash成一种Merkle树的形态,只有root节点被包含进了这个区块的hash。通过拔除Merkle树的分支,不保存内部的hash值,以此来压缩块。

此时一个块的头部大概会是80byte大小。假设块每10分钟就生成一个,那么每年产生80bytes * 6 * 25 * 365 = 4.2MB的数据。

Simplified Payment Verification

支付验证不需要运行所有的网络节点,有些节点已经不再持有全部的块信息,但用户可以通过向网络节点发起询问从而拿到最长工作量证明链条上的块副本,从而得到了Merkle树的分支,连接到这个用户的交易被加上时间戳的地方。用户自己不能验证交易,但可以通过把交易连接到Merkle树的分支。就可以看见一个可以看到一个网络节点曾经接受过它,在它后面增加的块也能证明网络曾经接收过它。

因而只要有多数诚实节点控制网络,支付的验证就是可靠的,而一旦网络被攻击者控制,一个简单的验证方法就是:当这些网络节点监测到一个非法的块,就会提醒用户去下载相关的全部区块,进行独立的安全验证。

Combining and Splitting Value

虽然可以独立的处理电子货币,但在一次转账中为每一分钱都构造一个独立的交易是不明智的。为了能让价值能够分割和组合,交易包含了多个输入和输出。通常情况,前面的交易要么是一大笔单一的输入或者是包括很多小额的多笔输入,输出也有两种,一个是付款,另一个是找零。bitcoin只关心差额,不关心货币最小单元。

Privacy

传统的银行系统实现隐私的保护是通过限制访问信息被提供给相关的参与者和第三方。像现在的场景需要将全部交易公开广播的时候,就不能使用这种方法了。这里的做法是公钥匿名,公众可以看到有一个人转账给另一个人,但是没有信息能把交易和人联系在一起。

还有一个额外的防范机制,就是每次有新的交易,进来都使用一个新的密钥对。但一旦用户的公私密钥被泄漏,由于信息是全网公开的,通过多笔的输入交易,仍然可能推测出这个人是谁。

Calculations

接下来我们考虑一个场景,一个攻击者尝试生成一条比目前诚实链还长的替换链。即便这样能实现,也不代表整个系统完全受制于攻击者。节点是不会接受无效的交易作为支付的,攻击者只能只能尝试修改他自己的交易信息,从而要回自己花掉的钱。

诚实链和攻击链的竞争可以看作是一个Binomial RandomWalk,这是指随机漫步有两个方向的概率模型,要么是诚实链领先,要么是攻击链领先。成功事件是诚实链延长了一个块,使其+1领先,同时失败事件是攻击链延长一个块,使得差距-1。攻击者从一个既定的差距中追上的可能性可以看作是一个Gambler's Ruinproblem。一个攻击者要追上诚实链,如下所示:

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

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

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

假设p>q,那么攻击者追上的概率就会随着块数目的增加而指数下降。现在可以考虑一个新的交易能够被充分地确认发送方不能再更改交易的情况要等多久,即不能再追上。假设付款人是一个攻击者,他希望收款方认为他已经付过款了,并且在之后把这个钱在付款后拿回来。收款方在这件事情发生的时候会被通知警告,但是付款方希望这件事情很久才发生。

接收方生成了一个新密钥对并在短时间内把这个公钥给了付款方,这能有效防止付款方事先准备好一个在时间之前的区块链。

一旦交易被发送,这个不诚实的发送者开始为包含替换他交易版本的并行链而秘密工作。事实上接收方不知道攻击者确切地进展了多少块。假设诚实块是花费平均时间来产生的,那么攻击者的潜在进展会呈现一种泊松密度分布,期望值λ是:

为了得到攻击者能追上的概率,将泊松密度乘以从该点追上的概率得到:

附上一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#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;
}

总结

论文提出了一个不依赖信任的电子交易系统,为了解决双重支付的问题,提出了一种p2p的网络,并采用工作量证明机制来记录交易的历史。当大多数节点控制主要的CPU算力,攻击者就不会通过计算去修改。整个网络还是比较鲁棒的,独立工作不需要太多协调,不需要被认证,可随意离开或加入网络,通过CPU算力投票进行工作从而延长区块链,以此表达他们对有效区块的接受。