• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
fyyy94
博客园    首页    新随笔    联系   管理    订阅  订阅
比特币学习杂记

基本概念

  1. 比特币是基于交易的记账系统,而不是基于账户的,一个“账户”对应的余额是通过索引交易链推算出的
  2. UTXO:未花费交易输出
  3. 交易的输入要给出UTXO的来源(hash) 以及顺序

比特币的数学模型(简要)

  1. 出块时间控制 -- 概率上控制10分钟
    出块时间总体符合指数分布:
    \( f(x) = \frac{1}{u} e^{-\frac{1}{u} x} \)
    其累计分布函数:
    \( F(x) = 1 - e^{-\frac{x}{u}} \)
    从而\(P(X \ge x) = e^{-\frac{x}{u}}\), 指数分布有个重要性质是无记忆性,即\(P(X \ge r + t | X \ge r) = P(X \ge t)\),举个例子来说,比如等待客人到来是服从指数分布的。那么我等了10分钟客人还没来,接下来客人到来的概率分布情况仍然是符合指数分布的,与我等多久没关系. 这里主要要表明的是已发生的事件对后续事件发生没什么影响
    数学上验证很简单:
    \( P(X \ge r + t) = e^{-\frac{r + t}{u}}; P(X \ge r) = e^{-\frac{r}{u}}; 由贝叶斯公式 P(X \ge r + t | X \ge r) = P(X \ge r + t) \times \frac{1}{P(X \ge r)} = e^{-\frac{r + t}{u}} / e^{-\frac{r}{u}} = e^{-\frac{t}{u}} = P(X \ge t) \)
    上个公式中,\(u=10\),表示整个系统的出块时间期望是10分钟

无记忆性有个好处就是保证算力与奖励的公平性。但我觉得课程里并没有把progress free对公平性的保证机制说清楚。实际上,progress free的工作机制我觉得他也没说

  1. 出块奖励递减
    每隔21W个区块,出块奖励减半,初始区块奖励为50,因此总的区块发行数量为:
    \( 210000 \times 50 \times(1+\frac{1}{2} + \frac{1}{4} + ... ) = 105 \times 10^5 \times (\lim \frac{1-0.5^n}{1-0.5}) = 210\times 10^5 = 21 \times 10^6 \)
    因此总的比特币发行数量为2100W个比特币。递减周期约为4年,比特币发行数量减少是人为设计的。

比特币的分叉攻击

这里假设,比特币系统中的区块链的交易账本是正常的。那么分叉攻击的实现方法是:

digraph blk_chain {
  subgraph cluster_0 {
    label="new block"
    node[shape="box"]
    blk_h0[label="header"];
    blk_body0[label="body"];
}
  subgraph cluster_attack {
    label="attack block"
    node[shape="box"]
    blk_hat[label="header"];
    blk_bodyat[label="body"];
}

subgraph cluster_1 {
    label="blk1'"
    node[shape="box"]
    blk_h1[label="header"];
    blk_body1[label="body"];
}


subgraph cluster_2 {
    label="blk2'"
    node[shape="box"]
    blk_h2[label="header"];
    blk_body2[label="body"];
}


subgraph cluster_3 {
    label="blk3'"
    node[shape="box"]
    blk_h3[label="header"];
    blk_body3[label="body"];
}


subgraph cluster_4 {
    label="blk4'"
    node[shape="box"]
    blk_h4[label="header"];
    blk_body4[label="body"];
}
 kk[label="B交付商品"]
 blk_h3 -> blk_h4
 blk_h2 -> blk_h3
 blk_h1 -> blk_h2
 blk_h0 -> blk_h1
 blk_hat -> blk_h1
 kk->blk_h0
}

图中,attack_block 是攻击区块,由恶意节点产生,new block 是新产生的区块,包含正常的交易。分叉攻击的逻辑是这样的:

  1. 先发起正常交易A->B: B 检测到被部分节点打包进区块后(相当于验证了交易),然后交付
  2. 攻击者利用恶意节点产生新的区块 A->A(图中的attack block),试图回滚这笔交易,如果攻击者的算力大于系统中的大多数算力,则新区块的所在的链可能会失败,从而交易被回滚

