侧边栏壁纸
博主头像
王一川博主等级

努力成为一个不会前端的全栈工程师

  • 累计撰写 70 篇文章
  • 累计创建 20 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

区块链1.0-比特币中的协议

王一川
2022-11-01 / 0 评论 / 0 点赞 / 1,332 阅读 / 3,384 字
温馨提示:
本文最后更新于 2022-11-01,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

博客是以技术探讨为目的,不构成任何投资建议

炒币有风险,投资需谨慎

请遵守相关法律法规

考虑一个问题:

在不考虑去中心化问题背景下,一个中心化的机构如何发行数字货币,例如:央行。假设全国人民都知道央行的公钥,此时央行发行一张价值100元的数字货币,为了防止伪造使用私钥进行签名,类似纸质货币的防伪标记。当用户进行交易时商家使用央行的公钥进行验证即可完成交易。

这样的方案存在一个致命的问题,那就是无法防止double-spending-attack(双花攻击)。即:数字货币的本质是一串字符串或者文件,与纸质货币难以复制不同,数字货币是可以被无限复制的,因此公钥验证签名是不存在问题的。为了解决这个问题就必须要详细记录每一个数字货币的拥有者,也即央行需要维护一个数据库,存储每张数字货币目前的拥有者,当使用数字货币进行交易时,需要验证数字货币本身的签名是否合法的同时也要验证数字货币的拥有者是否为本人,完成交易后数据库变更当前货币的拥有者。这样即可解决double-spending-attack

上述方案的安全性是没有问题的,同时在实践中也是可行的。但这是一个中心化方案,数字货币是由央行(中心化机构)发行的同时交易的合法性也是由央行(中心化机构)验证的。因此广大用户能否共同承担央行(中心化机构)职能,这就是比特币数字货币系统要解决的问题。

去中心化数字货币系统需要回答两个问题

  1. 谁来发行货币
  2. 如何验证交易的有效性

在比特币系统中,货币的发行是通过挖矿决定的(后面说),因此本文主要回答如何验证交易的有效性即解决double-spending-attack

一、比特币系统如何解决双花攻击

比特币系统中使用区块链技术来解决双花攻击,假设A有10个BTC,给B和C分别转5BTC,此时的区块链如下:

image-20221101143232786

第一个区块表明用户A获取到了10个BTC,即A发行了10个BTC,同时称A获得了铸币权(比特币的铸币权由挖矿来决定)本次交易称为铸币交易(coinbase tx),A与BC的交易区块需要由A进行签名(signed by A)表明本次交易是由A发起的。同时本次交易还需要指明币的来源,即指向铸币交易的输出。下面是后续假想的交易记录

image-20221101143852690

比特币系统中每次交易都包含输入和输出两个部分,输入部分需要指明币的来源,输出需要指明收款人公钥的hash值。

首先,为什么要说明币的来源?

  • 一方面证明币不是凭空捏造的,例如A发起交易的币来自要与铸币交易
  • 最重要是为了避免double-spending

例如B试图进行double-spending,如下图

image-20221101145059783

当最后一个区块尝试写入时,其他节点开始验证,沿着链条进行回溯发现B已经没有余额了,因此最后一个区块被拒绝写入

二、关于A->B交易的若干思考

2.1 A需要知道B的什么信息

A需要知道B的收款地址,比特币系统中账户地址是通过公钥推算出来的(取hash再做一些转换),地址就类似银行账户,那么A如何知道B的地址?在实际生活中A向B转账,B需要主动告诉A的银行账号,银行本身并不会提供查询某个用户银行账号的功能,比特币系统同样如此。被转账用户往往会主动提供自身的地址,例如在互联网上公开自己的钱包地址,例如下面是博主的metamask钱包地址(有钱的小伙伴可以给我转几个币😁😁)

image-20221101150825689

2.2 B需要知道A的什么信息

首先A需要有指向前面铸币交易证明有足够的余额支持本次转账,同时B需要知道A的公钥,不光B需要知道区块链上所有节点都需要知道A的公钥

  • 一方面B需要知道谁转的账
  • 另一方面所有节点需要验证本次交易的签名

那么问题就来了,怎么知道A的公钥?类似B的方法可以公布在网上但是A和B还是有区别的,更重要的是其他节点如何获取A的公钥,作为本次交易的旁观者我没有义务去主动获取A的公钥。因此本次交易A必须也要给出自己的公钥,也就是说交易的输入有两个:

  1. 币的来源
  2. 自己的公钥

这里似乎存在一个安全漏洞,A的公钥怎么能自己说呢?例如存在一个C试图伪造A进行交易,用自己的公钥说是A的公钥,同时使用自己的私钥进行签名。但这种方式是存在问题的,因为交易的输出需要指定账户的hash,而这种方式就会导致C试图伪造交易给出的公钥与币来源的账户hash对不上。 因此上述方案是不存在安全漏洞的。

注:上述画的区块链,每个区块都只包含一个交易,但实际上每个区块包含成百上千的交易,交易与交易之间组成上篇文章说的merkle tree

