[北大肖臻-区块链技术与应用笔记]第三节课——共识机制

[北大肖臻-区块链技术与应用笔记]第三节课——共识机制

一、数字货币

💵 假设权威机构——中央银行发行数字货币

数字货币与纸质货币

直接为货币的面额等信息,用央行的私钥签名,然后使用的时候,用户直接拿央行的公钥验证签名(假设大家都知道公钥)。

image-20220412214229244

问题:虽然签名保证了没办法篡改其中的内容,但是这样的数字货币可复制,因为数字货币本质上还是一个文件——花两次攻击(double spending attack)。不像是纸质货币,花出去手上就没有。

解决双花攻击——中心化方法

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

image-20220412215015970

在支付时,不仅要用公钥验证签名是央行签署的,还要通过央行验证该货币是归自己所有,央行再将货币所有者改成支付给的那个用户。

不仅数字货币的发行是由央行统一控制,而且每次交易都要由央行确认其合法性,这种方案是一个中心化的方案。

去中心化

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

1️⃣ 怎么决定数字货币的发行及发行量

2️⃣ 怎么验证交易的合法性,防止双花攻击

第一个问题在BTC系统中是挖矿决定的

第二个问题的解决,要维护一个数据结构,由所有用户来共同维护,这个数据结构也不再是关系表,而是区块链

举例

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

image-20220412220623152

BTC系统中每个交易都分为输入部分和输出部分,输入部分要给出这笔交易的BTC的来源以及付款方的公钥,输出部分要给出收款人的公钥的哈希值。比如A要转给B钱,就需要给出B的哈希。

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

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

image-20220412221114138

BTC系统中的收款地址就是收款人的公钥取哈希再经过一些转换得到的。

BTC系统也没有提供查询某用户的公钥或账户地址的功能,要向某用户转账,就需要对方提供公钥或账户地址。这种情况收款方可以把公钥公布在网站上。

然而A向B转账,除了A需要知道B的地址,B也需要知道A的公钥。因为一方面A的公钥代表A的身份,B要知道转账的是谁,另一方面是为了验证BTC交易中A的签名(私钥签名公钥验证),也就是说所有结点都需要知道A的公钥才行,每个结点都需要独立验证,即使是一个和交易无关的旁观者也要验证这笔交易的合法性。

如何知道A的公钥

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

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

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

我给你发送信息,用你的公钥加密,你收到信息以后用你自己的私钥解密

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

每个区块中可以有很多交易,这些交易就组成了上节课学习的Merkle Tree。

二、区块结构

image-20220412223313793

注意全结点(fully validating node)是有块身的,需要验证所有交易的合法性;轻结点(light node)是没有块身的,没有办法独立验证交易的合法性。

轻结点没有参与区块链的构造和维护,只是利用了区块链中的部分信息。

系统中大部分结点是轻结点,全结点不是很多。

这节课主要是对全结点进行说明。

块头(block header)

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

1️⃣ version: 用的是BTC的哪个版本的协议

2️⃣ 指向前一个区块块头的哈希指针(注意!这里的哈希值只计算前一个区块的块头,块头保存的Merkle Tree的根哈希就已经可以保证区块中保存的所有交易没有被篡改了)

3️⃣ Merkle root hash: 整棵Merkle Tree的根哈希值

4️⃣ target: 挖矿的难度目标阈值target

5️⃣ nonce: 挖矿用的随机数nonce,要使得 H ( b l o c k h e a d e r ) ≤ t a r g e t H(blockheader)\le target H(blockheader)target

块身(block body)

交易列表

三、共识协议

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

分布式的共识的简单的例子:分布式的哈希表

此时需要取得共识的是哈希表中有哪些hash pair

分布式系统的不可能结论

FLP impossibility result

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

CAP Theorem

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

一致性(C):每次读取要么获得最近写入的数据,要么获得一个错误。

可用性(A):每次请求都能获得一个(非错误)响应,但不保证返回的是最新写入的数据(对应HA,机器故障时仍然能够提供服务)。

分区容错性(P):尽管任意数量的消息被节点间的网络丢失(或延迟),系统仍继续运行(网络分区/网络故障时仍然能够提供服务)。

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

BTC中的共识机制