这里有几个问题,

  1. 首先是B已经收到了交易被打包进区块链时,攻击者再发起攻击实际上相当于是两条分叉链的竞争,攻击者链胜出的要求攻击者具有较多的算力
    • 拥有系统中多数算力时,攻击者可以做很多事情,二不光是这个用分叉交易做交易回滚。
  2. BTC是一个分布式系统,B收到交易添加进区块链,只意味着B附近的节点认可了这个正常区块,不意味着系统中的全部节点都已经达成共识,如果攻击者的攻击区块传播速度很快(有可能的),系统中大部分节点接受这个攻击区块的话,交易也会被回滚,当然这个概率比较低。
  3. 比较靠谱的方法是,B在收到交易打包进区块链时,在多等几个区块,如下图所示:
digraph f{
subgraph cluster_0 {
    label="blk0'"
    node[shape="box"]
    blk_h0[label="header"];
    blk_body0[label="body"];
}


subgraph cluster_1 {
    label="blk1'"
    node[shape="box"]
    blk_h1[label="header"];
    blk_body1[label="body"];
}


subgraph cluster_2 {
    label="new block"
    node[shape="box"]
    blk_h2[label="header"];
    blk_body2[label="body"];
}


subgraph cluster_3 {
    label="blk3'"
    node[shape="box"]
    blk_h3[label="header"];
    blk_body3[label="body"];
}


subgraph cluster_4 {
    label="blk4'"
    node[shape="box"]
    blk_h4[label="header"];
    blk_body4[label="body"];
}


subgraph cluster_5 {
    label="blk5'"
    node[shape="box"]
    blk_h5[label="header"];
    blk_body5[label="body"];
}


subgraph cluster_6 {
    label="blk6'"
    node[shape="box"]
    blk_h6[label="header"];
    blk_body6[label="body"];
}


subgraph cluster_7 {
    label="blk7'"
    node[shape="box"]
    blk_h7[label="header"];
    blk_body7[label="body"];
}

 blk_h7 -> blk_h8
 blk_h6 -> blk_h7
 blk_h5 -> blk_h6
 blk_h4 -> blk_h5
 blk_h3 -> blk_h4
 ll[label="B得到消息"]
 ll->blk_h2
 blk_h2 -> blk_h3
 blk_h1 -> blk_h2
 blk_h0 -> blk_h1
 kk[label="B交付商品"]
 kk->blk_h0
}

在这种情况下,攻击者没有拥有多数算力的情况下, 在new block 前插入攻击区块,并被系统大多数节点接收的概率非常低。这是因为,当出现多个确认时(比特币系统中默认是6个确认,即包含交易的区块后6个区块被挖出),交易区块被回滚的概率非常低(攻击者没有大多数算力)。当然,我们要注意到,因为分布式系统的特点,系统中可能仍然会有部分节点因为网络等问题没有收到这个最长合法链,仍然可能会接受攻击区块。

当攻击者有大多数算力时,这个问题就会发生变化。攻击者可以在任意位置开始篡改区块链,因为他的记录链迟早会胜过系统中其他节点维持的链

比特币网络

  1. 去中心化的网络:目标:简单、稳定、但效率不高
  2. 交易 flood 传播,且不重复转发
  3. 可能出现Race condition ??
  4. 区块大小和带宽有关,比特币的传播方式决定了其区块不能特别大
  5. 比特币是应用层,其网络层是一个基于TCP的点对点传输网络
    • 比特币系统中各节点是对等的,即没有主节点、从节点这种东西
    • 比特币系统中各节点可能要维护邻居节点信息, 用于传播
    • 使用TCP是为了便于穿过防火墙
  6. best effort 模式
  7. 交易池:交易池不是UXTO池,UXTO池相当于余额

几个问题:

  1. 交易被重复打包怎么办?
    • 打包了同一个交易的多个区块(如果有),只有一个会胜出
    • 监听到某个交易打包时,则矿工应当调整自己的区块交易,删除重复内容
  2. 不同的人打包了不同的交易 --> 区块对决
  3. 交易池中出现了冲突的交易如何解决?
    • 比如A只有5个Btc,分别给B C 转5 个,则A->B A-C 中只有一个是有效的,不同的节点可能会选择其中一个打包,但是最终只会有一个会胜出。比如A-C 胜出时,则A->B 交易被判定为非法
    • 作为接受者,B C 应当多等几个确认,这能确保自己收到的交易确认信息是有效的。前面说过,因为节点位置问题,即便B收到A->B 被打包进区块的消息也不意味着不会被回滚。但是当多等几个确认(比如6个)时,则被回滚的概率非常低。

