Skip to content

Latest commit

 

History

History
112 lines (55 loc) · 4.3 KB

4. BTC 共识协议.md

File metadata and controls

112 lines (55 loc) · 4.3 KB

数字货币如何发行

中心化方案

方案一:中心化方案,央行发行,每一张数字货币都由央行使用私钥签名,花钱时每个人用公钥验证数字货币是否是央行发行的

问题:==双重支付==(double spending attack)

改进方案:每一张数字货币都有编号,央行记录每一张数字货币在谁手里。支付时除了需要验证该数字货币是否是央行发行的以外,还要向央行确认该数字货币在谁手里。

改进方案问题:每次支付都要通过央行,太复杂

去中心化方案

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

  1. 谁来发行:BTC 使用挖矿
  2. 双重支付问题:区块链

区块链

基本原理

image-20221016140827784

图 1(A 获得了铸币权,简化为每个区块只有一个交易)

A 给 B 转账的交易中需要有:

  1. A 的私钥签名:证明这个交易是由 A 发起的
  2. 输入:币的来源(防范 double spending)和 A 的公钥
  3. 输出:收款人公钥的 hash(即地址,A 要给 B 转账,A 需要知道 B 的地址,这个地址由 B 告诉 A)

==所有节点都需要知道 A 的公钥,是为了验证 A 的签名是正确的==。A 的公钥在转账交易中由 A 自己给出,记录在转账交易中。

问题:有人(A')冒名顶替 A,自己生成一对公私钥,记录在交易中,如何避免这个问题?

解决方案:==每个输出中记录了公钥的 hash(即收款人的地址),如果有人冒充 A,币的来源中的公钥 hash 和交易中的公钥 hash 验证不通过,即无法验证币的来源是 A'==。

Tips:

在实际的实现中,验证 A 的签名和币的来源的过程由比特币脚本完成。

BTC 区块结构

Block Header

  • version
  • hash of previous block header: 只计算 header 的 hash
  • merkle root hash: 保证 block body 里包含的交易没有被篡改
  • time
  • target: 挖矿难度
  • nonce: 随机数用来挖矿

Block Body

  • transaction list

区块链中的两类节点

  • 全节点(full node)
  • 轻节点(light node): 只保留 block header 的信息,无法独立验证交易的合法性

分布式共识 (Distributed Consensus)

例子:分布式 hash 表,即系统中所有节点共同维护一个全局的 hash 表,需要取得共识的内容是 hash 表中包含哪些 key-value。

中心化系统中,可以用 Paxos 等共识协议解决。

BTC 中的共识协议是为了决定哪些交易需要写到区块中,需要解决恶意节点的问题,假设系统中大多数节点是好的,如何设计共识协议?

方案 1:投票决定,半数以上通过就接受交易 问题

  • 谁有投票权?(联盟链是特定账户才有投票权)
  • 女巫攻击(sybil attack):产生大量公私钥,超过总数一半

解决方案:==POW(挖矿),按算力投票==。每个节点都可以在本地组装一个候选区块,把它认为合法的交易打包到区块中,然后开始挖矿。

挖矿:找到 Hash(block header) <= target (通过改变 block header 中的 nonce)的节点获得记账权,可以把交易写到区块中并发布到网络中,其他节点收到这个区块后需要验证区块的合法性。

区块合法性:每个交易是合法的(使用的币没有被花过、签名正确、block header 验证通过)

最长合法链原则

是否有可能验证通过也不接受区块?有可能,出现分叉的情况,通过最长合法链原则确定应该接收哪个链。

区块链正常情况下也可能发生分叉:两个节点几乎同时找到了符合要求的 nonce,获得了记账权。 默认每个节点接受最早收到的区块,沿着这个链继续向下扩展(挖矿),出现的分叉只是临时的,但最终只会有一个链生出(最长链)

==分叉攻击(forking attack)==:通过向区块链中间某个位置插入一些区块,来回滚某些已经发生的交易。

节点为什么要争夺记账权

出块奖励:coinbase transaction,发行新 BTC 的唯一方法,初始 50 BTC,每过 21 万个区块减半。