1️⃣ 参考
-
北京大学肖臻老师《区块链技术与应用》
- P4 - BTC共识协议篇
- P5 - BTC具体实现篇
-
部分图片和文字来源
- 北京大学肖臻老师《区块链技术与应用》笔记 - BTC篇
- 北京大学肖臻老师《区块链技术与应用》公开课笔记5——BTC具体实现篇
4️⃣ 共识协议篇
① 双花问题?
- 理解: 将同一货币(份钱)花费两次
-
解决:
- 中心化 权威机构对货币添加唯一编号(不可篡改),每次支付向货币发行单位查询真伪。该方法每次交易都需要依赖于第三方机构来判断货币真伪且防止双花攻击。
- 去中心化 采样验证交易合法性,依赖于系统中维护的一个数据结构,记录货币的使用情况。该数据结构由系统中全体用户共同维护,保证了交易的有效性。该数据结构,便是区块链。
② 验证交易合法性【难点】
首先要理解数字货币的发行由谁执行?如何发行?发行多少?什么时候发行?
在比特币系统中由挖矿来决定货币发行权和发行量。
-
交易分为输入和输出两部分
- 输入: 要注明币的来源和发币者的公钥
- 输出: 收款人的公钥的哈希(地址)
-
一个简单的区块链
如下,假定A获得铸币权,新新发布了10个比特币(该交易称为铸币交易)。A将10个比特币转给了B(5个)和C(5个),A对该交易进行签名,同时该交易需要说明所花掉10个比特币来源(来自铸币交易)。之后,B将自己的5个比特币转给C(2个)和D(3个),该交易需要B的签名,该交易需要说明所花掉的5个比特币来自于第二个交易中。然后,C将自己所拥有的全部7个比特币都转给E,并对该交易签名,可以发现该交易中C的比特币来源于两个交易中。 -
如何防止别人伪造交易的发起者,然后签上伪名,从而骗取发起者的财产?
- 假设发起人为A
- 答:验证A的公钥【输入】 与 A币的来源中A的公钥的哈希【输出】能不能对的上
- 详细解释:在交易中,收款方需要知道付款方的公钥,从而验证A签名是否有效。即A需要提供自己的公钥,如果所提供公钥与铸币交易中。(实际上其他节点都需要知道付款方公钥,验证交易合法性)实际中A转账时候提供的公钥需要和铸币交易中公钥对的上,这样就防止了恶意节点伪造A的公钥来“偷”走A的比特币。
实际执行时是先执行A输入的脚本再执行A输出的脚本,运行没有问题(说明币的来源的交易)拼接执行),说明交易成功/合法(BitCoin Script)
③ 区块头信息
-
区块 = 块头(Block Header) + 块身(Block Body)
-
节点 = 全节点(full node, fully validating node) + 轻节点(light node)
Block Header 详细参数名称 | 作用 |
---|---|
version | 使用比特币哪个版本的协议 |
header of previous block header | 指向前一个区块的指针(仅是前一区块块头的哈希) |
Merkel root hash | 整颗Merkel Tree的根哈希值 |
target | 挖矿的难度目标阈值 |
nBits | 目标阈值编码 |
nonce | 挖矿的随机数 |
- 重点
- 挖矿求解问题:
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
:在异步(asynchronous)网络系统中,即使只有一个用户有问题(fault),也不能称为共识。了解更多 -
CAP(Consistency Availability Partition tolerance) Theorem
:只能同时满足两个性质。了解更多
-
- 在分布式系统中有很多经典的不可能问题(
- 共识协议:投票方案
- 内容:一个人打包一部分交易,广播给所有人进行投票,当一半以上的人投了赞成票,交易就通过
- 弊端:任何投票类的解决方案都有,
membership
(谁有投票权)的问题- 限制投票权的解决方案:联盟链(
hyperledger fabric
) :只有大公司才能加入 - 不限制的投票权会有女巫攻击(
sybil attack
):恶意的一方可以创建超过一半的账户,专门用来投反对票
- 限制投票权的解决方案:联盟链(
- 比特币系统中的投票方案:算力投票(记账权)
- 在比特币系统中,每个节点都可以自行组装一个候选区块,而后,尝试各种
nonce
值,这就是挖矿[H(block header)<=target
]。当某个节点找到符合要求的nonce
,便获得了记账权(往比特币去中心化的账本中写入区块的权利)。
其他节点收到区块后,验证区块合法性,比如:- 检查
nBits
是不是满足比特币协议中规定的要求 - 检查
nonce
是否满足 -
block header
的检查 -
block body
中全部交易的检验:是否有签名,币源检验 - 是否满足最长合法链(
longest valid chain
)
- 检查
- 在比特币系统中,每个节点都可以自行组装一个候选区块,而后,尝试各种
🇶🇦 最长合法链特性,会不会导致合法区块被拒绝?
A: 发生分叉时,随着时间推移,必然存在某一条链变成最长合法链,也就会导致合法区块被拒绝。
上面的问题就是分叉攻击(forking attack
)想要实现的效果,通过往中间插入一个区块来回滚之前的交易(使之前转出去的钱回滚回来,相当于"白嫖")。
但在比特币系统中,这种情况实际上很难发生。因为大多数矿工认可的是最长的合法链,会沿着上面的链继续挖下去。而攻击者要想回退记录,就必须使得下面的链变得比上面的链还长。理论上来说,攻击者需要达到整个系统中 51%
的计算力,才能使得这种攻击成功。下图是当前算力的分布图,来源
此外,区块链正常运行场景下,也可能会发生分叉。当两个节点同时获得记账权时,会有两个等长的合法链。在缺省情况下,节点接收最先听到的区块,该节点会沿着该区块继续延续。但随着时间延续,必然有一个链胜出,由此保证了区块链的一致性。(被扔掉的区块称为“孤儿区块”)
⑤ 比特币激励机制
🇶🇦 如何避免说矿工们奔着记账权去的,随意记账,使得整个比特币系统无法存储全部合法的交易呢?
A: 使用出块奖励(block reward),可以获得铸币交易(coinbase transaction)是唯一产生币的途径
-
演变过程:
- 一开始的出块奖励是50BTC
- 21万个区块后减半25BTC
- 再过21万个区块再减半12.5BTC
- 比特币系统的出块时间是10分钟 =》差不多4年减半一次
-
小结
- 投票的权重是看算力(hash rate),这样避免了女巫攻击
- 争夺记账权的过程叫做挖矿(mining),争夺记账权的节点叫矿工
- 矿工收益来源:
- 出块奖励(会随时间降低)
- 每一笔交易的打包费用(少)
5️⃣ 具体实现篇
① 账本模式
区块链是区中心的账本
- 比特币采用的是基于交易的账本模式
transaction-based ledger
收支总账- 优点:隐私性高
- 缺点:需要说明币的来源来验证支出时的合法性
- 以太坊采用的是基于账户的账本模式
account-based ledger
系统没有显式记录每个账户多少钱,都是通过交易记录推算出来
全节点需要维护UTXO: Unspent Transaction Output
数据结构
- 定位utxo中的输出条件:
- 产生这个输出的交易的哈希值
- 它在这个交易里是第几个输出
- 作用是防止
double spending
,只允许花出在UTXO中存在的币
② 比特币区块具体信息
这部分借鉴(复制)了别人博客的内容,偷懒😶
- 什么是挖矿?
可以看到,区块哈希与前一区块哈希都是以一长串0开头的,挖矿本身就是尝试各种nonce,使得产生的区块哈希值小于等于目标阈值。该目标阈值,表示成16进制,就是前面含有一长串的0
下为block header的代码中实现的数据结构。
Block header详解:
-
❗️ ❗️ 此时,只看
header
会发现nonce
是uint32_t
有限值,可以随着挖矿⛏力度的不断加大,nonce
值又不会增大,那难度如何调整呢?-
✨ 修改
merkle root hash
中铸币交易,铸币交易(BTC系统中产生新比特币的唯一方式)中的coinbase 8Byte
域可以写入任何内容 -
事实上
time
的值可以不用非常精确,这里可以适当调整,
-
总的来说,coinbase 8Bytes(extra nonce)
+ nonce 4Bytes
= 12Bytes =
2
96
2^{96}
296bit,下为一个铸币交易的内容:
-
真正挖矿是有两层循环
-
先外层循环调整
coinbase
域的extra nonce
=>merkle root hash
-
再内层循环调整
header
中的nonce
-
③ 交易的具体信息
- 注意:
-
Fee
=Total input
(是币的交易来源output) -Total output
(unspent未花费) -
这笔交易的
input Script
能与上一笔交易的output script
,拼接在一起能够顺利执行
-
④ 挖矿过程的概率分析
求解nonce
的过程是伯努利过程Bernoulli process
,每次实验的概率都是相等的(对 or 不对)
可以用泊松分布Poisson process
近似,出块时间符合指数分布exponential distribution
纵轴表示概率密度,横轴表示出块时间(整个系统的出块时间,并不是每个矿工的出块时间)
平均需要挖10分钟,但不是已经挖了10分钟就快出区块了。挖完10分钟那一刻起,还是平均10分钟
也就是将来还要挖多长时间,跟过去已经挖了多长时间是没有关系的。这个过程也叫progress free
,虽然无情但恰恰是维护区块链网络的去中心化和公平性,如果没有progress free
,算力强的就无敌了,使系统逐渐中心化
图形上理解:任意取一点,做垂线,之后仍然服务这个概率分布,还是平均要等10分钟也就是memoryless
同时要理解:挖矿的puzzle是无意义的,纯拼算力,但过程是维持比特币安全最重要的环节
⑤ 比特币总量(等比数列)
21 万 ∗ 50 + 21 万 ∗ 25 + 21 万 ∗ 12.5 + . . . 21万*50 + 21万*25 + 21万*12.5 + ... 21万∗50+21万∗25+21万∗12.5+...
= 21 万 ∗ 50 ( 1 + 1 2 + 1 4 + 1 8 + . . . ) = 21万*50(1 + \frac{1}{2}+ \frac{1}{4}+ \frac{1}{8} + ...) =21万∗50(1+21+41+81+...)
= 21 万 ∗ 50 ∗ 2 = 2100 万 = 21万*50*2 = 2100万 =21万∗50∗2=2100万
⑥ 比特币系统安全性分析(QA)
- 如何保证区块不被坏节点靠算力篡改?
- 答:等6个新的区块产生再确认,也就是
six confirmation
- 答:等6个新的区块产生再确认,也就是
- 是否凡是写入区块链的内容都修改不了呢?
irrevocable ledger
- 答:并不是绝对意义上的不可修改,新的区块较容易被修改,越往后出新的区块越难修改(指数级)
- 特殊情况:交易发出去了,没有被写入区块链(没有被挖出来)
zero confirmation
- 大多是情况下是这种情况,收到转账记录(没有被写入区块)就"发货",不安全,但可以通过比特币系统外的手段,比如第二天确认后再发货。
- 坏节点,不记录某些交易怎么办?
- 答:没有关系,总会有诚实的节点记录交易(赚手续费)
- 坏节点,自私挖矿
selfish mining
,分叉攻击时,底下藏一条链。准备好坏节点后(获得回滚),再挖后面6个节点,发布时再同时发布6个,跳过验证,怎么办?-
答:需要占据51%的算力才可以,普通坏节点成功不大文章来源:https://www.toymoban.com/news/detail-849980.html
-
另一个角度,不是为了回滚,而是为了出块奖励。坏节点偷偷挖出一个区块A,不发布,此时其他人就都还在挖区块A,如坏节点挖出了下一个区块B。当其他人挖出区块A时,坏节点将区块A和B同时发布,这样别人的A就废了,同时获得了两个区块奖励。精妙的点在于,坏节点是先挖出A,此事没有人跟他竞争区块B,竞争少了文章来源地址https://www.toymoban.com/news/detail-849980.html
-
到了这里,关于北京大学肖臻老师《区块链技术与应用》P4(共识协议)和P5(具体实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!