网络
运行网络的步骤如下:
1、新交易通过广播的形式传播给所有节点;
2、每个节点收集新交易并打包进区块;
3、每个节点都尝试在自己的区块中找到一个具有足够难度的工作量证明;
4、当一个节点找到了一个工作量证明,向全网广播;
5、只要当包含在该区块中的所有交易都是有效的,之前未存在过的,其他节点才认同改区块的有效性;
6、其他节点在通过在区块尾部,知道新的区块以延伸链条,来接收该区块,并且将该区块的哈希值记录下来(previous hash);
节点只把最长链条视为正确的链条,持续工作并延长她。如果两个节点同时广播不同版本的新区块,其他节点在接收该区块时会有时间差。这种情况下,节点会在先收到的区块基础上进行工作,但也会保留另外一个链条,防止后者变成最长的链条。当下一个工作量证明被发现,而其中一条链被证实为较长的链,那么另外一条分支上工作的节点就得切换链条,开始在较长的链条上工作了。
其实新交易的广播,并不要求所有节点都接收到。只要交易信息能够抵达足够多的节点,那么他们会很快被整合进区块中。广播机制下,区块是具有容错能力的,如果一个节点没有收到某个特定区块,当他收到下一个区块是,该节点会校验到自己缺失了这个区块,然后他可以提出下载确实区块的请求。
激励
协议约定,每个区块的第一笔交易是一笔特殊交易,包含特定数量的比特币,由区块创造者分配。这加强了节点支持网络运转的积极性。并且在没有造币厂的情况下,提供了一种发行货币并进入流通的方式。这种按一定数量进行的货币增发方式,类似于耗费资源去挖掘金矿并注入流通的形式,而这里,我们消耗的资源是CPU的时间和电力资源。
另外一种奖励来源是交易费。如果一笔交易的输出值小于输入值,其中的差额就是交易费,不同的是交易费归属处理该交易的节点。当既定数量的比特币进入流通,那么激励机制就可以逐渐转换为完全依靠交易费,这种机制能避免系统的通货膨胀。
激励机制也许能鼓励节点保持诚实可信。如果一个贪婪的攻击者,能够集结比所有诚实节点加起来还要多的算力,那么他可以通过欺骗交易人偷取比特币,也可以老实工作通过激励机制来获利。他会发现老实按规则来,更有利可图,因为在规则下他能获得更多的比特币,同时破坏系统将损害到他自己的财富。
回收硬盘空间
如果最近的交易已经纳入到足够多的区块中了,那么就可以丢弃该交易之前的交易数据,以减少数据量,回收硬盘空间。为了确保不损害区块的哈希值,交易信息被哈希时,构建成Merkle树(Merkle tree)的形式,使得只有根(root)被记录到区块的哈希值,通过对树剪枝,老区块就能被压缩。内部哈希值就不需要存储了。
不包含交易信息的区块头大小为80个字节。如果我们设定区块没十分钟生成一个,那么一年产生的数据量为4.2MB。2008年一般个人电脑的内存为2G,按照摩尔定律,即使将所有区块头存放在内存中都不成问题。
简化的支付校验
在不包含所有网络节点的情况下,也可以完成交易的验证。用户只需要保存最长的工作量证明的链条的区块头的副本,他可以不断向网络发起询问,直到他确信自己拥有最长的链条,并能够通过Merkle的分支通向他被加上时间戳并纳入区块的那次交易。节点无法肚子检验某个交易的有效性,但是可以链接在通过网络中某个节点确认,那个节点曾经校验过他,并且之后追加的区块也进一步证明全网曾经接受了他。
在这种情况下,只要城市的节点控制了网络,这个检验机制就是可靠的。但是,当全网被一个算力占优势的攻击者攻陷。当网络节点能够自行确认交易有效性的时候,只要攻击者能持续保持算力优势,这个简化了的机制会让节点被攻击者重组的交易信息欺骗。一个可行的策略是,只要他检测到一个非法区块,就立刻发出警报,收到警报的用户软件会立刻开始下载被警告有问题的完整区块和被报警的交易,来确认信息的一致性。对应日常进行大量交易的商业机构,可能任会希望他们自己的完整节点,以保持独立性和灵活性。
价值的组合与分割
虽然我们可以逐个的对比特币进行处理,但是对每分钱都单独发起一次交易显得有点蠢了。为了使得交易易于组合和分割,交易被设计为可以包含多个输入和输出。通常情况下,某次价值较大的前次交易构成的单一输入,或者由某几个价值较小的前次交易共同构成的并行输入,但是输出最多只有两个:一个用于支付,另一个用于找零。
需要指出的是,当一笔交易依赖于之前的多笔交易时,这些交易有各自依赖于多笔交易,这并不存在什么问题。因为这个工作机制并不需要展开检验之前发生的所有历史交易。
隐私
传统的银行模型中,为交易的参与者提供了一定程度上的隐私保护,会严格限制参与交易的三方和可信的三方机构的信息访问。但是如果将交易信息向全网进行广播,就意味着这个模型将不再适用。但是隐私任然可以得到保护:将公钥保持匿名。从公布的信息来看,我们只能得到某个人将一定数量的货币发给了另外一个人,但是没有足够的信息来确认人到的是谁。这有点类似股票交易所发布的信息类似,每一手股票买卖发生的时间、交易量是记录在案可查询的,但是交易双方的身份信息却是不予透露的。
作为额外的预防措施,使用者可以让每次交易都生成一个新地址,以确保这些交易不会被追溯到一个共同的所有者。不过存在并行输入交易,一定程度上的追溯是不可避免的,因为并行输入暗示这些货币都属于同一个所有者。如果一个人的公钥被确认属于他,那么就可以追溯到这个人的其他很多交易。
计算
我们来设想一个下:一个攻击者想要比诚实节点产生链条更快的知道替代性链条。即使他达到了这个目的,整个系统也并不会完全受攻击者控制,比方说,凭空创造比特币,或者掠夺属于别人的比特币。节点不会接受非法交易支付,并且诚实的节点永远不会接受一个包含非法信息的区块。攻击者最多能改变他自己的交易信息,那会他刚刚支付给别人的钱。
诚实链条和攻击者链条之前的竞赛,可以用二叉树随机漫步(Binomial Random Walk)来描述。成功事件定义为诚实链条增加了一个区块,使其领先+1,而失败事件则是攻击者链条+1。
攻击者成功填补某一既定差距的可能性,可以近似的看做赌徒破产问题(Gambler’s Ruin problem)。假定一个赌徒拥有无限的透支信用,然后开始进行潜在次数为无穷的赌博,试图填补上自己的亏空。那么我们可以计算他填补上亏空的概率,也就是该攻击者赶上诚实链条。
p=诚实节点制造出下一个节点的概率;
q=攻击者制造出下一个节点的概率;
qz=攻击者最终消弭了z个区块的落后差距;
假定p>q,那么攻击成功的概率就因为区块数的增长而呈指数下降。站在赔率更大位置的他,如果不能幸运而迅速的获得成功,那么他成功的机会将越来越渺茫。
我们现在来考虑一个收款人需要等待多长时间,才能确信付款人不能更改交易了。我们假设付款人是一个攻击者,希望收款人相信他已经付过款了,然后将支付款项重新支付给自己。收款人会受到提醒,但是为时已晚。
收款人生成了新的一对密钥组合,然后只预留一个较短的时间将公钥发送给付款人。这将可以防止以下情况:付款人预先准备好一个区块链然后持续地对此区块进行运算,直到运气让他的区块链超越了诚实链条,方才立即执行支付。当此情形,只要交易一旦发出,攻击者就开始秘密地准备一条包含了该交易替代版本的平行链条。
然后收款人将等待交易出现在首个区块中,然后在等到z个区块链接其后。此时,他仍然不能确切知道攻击者已经进展了多少个区块,但是假设诚实区块将耗费平均预期时间以产生一个区块,那么攻击者的潜在进展就是一个泊松分布,分布的期望值为:
当此情形,为了计算攻击者追赶上的概率,我们将攻击者取得进展区块数量的泊松分布的概率密度,乘以在该数量下攻击者依然能够追赶上的概率。
化为如下形式,避免对无限数列求和:
写为如下C语言代码:
#include
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%的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