挖矿难度调整

  1. 出块时间太短的问题:

    • 分布式系统的特征:因为节点位置不同,所以时间越短出现的分叉可能就越多,这会造成算力浪费(出现太多的孤儿区块),同时也会让系统共识难度增加
    • 安全性问题:因为算力被分摊给多个分叉,这使得攻击者的攻击分叉更容易胜出(概率)
  2. 难度调整规则:每2016个区块调整难度,2016各区块预期值是2周调整方式\(ntarget = target \times 2w / actual\_time\), 公式可见:实际2016个区块花费时间超过2周时,目标值减小,挖矿难度增加;相反,目标值增大,挖矿难度减小

  3. 挖矿条件:\(hash(header) \le target\)

  4. 挖矿ASIC:专用电路挖矿,生命周期较短,刚几个月时间内能够大幅占据算力,而后可能会被新的AISC替代。比特币系统中对算力的监控变化(比如系统算力突然增大)可以推断出新的矿机出现

    • 因为ASIC矿机的生命周期较短,因此往往需要提前预定。交付后立即投入使用。

阶段总结

  1. 最长链、最长合法链的区别
  2. 全节点、轻节点
  3. 矿工和矿池、矿主和矿工的写作、矿工的工作量证明(Q:什么是BTC的POW?)
  4. 矿池的利弊
  5. 51% 攻击类型:
    • 分叉攻击
    • 拒绝攻击(拒绝某些账户的交易)
    • 盗币交易 (生成的链不是合法链,会被拒绝)
  6. selfish mining 攻击
    • 这个说的是,恶意节点在掌握大多数算力的情况下挖掘的链比系统中的最长合法链长,但是他不发布。当别人挖掘新的区块时,他立即发布连续两个区块(或者多个),使得自己成为最长合法链,从而使得别人的工作白费,自己坐拥100%收益
    • 如果拥有大部分算力的节点诚实的话,那么他只能收获对应比例的收益
      比特币系统中,盗币是不可能的,无论算力多少,原因如下:
  7. 盗币交易的签名不合法,不会被诚实的节点认可,包含的区块会被认为非法区块,对应链属于非法链
    • 如果系统中攻击者节点(算力)较多,那么就会产生硬分叉,这通常划不来
  8. 如果想要直接盗取别人挖区块,也是不可能的,原因如下:
    • 如果要实现盗取,则需要更改coinbase里面的收款账户,这会引起header中的merkle tree hash发生变化,从而整体hash变化,进而不会满足要求

比特币脚本

重点:交易是怎么验证的

  1. 基于栈的语言,没有循环结构,语言较为简单
  2. 用当前交易的输入脚本+前一个交易的输出脚本联合执行,如果不出错,则表明验证通过。有多个输入场景时,则每一个配对都需要验证
  3. 三种交易形式:P2PK P2PKH P2SH
    • Pay 2 PublicKey
    • Pay 2 PublicKeyHash
    • Pay 2 ScriptHash 这里的Script叫ReedemScript(赎回脚本),主要用于解决多重签名问题,早期多重签名场景,需要用户发起交易时填写多个public key,不是很方便。P2SH 使得用户填入ScriptHash即可。 ReedemScript 在 发起多重签名交易的输入脚本中用序列化形式给出。而对应其引用的交易的输出脚本只需要验证该hash即可。
      • 多重签名解决了 私钥泄露问题(需要多个私钥签名)、私钥丢失问题(还有多个私钥可用),相当于增强了安全性
      • P2SH 不是一开始就引入的,而是后面通过软分叉形式引入。
  4. 比特币脚本不是图灵完备的,但是针对比特币应用场景做了高度优化
  5. MULTI_SIG 签名验证操作实现有bug,会从栈顶上多弹出一个元素,因此使用多重签名的输入脚本,通常要提前准备一个无用的元素
  6. RETURN + anything 会直接返回错误,在输出脚本语句中写入RETURN语句会造成该交易输出不可用(总是运行失败),这相当于销毁了比特币
    • 如果交易输出金额为0,相当于用一定的交易费用(给矿工)来写入一些特殊信息,比如知识产权保护信息等
    • 如果交易输出金额不为0,则相当于就是要销毁一定金额比特币,可能用于置换新币,或者做别的事情

