《区块链技术与应用》课堂笔记(四):BTC协议

一、数字货币和纸质货币的区别

        央行要发行数字货币,如果直接为货币的面额等信息,用央行的私钥签名,然后使用的时候,用户直接拿央行的公钥验证签名,就这样用是行不通的,因为完全可以用这个数字货币再去买东西了,这叫双花攻击(double spending attack)。签名保证了面额等信息不能修改,但这个数字文件可以复制很多份。如果是纸质货币,花出去自己手里就没有了,这是数字货币和纸质货币的区别。

去中心化货币要解决两个问题:

①数字货币的发行

②怎么验证交易的有效性,防止double spending attack(双花攻击)。

二、两种解决方案

中心化的方案:

        仅仅有面额是不够的,每个数字货币还要有编号,先不考虑去中心化,央行还要维护一个数据库,即记录每个编号的数字货币是归哪个用户所有。 

在支付时,不仅要用公钥验证签名是央行签署的,还要通过央行验证该货币是归自己所有,央行再将货币所有者改成支付给的那个用户。不仅数字货币的发行是由央行来做,而且每次交易都要由央行确认其合法性,这种方案是一个中心化的方案。

去中心化的方案 : 

将央行的职能改成由广大的用户来共同承担,也就是去中心化的方案,这是比特币等数字货币系统要解决的问题,也即:

怎么决定数字货币的发行及发行量
怎么验证交易的合法性,防止双花攻击
第一个问题在比特币系统中是挖矿决定的,后面会学到。

第二个问题的解决,也是和中心化的方案一样要维护一个数据结构,但不再是由央行来维护,而是由所有用户来共同维护,这个数据结构也不再是关系表,而是区块链

如下图,假设用户A获得了铸币权(发行货币的权利),他发行了10个比特币,即自己获得了10个比特币。然后他将这10个比特币转给B和C,每个人分5个比特币。接下来B给C 2个货币,给D 3个货币。最后C将所得的7个货币全部给E。

比特币系统中每个交易都分为输入部分和输出部分,输入部分要给出这笔交易的比特币的来源以及付款方的公钥,输出部分要给出收款人的公钥的哈希值。比特币系统中的收款地址就是收款人的公钥取哈希再经过一些转换得到的。

这里涉及两种哈希指针,一种就是图中钴蓝色的,将各个区块串起来的哈希指针;另一种是图中深红色的,是为了说明币的来源是从哪个交易来的。

这里“说明币的来源”也就防止了双花攻击,如在下图中,B已经将自己的5个比特币花掉了,假设B尝试再花一次,将5个比特币转给F。这时顺着区块链去检查这个区块到来源交易之间的区块,发现B已经花了来源区块的比特币,说明这新个交易是不合法的,也就不会接受这个区块进入区块链。

类似于银行没有提供查询某用户的银行账号的功能一样,比特币系统也没有提供查询某用户的公钥或账户地址的功能,要向某用户转账,就需要对方提供公钥或账户地址。这种情况收款方可以把公钥公布在网站上。

然而A向B转账,除了A需要知道B的地址,B也需要知道A的公钥。因为一方面A的公钥代表A的身份,B要知道转账的是谁,另一方面是为了验证比特币交易中A的签名(私钥签名公钥验证),也就是说所有结点都需要知道A的公钥才行。

 区块链上每个结点都需要独立验证,即使是一个和交易无关的旁观者也要验证这笔交易的合法性。

在这种情况下,如何知道A的公钥?这里如前面所学A的公钥是A自己写在这笔交易的输入部分里,即在交易中付款方自己宣称的。但这样是否会造成其他人可以伪造成A来发起交易?如B的同伙B’说自己是A,然后用自己的私钥签名,将自己的公钥说是A的公钥放在交易输入部分里,尝试将A账户上的比特币转走。

但因为币的来源(图中铸币交易)中交易的输出部分有收款人A的公钥的哈希值,这时B’伪造的公钥的哈希就和A的公钥的哈希对不上了,所以可以防止这种攻击。

