目录
与纸质货币类似,数字货币的内容包括面额、发户行的认证防伪信息等,即用央行的私钥签名,然后使用的时候,用户直接拿央行的公钥验证签名,证明数字货币的合法性。数字签名保证了其中内容不可篡改性,但是,同密码学中的数字签名一样,数字货币有着类似“重放攻击”的安全隐患——花两次攻击(Double Spending Attack)。
所以数字货币仅包含面额和数字签名是不够抵御双花攻击的,每个数字货币还要有编号,在不考虑去中心化的情况下,央行需要维护一个巨大的数据库,用来记录每个合法编号的数字货币是归哪个用户所有。用户在支付时,不仅要用央行的公钥验证签名是否为央行签署,还要通过央行验证该货币是归自己所有,然后央行才能将货币所有者改成接收这笔数字货币的用户。不仅数字货币的发行是由央行统一控制,而且每次交易都需要由央行确认其合法性,这种方案是一个中心化的方案。
将央行的职能改成由所有用户来共同承担,也就是去中心化的方案。比特币等数字货币需要解决的问题有:如何决定数字货币的发行量以及如何验证交易的合法性等。数字货币的发行及发行量在比特币系统中是由挖矿决定的,而验证交易合法性则需要要维护一个数据结构,由所有用户来共同维护,这个数据结构就是区块链。
假设用户A获得了铸币权,所谓铸币权就是发行货币的权利。假定用户A发行了10个比特币。然后A将这10个比特币分别转给用户B和用户C,每个人分得5个比特币。接下来用户B给用户C分2个比特币,给用户D分3个比特币。最后C将自己的7个比特币全部给用户E,那么这个交易过程用区块链可以表示为如下图1-1所示。这样就可以避免双花攻击。
比特币系统中的收款地址是收款人的公钥取哈希再经过一些转换得到的。比特币系统也没有提供查询某用户的公钥或账户地址的功能,假设A要向B用户转账,就需要B提供公钥或账户地址。这种情况B可以把公钥公布在网站上。然而在这个转账过程中,除了A需要知道B的地址,B也需要知道A的公钥。一方面,A的公钥代表A的身份,B要知道转账的是谁;另一方面,B需要验证比特币交易中A的签名。其实,所有结点都需要知道A的公钥,每个结点都需要独立验证,即使是一个和交易无关的旁观者也要验证这笔交易的合法性。
A给B提供A的公钥,如何确保A的公钥的合法性呢?因为比特币交易中需要注明币的来源,其中交易的输出部分有收款人A的公钥的哈希值,所以,我们只需要验证A提供的公钥的哈希值跟币的来源中A的公钥的哈希值是否一致,就可以验证A的公钥的合法性。比特币交易过程中的输入部分和输出部分实际上都是脚本(Bitcoin Script),A的公钥也是写在这笔交易的输入脚本里面。对公钥的验证过程,实际上就是把当前这笔交易的输入脚本,和币的来源的交易的输出脚本拼在一起执行,看看能不能顺利执行。实际上,每个区块中可以有很多交易,这些交易就组成了Merkle Tree。
块头(Block Header)是保存区块的宏观的信息的地方。
(1)version: 用的比特币的哪个版本的协议。
(2) hash of pervious block header:区块链中指向前一个区块块头的哈希指针。
(3)Merkle root hash: 整棵Merkle Tree的根哈希值。
(4)target: 挖矿的难度目标阈值。
(5)nonce: 挖矿用的随机数nonce,要使得H(block header) ≤ target。
块身(Block Body)是保存区块交易列表(Transaction List)的地方。取哈希的时候实际上只是将块头中的所有信息取哈希,交易信息不管。
每个账户都可以发布交易,区块链可以看做去中心化的账本,账本的内容要取得分布式的共识(Distributed Consensus)。分布式的共识的简单的例子:分布式的哈希表。
FLP impossibility result讲的是在一个异步的系统(asynchronous system)中,网络传输的时延没有上限,那么即使只有一个成员是有问题(faulty)的,也不可能取得共识。
(2)CAP Theorem
CAP是分布式系统想要的三个性质,Consistency一致性、Availability可用性、Partition tolerance分区容忍性。CAP Theorem是指在任何一个分布式系统中,CAP三个性质最多只能满足其中两个,不可能三个全满足。
一致性(Consistency):每次读取要么获得最近写入的数据,要么获得一个错误。
可用性(Availability):每次请求都能获得一个(非错误)响应,但不保证返回的是最新写入的数据(对应HA,机器故障时仍然能够提供服务)。
分区容错性(Partition tolerance):尽管任意数量的消息被节点间的网络丢失(或延迟),系统仍继续运行(网络分区/网络故障时仍然能够提供服务)。
在比特币系统中的共识要考虑到有些结点是有恶意的,假设系统中大部分结点是友好的,有恶意的结点占少数。在普通的分布式系统中,如分布式哈希表里,取得的共识就是哈希表中的内容。在比特币系统中,共识协议取得的共识是去中心化的账本里的交易。只有获得记账权的结点可以往区块里写交易,而获得记账权的途径就是解那个不等式puzzle,根据第一节课学习的哈希函数puzzle friendly的性质,求解这个puzzle的过程没有捷径,只能一个一个nonce去尝试,所以可以作为工作量的证明,算力越强得到出块奖励的概率也就越大,所以才说比特币系统中是靠算力来投票的。
也就是说,每个结点都可以在本地组装出一个候选区块,把它认为合法的区块放在这个区块里,然后就开始尝试各种nonce值(4 byte),使得H(Block Header) ≤ target。如果某个结点找到了符合要求的nonce,也就获得了记账权(即往比特币去中心化账本——区块链中,写入下一区块的权利),其它结点收到这个区块之后,也会验证这个区块的合法性。(如检查target的编码nBits域设置的是不是符合比特币协议规定的难度要求、检查带nonce的块头哈希值是不是小于target、检查块身中的每个交易是否都有合法的签名、检查每个交易都没有双花问题等)
经确认合法性无误之后,候选区块并不会马上被接收,这里我们依旧使用之前的例子做扩展,假定用户A发行了10个比特币。然后A将这10个比特币分别转给用户B和用户C,每个人分得5个比特币。接下来用户B给用户C分2个比特币,给用户D分3个比特币。然后C将自己的7个比特币全部给用户E,接着C又将这7个比特币转给了自己,那么这个交易过程用区块链可以表示为如下图2-1所示。
这里,“C将7个比特币转给了自己”这个候选区块的这项操作是合法的,但不应当被接受,因为它不在最长合法链(Longest Valid Chain)上,这实际上是一种分叉攻击(Forking Attack),即通过往区块链中增加区块,来回滚某个已经发生了的交易。
如果两个结点同时获得记账权,此时都能插入候选区块,这种等长的、临时性的最长合法链(分支)的情况会维持一段时间,直到某个分支胜出。假如上面的先找到下一个区块,那么下面这个区块就成为了Orphan Block被丢弃掉。因为Orphan Block不在最长合法链里,所以里面的出块奖励的铸币交易也就无效了。
获得记账权的结点本身有一定的权力,如:可以决定哪些交易被写入下一个区块中,但这不应当成为竞争记账权的主要动力,因为比特币系统设计来希望所有交易都能被公平写入账本。获得记账权的主要动力是出块奖励。比特币协议中规定,获得记账权的结点,在发布的区块里可以有一个特殊的交易——铸币交易,在这个交易中可以发布一定数量的比特币,这是发行比特币(产生新的比特币)的唯一方法,不必指定币的来源。
比特币刚出现时,出块奖励是50个比特币,比特币协议规定每21万个区块之后,出块奖励就要减半,产生21万个区块所需要的时间大约为4年,也就变成25个比特币。如今的情况是每个区块中能产生12.5个比特币。