官方文档,包括开发指南。https://github.com/GammaGao/bitcoinwhitepaper
我阅读的pdf及批注:http://note.youdao.com/noteshare?id=f995f644399178b5a316561d6457023d&sub=2912F845E0FB49F7A36799B7C38AC976
比特币:一种点对点的电子现金系统
摘要
一种完全通过
点对点技术实现的电子现金系统,使得一方直接支付给另一方,同时不需要第三方信任系统也能防止双重支付。通过
工作量证明机制来有效的保证交易的可靠性除非全网超过一半的计算能力都被攻击者控制。
1 简介
互联网交易的核心问题就是
信任问题。通过
第三方来处理虽然能够很好解决,但是双方的信息都受到第三方的掌控。由此造成
的隐私问题和相关费用问题却不可避免。所以需要一种基于密码学原理而不基于信任,使得双方能够
直接交易,并且杜绝回滚支付交易的可能(避免买家撤回之前交付的货币用于双花),保护卖家。而对于买家,在此环境下
设立第三方担保机制能够更加的轻松。
综上,保护卖家,即保护资金可靠,就用比特币系统;保护买家,即保护货物可靠,在比特币系统上建立第三方担保机制。我举个例子,暗网中的丝绸之路(暗网淘宝)使用比特币支付。那么比特币系统就是保护买家,丝绸之路作为第三方担保机制是保护买家。
2 交易过程
a和b要进行比特币交易,那么a把前一次
交易(比特币数据块)和
b的公钥用a自己的
私钥进行
数字签名。然后发给b。b可以照此继续交易给c。由
时间戳先后的
交易记录逐渐加长。为了防止双花,通过检查交易记录,确认该货币是第一次被主人交易。
就像是a拿出了一枚比特币,然后在比特币上的
所有者 一栏中写上b的名字(公钥),然后在转让书上面签上自己的名字(数字签名,具有不可否认,不可伪造性),然后b就拿到了属于他的比特币。如果b想交易给c,那么在把所有者一栏的名字上改成c的,然后自己再写一份转让书并签字。值得注意的是,这一系列的
转让书都要和比特币一块交易。以供收款人检查确定,这个货币之前没有被交给别人(双花)。
这里有一个问题,就是a开始有一个比特币$1,几经周折又被交易回a手里,那么a在使用$1交易时,收款人检查交易记录会发现a使用过$1,是不是就会认为双花?
其实不会,因为比特币包含时间戳信息,a在1点钟拥有$1,开始交易,5点钟又回到a手里。此时a手里的$1已经不是原来的$1了,时间戳变了,包含的交易记录(一沓子转让合同)也变多了。所以并不会双花。这里要好好想,不要犯
形而上的思想错误。
3 时间戳服务器
一组交易数据形成一个
区块。区块的形成就是通过大量cpu的计算得来的,以后会详细说明。区块链就是把这些区块链接起来,就像铁索连战船。为了防止区块链被伪造,被重复使用,被改造等共计,在提出工作量证明机制之前,首先是
时间戳服务器。时间戳服务器将区块都打上时间戳然后hash公布,这样一来就能证明在彼时确实存在交易,而几乎不能篡改伪造相关交易。
不仅是英文的和中文的文章这里写的都不是很清楚,我思索很久才弄搞定。
4 工作量证明机制
之前也说过,为了防止攻击者伪造篡改区块,需要相应的
证明机制,让攻击者难以实现伪造。这就是
工作量证明机制:寻找随机数,使得该数字的随机散列以一个或多个0开头。随着0的个数上升,找到这个解的工作量将呈指数增长。但是对结果的检验仅需要一次hash运算。寻找随机数的过程也就是通常说的”
挖矿“。
另外,工作量证明机制还解决了在
集体投票时,谁是大多数的问题。其本质是
一cpu一票,诚实的节点会选出
最长的链,然后被大多数认可。这个最长的链就代表了最大的工作量。攻击者想要篡改某一块,就需要相应的改变随后所有的块,并且还要得到大多数的cpu支持。所以攻击难度是很大的。
这里有一个问题没有说清楚,以0开头是指的hash后的
- 32个字符的0开头?
- 还是二进制的0?
- 还是十六进制的0?
我按照1写了部分代码来尝试,发现找到"0"开头很容易,几毫秒。但找到“00”开头的就非常困难了,找了好几个小时都没找到。
def sha_find_str2(basicstr='123456', target='00'):
sha256 = basicstr
start = time.time()
print 'begin at %s'%start
print 'searching...'
while True: #1亿1000000000,35分钟左右
sha256 = hashlib.sha256(sha256).hexdigest()
if sha256[0].startswith(target): #一个0,10次就找到了
print sha256
break
print time.time() - start
5 网络流程
工作流程:
- 新的交易向全网广播;
- 每一个节点都将收到的交易信息纳入一个区块中;
- 每个节点都尝试在区块中找到一个工作量证明(挖矿);
- 当节点找到一个工作量证明,就全网广播;
- 当且仅当包含在该区块中的所有交易都是有效的,且之前未存在过,其他节点才认同该区块的有效性。
- 其他节点接受该区块:区块打包,在其末尾制造新的区块,回到2.
其中,广播交易不需要到达全部的节点,只需要到达足够多的节点,然后全网会经常投票找出最长的可信的链。如果某节点发现自己缺失了某个区块(自己的是错误的缺损的),可以直接下载该区块。
6 激励
挖矿:在上一节4,5步骤中,工作量证明被a发现且工作量证明被大家接受,那么a就成了下一个区块的发起者,作为奖励,在下一个区块第
一笔交易被特殊化,生成一个属于a的电子货币。a就像一个旷工,消耗了自己体力(cpu的电力和时间),挖到了一块黄金(比特币)。
交易费:某笔交易的输出值小于输入值,
差额就是交易费。也就是说每次交易收取一定的交易费,这个交易费被增加到
该区块的奖励中。我猜想一下,挖到矿后不再给新的货币,而是获得上一个块所有的交易费。这个的好处就是当既定数量的比特币进行流通,那么就不需要产生新的货币,本货币系统就能够
挖矿通货膨胀。
在激励制度下,拥有强大计算能力的攻击者便可以通过正常工作获取不输于攻击获取的奖励,
7 区块存储:硬盘空间回收
如果最近的交易已经被纳入了足够多的区块之中(别的节点已经接受了),那么就可以丢弃该交易之前的数据节省空间。当然,同时还要确保不损坏区块的hash。这就需要一个树形结构的存储。叫做梅克尔树(Merkle tree),从下往上两两hash,区块只需保存根hash即可。
不含交易信息的区块头大小仅有80字节,假设
区块10分钟生成一个,那么一年生产的数据为4.2MB。按照摩尔定律,
内存的增长能够适应区块的增长。
注意,这里提到了区块的生成速度,相对很慢。
8 简化的支付确认
在不运行完整网络节点的情况下,也能够对
支付进行检验:用户需要保留最长的工作量证明链条的区块头的拷贝,他可以不断向网络发起询问,知道它确信自己拥有最长的链条。查找梅克尔树中的交易(加入时间戳)就能够检验。
如果发现hash存在,就说明支付成功并且被主流接受。
9 价值的组合与分割
电子货币是一个一个的,但是实际交易可能一次花费好几个。于是交易被设计成了可以容纳多个输入或输出。输出
最多有两个,一个用于
支付,一个可以用于
找零。比如,我花10个比特币买了一辆价值9.9比特币的车,那么我输入10个,输出9.9和0.1,其中0.1用于找零。
也由此可见,比特币并不总是整数。
10 隐私
传统第三方,使用支付宝,网银等都不行,一查就能查到你。因为你的信息都登记在第三方信任平台。与传统的第三方交易不同,比特币系统能够很好的保护隐私。
回看第二节交易过程,交易双方是
通过公钥来判断所有者的。所以
比特币交易信心仅仅知道某个人将一定数量的货币转移给了另一个人,但并不知道到底是谁。除非知道公钥是属于谁的。为了应对,交易的时候可以生产新的密钥对,确保交易不被追溯到一个共同的所有者。
11 安全性计算
一个攻击者a试图改变某个交易,也就是篡改某个区块链,就需要a计算出当前区块,下一区块,直到最新的区块。诚实链条和攻击者链条之间的竞赛,可以用
二叉树随机漫步来描述。成功事件诚实链条+1,失败事件攻击者链条+1,距离减小。
攻击者成功填补某一既定差距的可能秀,类似于
赌徒破产问题。就是一次一次追,但是差的越多,可能性越低。
在p>q时,成功攻击的概率因为区块书的增长而成指数下降。即如果不能幸运的快速成功,那么他成功的机会随着时间的流逝会变得越来越渺茫。由此我们计算出考虑一个人在付款后多长时间可以确认安全。
假设在Z个区块链后攻击者成功了,那么此时就是一个泊松分布。由概率密度乘以概率,数列求和可以计算概率。
文中有c语言代码和相应的结果。
总的结果如下
我这里要说一下,就算攻击者成功篡改了,也需要群众投票来选出最长链,也就是说攻击者要控制51%的计算能力才行。这个民主投票也就是
拜占庭问题。
但我想能不能送小范围进行攻击呢?就是山高皇帝远,攻击者控制一块区域的大部分,然后控制这一区域内的投票结果。有待研究。
12 总结
本文提出了一个有效的安全带,良好匿名性的,点对点电子支付系统。利用电子签名原理实现交易和匿名,通过工作量证明机制记录公开信息,防止双花,保证安全。同时通过公开信息,最长链民主投票方式进一步确保安全,也使系统更加灵活,强壮。激励措施保证系统良好运行。
简单回顾一下过程:时间戳服务(hash块),交易信息收发,交易,奖励,块(链)下载,投票选链(拜占庭)