bitcoin的脚本相当于一种DSL,图灵不完备

比特币分叉

重点

  1. 硬分叉

协议修改导致产生的永久性分叉,本质是旧节点不能兼容协议修改后的节点,导致旧节点始终按照旧协议来走。这是因为新节点产生的区块被认为是非法的,无论其多长,都不会被作为有效区块链认可(对旧节点而言)。并且,只要旧节点不升级,该硬分叉始终会保留

比如,将比特币区块大小限制从1M提升到4M,旧节点不兼容这种区块(向后不兼容),实际的例子是ETC和ETH.

硬分叉有个问题是会导致在分叉钱的某人的账户的金额会变成双份(或者多分),从而它们可以在分叉链上分别消费。硬分叉容易引起各种歧义问题。

  1. 软分叉

协议或者某些数据域修改,导致的临时性分叉,本质是新节点不兼容协议修改前的节点(产生的区块)。导致新节点始终按照新协议来走。 但是因为旧节点可以接受新协议区块,所以它们可能也在新协议产生的区块链上继续扩展。但是旧节点产生的区块不被新节点认可。只要系统中大多数算力节点升级了软件。那么旧节点挖出的区块始终会被当做孤儿区块而拒绝,最终它们也会升级软件。该临时性分叉小时

比如,比特币中的P2SH支持。其相当于将验证分为两步1. 按照旧协议验证输入输出脚本 2. 反序列化赎回脚本,验证赎回脚本。 旧节点产生的区块只验证第一步,它们广播区块时,新节点可能因为第2步不通过而拒绝该区块。 最终旧节点会升级软件

  1. 状态分叉:

比如分叉攻击、或者多个节点同时挖出区块时的各分叉竞争,状态分叉最后会因为一个最长合法链的胜出而消失

比特币匿名

  1. 匿名性排名
    • cash > 不记名银行账户 > 比特币
    • 原因:比特币交易公开且不可篡改,一旦账户关联被分析出,匿名即被破坏
  2. 比特币匿名性被破坏case:
    • 与实体发生交互,比如比特币交换大额现金,或者实体消费,这些都可以被追溯,且只要知道某人在某时刻干了什么事情,联合比特币上的交易信息,即可破坏匿名
    • 交易时,账户之间的关联,包括多个联合输入账户及找零账户都可被推算
  3. 零知识证明:
    • 证明某个陈述,但不透露陈述之外的任何信息
    • 同态加密:$ \forall x \ne y, E(x) \ne E(y)$; \(E(x)+E(y) = E(x + y); E(xy) = E(x) E(y)\)
      • 证明场景: 知道\(x+y=7\), A提供\(E(x),E(y), x+y=7\) 三个信息,B可以验证\(E(7)\)是否等于\(E(x) + E(y)\) 而不用知道x y 具体数值
      • 盲签:
        • A 发起交易,申请签名token, 中心银行从A账户划去一笔费用,并提供该账户
        • A 将token + 序列号 发送给B
        • B 将token + 序列号 发送给银行,银行增加B的金额
        • 过程中 银行不能将A B联系起来? 这里银行能否通过Token 将A B联合起来?

阶段总结

  1. hash指针:实际系统中,只有hash,没有指针,只是为了形象描述。实际的存储结构使用levelDB 存储kv 键值对
  2. 区块恋: 私钥分割 安全性下降,私钥分割不如多重签名
  3. 分布式共识: 实际没有真正的共识,如果有足够多的算力做坏事,那么区块链可以混滚到创世区块位置。但比特币的设计是基于系统中大部分算力都是好的
  4. 加密货币的稀缺性:
    • 冷启动问题,早期激励
    • 稀缺性资源不适合作为货币,如黄金,因此比特币不适合用于货币目的
  5. 量子计算: 暂时不用担心

未确认问题

  1. 比特币的交易结构
  2. merkle tree 如何组织和生成?
posted on 2025-09-01 18:33  feiyangyy94  阅读(19)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3