倘若B’直接使用A的公钥写上去,但因为没有A的私钥,这时签名就无法用A的公钥验证了,显然也是不行的。

交易的输入部分和输出部分实际上都是脚本,A的公钥也是写在这笔交易的输入脚本里面。对公钥的验证过程,实际上就是把这笔交易的输入脚本,和币的来源的交易的输出脚本拼在一起,看看能不能顺利执行。

在前面的几张图里,每个区块里只花了一个交易,实际系统中每个区块中可以有很多交易,这些交易就组成了上节课学习的Merkle Tree。

区块结构

这里补充了上节学习的区块链中结点的构造,详述一下块头和块身。

上图中连起来的是块头,块身挂在区块上,哈希指针和块身没有直接联系(间接联系就是通过Merkle Tree的根哈希建立的)。

注意全结点(fully validation node)是有块身的,需要验证所有交易的合法性;轻结点(light node)是没有块身的,没有办法独立验证交易的合法性。
轻结点没有参与区块链的构造和维护,只是利用了区块链中的部分信息。
系统中大部分结点是轻结点,全结点不是很多。

块头(block header)


块头里保存的是区块的宏观的信息。

  • 用的是比特币的哪个版本的协议
  • 指向前一个区块块头的哈希指针(注意!这里的哈希值只计算前一个区块的块头,块头保存的Merkle Tree的根哈希就已经可以保证区块中保存的所有交易没有被篡改了)
  • 整棵Merkle Tree的根哈希值
  • 挖矿的难度目标阈值target
  • 挖矿用的随机数nonce,要使得H ( blockheader) ≤ target

块身(block body)

  • 交易列表

挖矿求解问题:Hash(block header)<=target
Hash of previous block header只计算区块块头部分的哈希( Merkle root hash保证了block body内容不被篡改,所以只需要计算block header即可保证整个区块内容不会被篡改)
区块链系统中,轻节点(只存储区块block header信息)只利用区块链,但并不参与区块链系统维护和构造。

三、共识协议

        还有一个问题就是,每个账户都可以发布交易,区块链可以看做账本,那么发布的交易应该写在哪个区块里呢?交易广播给每个区块,每个人都在自己本地的区块链上写入交易,如何保证写入后的一致性?也就是说账本的内容要取得分布式的共识(distributed consensus)

分布式系统的一些不可能结论
分布式系统研究中产生了很多不可能结论(impossibility result)。

  • FLP   impossibility result

FLP impossibility result讲的是在一个异步的系统(asynchronous system)中,网络传输的时延没有上限,即使只有一个成员是有问题(faulty)的,也不可能取得共识。

FLP是研究分布式系统的三个专家的名字开头字母。

  • CAP Theorem

CAP是分布式系统想要的三个性质,Consistency、Availability、Partition tolerance。而CAP Theorem是说任何一个分布式系统中,CAP三个性质最多只能满足其中两个,不可能三个全满足。

分布式共识中一个比较著名的协议是Paxos,这个协议能够保证一致性。即如果该协议达成了共识,这个共识一定是一致的(即不会出现系统中两个成员的共识不一致)。但是Paxos协议是有一个较小的概率(虽然小但是客观存在),使得系统一直无法达成共识。

分布式共识中协议Paxos 可以保证Consistency(若达成共识必然一致),但在某些情况下,可能会一直无法达成共识。

【在这里附上一个Paxos协议详解:https://my.oschina.net/u/150175/blog/2992187

四、比特币中的共识协议

背景:假设系统中存在部分节点有恶意,但存在比例较小。大多数节点为“好”的节点,在这种情况下进行共识协议设置。
想法1:直接投票
某个节点打包交易到区块,将其发给其他节点,其他节点检查该候选区块,检查若正确投赞成票,若票数过半数,加入区块链。
存在的问题1——恶意节点不断打包不合法区块,导致一直无法达成共识,时间全花费在投票上。
存在的问题2——无强迫投票手段,某些节点不投票(行政不作为)。
存在的问题3——网络延迟事先未知,投票需要等多久?效率上会产生问题。
更大的一个问题——membership。如果是联uoyi s盟链,对加入成员有要求,可以基于投票。但比特币系统,任何人都可以加入,且创建账户及其简单,只需要本地产生公私钥对即可。只有转账(交易)时候,比特币系统才能知道该账户的存在。这样,黑客可以使用计算机专门生成大量公私钥对,当其产生大量公私钥对超过系统中一半数目,就可以获得支配地位(女巫攻击)。所以,这种简单的投票方案也是不可行的。
 

