比特币:共识协议

liujie
liujie
发布于 2024-06-14 / 2 阅读
0
0

比特币:共识协议

工作量证明

工作量证明是通过计算来猜测一个数值(nonce),使得拼凑上交易数据后内容的 Hash 值满足规定的上限(来源于 hashcash)。由于 Hash 难题在目前计算模型下需要大量的计算,这就保证在一段时间内,系统中只能出现少数合法提案。反过来,如果谁能够提出合法提案,也证明提案者确实已经付出了一定的工作量。

同时,这些少量的合法提案会在网络中进行广播,收到的用户进行验证后,会基于用户认为的最长链基础上继续难题的计算。因此,系统中可能出现链的分叉(Fork),但最终会有一条链成为最长的链。

Hash 问题具有不可逆的特点,因此,目前除了暴力计算外,还没有有效的算法进行解决。反之,如果获得符合要求的 nonce,则说明在概率上是付出了对应的算力。谁的算力多,谁最先解决问题的概率就越大。当掌握超过全网一半算力时,从概率上就能控制网络中链的走向。这也是所谓 51% 攻击的由来。

参与 PoW 计算比赛的人,将付出不小的经济成本(硬件、电力、维护等)。当没有最终成为首个算出合法 nonce 值的“幸运儿”时,这些成本都将被沉没掉。这也保障了,如果有人尝试恶意破坏,需要付出大量的经济成本。也有人考虑将后算出结果者的算力按照一定比例折合进下一轮比赛。

有一个很直观的超市付款的例子,可以说明为何这种经济博弈模式会确保系统中最长链的唯一性。

Pow 保证一致性

假定超市只有一个出口,付款时需要排成一队,可能有人不守规矩要插队。超市管理员会检查队伍,认为最长的一条队伍是合法的,并让不合法的分叉队伍重新排队。新到来的人只要足够理智,就会自觉选择最长的队伍进行排队。这是因为,多条链的参与者看到越长的链越有可能胜出,从而更倾向于选择长的链。

可以看到,最长链机制可以提高很好地抗攻击性,同时其代价是浪费掉了非最长链上的计算资源。部分改进工作是考虑以最长链为基础,引入树形结构以提高整体的交易性能,如 GHOST 协议(《Secure high-rate transaction processing in bitcoin》)和 Conflux 算法(《Scaling Nakamoto Consensus to Thousands of Transactions per Second》)。

双花问题

在比特币系统中,Hash指针有两个用途:指向前一个区块和指向某笔交易。

比特币支付过程中,每笔交易都必须包含输入和输出。

交易输入中需要包含付款方此次交易的币的来源,付款方的公钥,交易输出包括此次要交易的币的数量以及收款方的地址。

币的来源中会包含付款方的地址,这样可以防止盗币事件的发生。

在交易时,首先会从区块中验证交易输入,验证通过后才会执行交易输出。这一步可以防止“双花”攻击。

共识

区块链是一个去中心化的分布式账本,既然是分布式,那就需要网络中的各个节点对账本信息达成共识,保证比特币网络中使用的都是同一份账本。

在生活中,当对某个问题产生分歧时,通常会采用投票的形式来进行表决,大部分情况下采用的都是“少数服从多数”的原则。当在区块链网络中是很难操作的。

假设区块链网络中的大多数节点都是诚实节点,只存在少部分恶意节点。如果采用投票的形式来决定区块的产生,那么会面临以下几个问题:

  • 谁有投票权

  • 网络延迟

  • 存在弃权节点

  • 女巫攻击或者“水军”攻击

针对以上问题,比特币使用了“算力”来进行投票,决定新区块的产生。

数字货币的交易,如果只用到密码学中的非对称加密体系,没有区块链的话,数字可以复制,会出现双花攻击。

数字货币面临的主要挑战就是怎么防范双花攻击。

比特币数字货币系统的主要问题

数字货币的发行方:挖矿

怎么防范双花攻击

发行货币的权利:铸币权creat coin

图中构成一个小型区块链。如下图,假设用户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来发起交易?如B的同伙B’说自己是A,然后用自己的私钥签名,将自己的公钥说是A的公钥放在交易输入部分里,尝试将A账户上的比特币转走。

    因为币的来源(图中铸币交易)中交易的输出部分有收款人A的公钥的哈希值,这时B’伪造的公钥的哈希就和A的公钥的哈希对不上了,所以可以防止这种攻击(查一下全结点存在内存中的UTXO。要花掉的币只有在这个UTXO这个集合里才是合法的,否则要么是不存在的,要么是已经花过了的。)

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

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

区块结构

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

  1. 块头(block header)

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

  • 用的是比特币的哪个版本的协议

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

  • 整棵Merkle Tree的根哈希值

  • 挖矿的难度目标阈值target

  • 挖矿用的随机数nonce,要使得H(blockheader)≤target

  1. 块身(block body)

    交易列表

全结点(fully validation node)是有块身的,需要验证所有交易的合法性

轻结点(light node)是没有块身的,没有办法独立验证交易的合法性。轻结点没有参与区块链的构造和维护,只是利用了区块链中的部分信息。

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

分布式共识(distributed consensus)

分布式系统的一些不可能结论

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

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

比特币中的共识协议

一种思路是用投票的方式,将所有交易写入一个候选区块,然后发给所有结点,大家验证这个区块中的交易是不是都是合法的,然后投赞成和反对票,按一定票比通过后将候选区块写入区块链中。这种思路的问题是一个membership的问题,任何基于投票的系统都要考虑谁有投票权,例如hyperledger fabric就是一个联盟链的协议,规定了谁可以参加。

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

比特币系统中不是用账户来投票,而是用计算力来投票

  • 每个结点都可以在本地组装出一个候选区块,把它认为合法的交易放在这个区块里,然后就开始尝试各种nonce值(4 byte),使得H(blockheader)≤target

如果某个结点找到了符合要求的nonce,也就获得了记账权——往比特币去中心化的账本(区块链)里写入下一个区块的权力,其它结点收到这个区块之后,要验证这个区块的合法性(如检查target的编码nBits域设置的是不是符合比特币协议规定的难度要求、检查带nonce的块头哈希值是不是小于target、检查块身中的每个交易是否都有合法的签名、检查每个交易都没有双花等)

  • 检查出的候选区块完全合法,就应当接受吗?

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

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

如何知道某个区块是插入在哪的?

块头有指向前一个区块块头的哈希指针,通过这个哈希指针就能判断了。

接受的区块应当是在扩展最长合法链(longest valid chain):区块链在正常运行下也会出现分叉。如两个人在差不多相同的时间都发布了合法区块,就可能出现分叉。这种等长的,多条最长合法链(分支)的情况会维持一段时间,直到某个分支胜出,另一个分支就成为了orphan block被丢弃掉

这里,部分结点接受上面那个区块,部分结点接受下面那个区块(如果一个结点收到一个区块后,沿着这个区块继续往下扩展,那么就算该结点接受了这个区块),然后他们竞争,谁先找到下一个结点,最终形成一个共识的最长合法链。

激励机制:出块奖励(block reward)

  • 比特币协议中规定,获得记账权的结点,在发布的区块里可以有一个特殊的交易——铸币交易,在这个交易中可以发布一定数量的比特币,这是发行比特币(产生新的比特币)的唯一方法,不必指定币的来源

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

共识协议取得的共识:比特币系统中,共识协议取得的共识是去中心化的账本里的交易**。


评论