三、共识协议

到这里区块链的内容相信有了初步的认识,区块链的每个区块分为块头和块身,每个部分包含的数据上篇文章已经介绍过了,那么区块是怎么被写入区块链又被链上所有节点认可的呢?
在区块链中每个账户都可以进行交易,这些交易是被广播给所有节点的,有些交易是合法的,有些交易是非法的,那么这些交易哪些是可以被写进区块链的?按照什么顺序写入?由谁来写入?一种方式是:每个节点自己决定独自打包写入区块链中,在本地构建一个区块链。这种方案存在分布式一致性问题,即:在分布式系统中无法取得分布式共识(distributed consensus)

3.1 理论研究

分布式系统典型代表就是distributed hash table,在分布式系统中存在很多不可能结论(impossibility result),例如

FLP理论:在一个异步的系统里,网络传输时延没有上限,即使只有一个成员有问题,那么也不存在共识

CAP理论:Consistency、Availability、Partition tolerance三者最多只能满足其二

分布式共识最著名的算法是Paxos,这些理论在比特币实际应用关系不大,仅做了解或面试八股文

3.2 比特币的共识

3.2.1 投票

比特币系统的共识需要解决有些节点存在恶意,假设系统中大多数节点是“好人”,在这种情况下如何设计出一种协议。一种方法是通过投票,逻辑如下:

某个节点根据其受到的交易判断出哪些是合法的,并按照某种顺序打包成一个候选区块,将候选区块发送给链上所有节点,节点收到区块后检查一下所有交易是否合法并进行投票,若超过半数则候选区块写入区块链中。

该方案存在一个致命的问题,任何基于投票的方案首先需要解决谁可以投票的问题,而比特币系统创建账号是没有限制的,导致比特币系统基于投票的方案会受到sybil attack(女巫攻击),因此简单的投票是不可行的。

3.2.2 工作量证明

比特币系统重采取一种更为巧妙的投票方式,不是按照账户投票,而是通过计算力投票。每个节点都可以在本地组装一个候选区块,把他认为合法的交易写入这个候选区块,然后不断生成nonce值(4bytes)使之满足H(block header) <= target,当找到一个nonce满足这个不等式我们就说这个节点获得了记账权,即:该节点可以将本地的候选区块写入区块链中,其他节点收到区块后验证一下是否合法(交易是否合法、块头数据是否正确)即可。

3.3 最长链原则

如果满足了工作量证明的所有条件,合法的候选区块是否就真的就可以被写入区块链中,看下面的区块是否被接受

image-20221101163631225

假设标绿的区块是合法,该区块是否可以被写入?

候选区块被写入在区块链哪个位置是通过block header中的hash of pre,这些值是可以被节点自由填入的

假如区块链已经存在一个交易是A->B,候选区块中存在A->A会被写入吗?有聪敏的小伙伴立刻就说这不是double-spending吗?其实不是的。验证double-spending是进行链上回溯,A->A的回溯链不包含A->B,因此候选区块是合法的。但这个区块不应该被写入,因为一旦写入相当于把A->B的交易进行回滚,显然是不被允许的。

因此:虽然候选区块是合法的,但不在最长合法链上(longest valid chain)。比特币接受的区块应该是在拓展最长合法链

上述问题其实是forking attack(分叉攻击),通过往区块链中间位置插入一个区块来回滚已经发生的交易

正常情况下比特币系统的区块链也有可能存在分叉情况,例如两个旷工几乎在同一时间找到了一个满足不等式的nonce,这种情况会在短时间内存在分叉情况,直到某个分叉有新的合法区块来拓展导致该分叉存在的链成为最长合法链为止,另一个竞争失败的分叉被称为orphan block被放弃。这会导致再出现分叉情况时会有两个“派系”进行算力或运气上的竞争。那么为什么大家会竞争这个记账权呢?首先获得记账权的节点有权决定哪些交易被写入区块链中,但比特币的设计初衷是只要是合法的交易都应该被写入,因此记账权不应该被作为其争夺的奖励。

3.4 出块奖励

比特币协议规定,在获得记账权的节点在发布候选区块时可以加一笔特殊的交易,即:铸币交易。这就回答了最开始提出的“去中心化数字货币系统需要回答两个问题”。铸币交易(coinbase transaction)是比特币系统中发行货币的唯一方式,只有这个交易不用指定币的来源,因为这个币是凭空捏造的,其他所有的交易都只不过是把BTC从一个账户转移到另一个账户。

在比特币系统运行初期,出块奖励为50BTC,同时协议规定在21万个区块后出块奖励减半。截止2022年的出块奖励为6.25BTC


因此在比特币系统中,共识机制取得的共识到底是什么?

取得共识的是去中心化账本的内容

谁能决定账本的内容:取得记账权的节点

如何取得记账权:通过解不等式

因此比特币的共识机制是通过算力决定的,通过算力(hash rate每秒试的次数)进行投票

思考题:算力投票是怎么避免sybil attack的

0

评论区