比特币系统中采用了很巧妙的方案解决这个问题。虽然仍然是投票,但并非简单的根据账户数目,而是依据计算力进行投票。
在比特币系统中,每个节点都可以自行组装一个候选区块,而后,尝试各种nonce值,这就是挖矿。[H(block header)<=target]
当某个节点找到符合要求的nonce,便获得了记账权,从而可以将区块发布到系统中。其他节点受到区块后,验证区块合法性,如果系统中绝大多数节点验证通过,则接收该区块为最新的区块并加入到区块链中。
 

1、会不会合法区块被拒绝?
如图所示。发生分叉的情况下,暂时保存分叉情况,但区块链只承认最长合法链,随着时间推移,必然存在某一条链变成最长合法链。这样,也就会导致合法区块被拒绝

2、分叉攻击
如图所示,A用户对上面的A转账给B的记录回滚,从而非法获取利益。在两条链上,发现交易都合法。这是一个典型的双花攻击。A给B转账后,用分叉攻击将钱又转回来,覆盖掉原来的记录。
在比特币系统中,这种情况实际上很难发生。因为大多数矿工认可的是最长的合法链,会沿着上面的链继续挖下去。而A这个攻击者要想回退记录,就必须使得下面的链变得比上面的链还长。理论上来说,攻击者需要达到整个系统中51%的计算力,才能使得这种攻击成功。

此外,区块链正常运行场景下,也可能会发生分叉。当两个节点同时获得记账权时,会有两个等长的合法链。在缺省情况下,节点接收最先听到的区块,该节点会沿着该区块继续延续。但随着时间延续,必然有一个链胜出,由此保证了区块链的一致性。(被扔掉的区块称为“孤儿区块”)

可见,依赖于算力竞争,有效的防止了“女巫攻击”。

四、比特币激励机制

为什么系统中节点要竞争记账权?需要提供算力和电力成本,节点为什么要去做?

比特币系统设计之初便考虑到了这个问题,那就是引入激励机制。比特币通过设置出块奖励来解决该问题,一个获得合法区块的节点,可以在区块中加入一个特殊交易(铸币交易)。事实上,这种方式也是唯一一个产生新比特币的途径。

比特币系统设计规定,起初每个区块可以获得50个比特币,但之后每隔21万个区块,奖励减半。

但是这样就可以了吗???
区块中保存交易记录,那么,会不会存在节点只想发布区块而不想打包交易?中本聪在设计该系统时,引入了交易费。在一个区块中,其输入>=输出,差值便是给区块所属节点的手续费。这些会在后续文章中详细说明。
 

五、一些问题


共识协议取得的共识到底是什么?

在普通的分布式系统中,如分布式哈希表里,取得的共识就是哈希表中的内容。比特币系统中,共识协议取得的共识是去中心化的账本里的交易。

只有获得记账权的结点可以往区块里写交易,而获得记账权的途径就是解那个不等式puzzle,根据第一节课学习的哈希函数puzzle friendly的性质,求解这个puzzle的过程没有捷径,只能一个一个nonce去尝试,所以可以作为工作量的证明,算力越强得到出块奖励的概率也就越大,所以才说比特币系统中是靠算力来投票的。

靠算力投票是如何避免女巫攻击的?

        因为投票是靠算力的,创建多少个账户都没有影响,创建很多账户并不会使每秒尝试的nonce数目增加。

为什么形容取得记账权的过程为挖矿(mining)?

矿的数量有限,比特币总量有限。
挖矿的过程很难,挖到矿的回报很大,比特币取得记账权来获得出块奖励也是一样。

   

猜你喜欢

转载自blog.csdn.net/djklsajdklsajdlk/article/details/127195632