BTC系统中的共识要考虑到有些结点是有恶意的,假设系统中大部分结点是友好的,有恶意的结点占少数。

共识

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

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

直接投票方式——按照账户数

一种思路是用投票的方式,将所有交易写入一个候选区块,然后发给所有结点,大家验证这个区块中的交易是不是都是合法的,然后投赞成和反对票,按一定投票比通过后将候选区块写入区块链中。

❓ 问题:membership问题,任何基于投票的系统都要考虑谁有投票权,例如hyperledger fabric就是一个联盟链的协议,规定了谁可以参加(只有一些有实力的大公司可以参与)。

因为BTC系统中要产生账户只要在本地生成公私钥对就可以了,所以如果用这种方式,那么有恶意的人就可以进行女巫攻击(sybil attack),只要不断产生账户,然后获取大量的投票权就能控制整个区块链了。

计算力投票

每个结点都可以在本地组装出一个候选区块,把它认为合法的区块放在这个区块里,然后就开始尝试各种nonce值(4 byte),使得 H ( b l o c k h e a d e r ) ≤ t a r g e t H(blockheader)\le target H(blockheader)target。如果某个结点找到了符合要求的nonce,也就**获得了记账权——往BTC去中心化的账本(区块链)里写入下一个区块的权力**,其它结点收到这个区块之后,要验证这个区块的合法性

如检查target的编码nBits域设置的是不是符合BTC协议规定的难度要求、检查带nonce的块头哈希值是不是小于target、检查块身中的每个交易是否都有合法的签名、检查每个交易都没有双花等

候选区块合法了就要去接收吗?

image-20220412230451517

根据前一个区块指针就知道应该插入到哪个位置

如上图,C转账给A,A又将这些BTC转给B,然后A又发起了一次交易把BTC转给自己,这个交易的候选区块在下面,它希望挂在如图的位置上(分支上)。这里其实A所做的相当于将A转给B这个交易回滚了,仅仅做双花的检查会发现这两个分支都是没问题的,但如果接收了,那么在这个分支上A又获得了转给B的那些BTC。

这是一个分叉攻击(forking attack) ,通过往区块链中间位置插入区块,来回滚某个已经发生了的交易。这样一个候选区块检测其内容是合法的,但不应当被接受

如果两个结点同时获得记账权,此时都能插入候选区块,该接收哪个?

这种等长的,多条最长合法链(分支)的情况会维持一段时间,直到某个分支胜出。假如上面的先找到下一个区块,那么下面这个区块就成为了orphan block被丢弃掉。

因为orphan block不在最长合法链里,所以里面的出块奖励的铸币交易也就无效了。

什么是接受一个区块?如果一个结点收到一个区块后,沿着这个区块继续往下扩展,那么就算该结点接受了这个区块

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

BTC中的激励机制——出块奖励

让大家去竞争记账权的动力是什么?获得记账权的结点本身有一定的权力,如可以决定哪些交易被写入下一个区块中,但这不应当成为竞争记账权的主要动力,因为BTC系统设计来希望所有交易都能被公平写入账本。出块奖励机制解决了这个问题。

BTC协议中规定,获得记账权的结点,在发布的区块里可以有一个特殊的交易——铸币交易,在这个交易中可以发布一定数量的BTC,这是发行BTC(产生新的BTC)的唯一方法,不必指定币的来源。这也就解决了前面谈及的去中心化系统中的第一个问题——谁来发行BTC和发行多少BTC。

BTC刚出现时,出块奖励是50个BTC,BTC协议规定每21万个区块之后,出块奖励就要减半,也就变成25个BTC。如今的情况是每个区块中能产生12.5个BTC。

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

矿的数量有限,BTC总量有限。

挖矿的过程很难,挖到矿的回报很大,BTC取得记账权来获得出块奖励也是一样。

争夺记账权的结点称为矿工

参考资料

1、BitCoin and Cryptocurrency Technologies:A Comprehensive Introduction

2、以太坊白皮书、黄皮书、源代码

3、Solidity文档

4、北京大学肖臻老师《区块链技术与应用》公开课系列笔记

5、【区块链学习笔记】2:BTC中的数据结构

6、分布式CAP原则(CAP定理)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值