比特币:点对点的电子货币系统

6.824 2020 Lecture 19: Bitcoin

Bitcoin: A Peer-to-Peer Electronic Cash System, by Satoshi Nakamoto, 2008

为什么读这篇论文?

  • 类似Raft——状态,log操作,log内容和状态的一致性
  • 不像Raft——许多参与者肯定包含恶意的行为——哪些呢?
  • 比起大多系统更加分布式——去中心化,点对点:参与者的身份是位置的,甚至数量也未知
  • 一致性模型非常新颖和有意思
  • 比特币的成功是一个巨大的惊喜

为什么人们会想去用电子货币呢?

  • 可能在线支付更方便、更快、费用更低
  • 信用卡能用,但并不完美
    • 不安全,诈骗,费用,限制,逆转
    • 所有你购买的记录
  • 可能减少各种实体新人的要求(比如银行、政府)

有哪些技术挑战?

  • 伪造(容易解决)
  • 重复花费(难,比特币做的很好)
  • 盗窃(难,比特币不是做的特别好)

社会/经济上的难点?

  • 怎样说服人们比特币是有价值的?
  • 怎样构建一种有商业使用价值和存储价值的货币?
  • 怎样为基础设施支付?
  • 货币政策(刺激,控制通货膨胀等)
  • 法律(税、洗钱、毒品、恐怖主义分子)

想法:交易的签名链(这是比特币中最直接的部分)

  • 一串币,每个被人拥有
  • 每个币有一列交易记录,记录某时间该币作为支付的转移
  • 一个币最后一次的交易表示它现在归谁

交易记录有什么?

  • pub(user1): 新所有者的公钥
  • hash(prev): 币的前一个交易记录的hash
  • sig(user2): 前一个所有者的私钥在交易上的签名
  • (BitCoin 更加复杂,金额(很小),多in/out…)

交易的例子:

1
2
3
4
5
6
7
8
9
10
11
  Y有一个币,是X给的:
    T6: pub(X), ...
    T7: pub(Y), hash(T6), sig(X)
  Y从Z处,买了汉堡,用该币支付
    Z 发公钥给 Y
    Y 创建一个交易,并签名
    T8: pub(Z), hash(T7), sig(Y)
  Y 把交易交易记录发给 Z
  Z 验证:
    T8's sig(Y) 和 T7's pub(Y)对应
  Z 把汉堡给 Y

只有交易是存在的,而不是硬币本身

  • Z的余额是一组未消费的交易,且Z拥有其私钥
  • 硬币的“id”是其最近的xaction(的哈希)

除了硬币的所有者,还有人可以花硬币吗?

  • 当前所有者的私钥需要对下一个交易签名
  • 危险:攻击者窃取Z的私钥,比如从PC、手机等,现实中确实是严重的问题,很难解决

硬币的拥有者可以花两次吗? Y用该币创建两个交易,Y->Z,Y->Q,都是hash(T7) 然后分别展示给Z和Q,交易都看起来没问题,包括签名和hash 所以,现在Z和Q都会把汉堡交给Y

为什么会有重复花费的可能? 因为Z和Q不知道交易的完整集合和顺序

我们该怎么做? 对所有交易都发布log 确保每个人看到同样的log,且顺序一致 确保Y不会撤销已发布的交易 最后: Z先看到Y->Z,就会接受 而Q先看到Y->Z,就会拒绝 “公共账簿”

为什么不这样发布交易呢? 1000+个节点,每个人都运行,每个节点点都不要求信任 交易被发到每个节点 由节点投票,那个交易应该加到下一个log:听大多数的 假设大多数都是诚实的,将会达到一致,并在少数恶意节点中获胜 怎样统计票数? 如何统计节点数,以便知道大多数是多少? 也行,依赖IP地址吗? 问题:西比尔攻击(sybil attack) Ip地址并非安全的——容易伪造,肉机 攻击者可以伪装成有庞大数量的计算机——大多数 当Z询问是,攻击者的大多数回复,Y->Z在Y->Q前面 当Q询问是,攻击者的大多数回复,Y->Q在Y->Z前面 投票的方法在公开模式下难以运作

比特币的区块链 目标:交易log一致性,防止重复花费 区块链包含所有硬币的交易 许多节点: 每个节点都有整个链完整的拷贝 使用TCP和其他节点通信——网状结构 新的块会群发给所有节点,通过TCP推送 提议的交易也会群发给每个节点 每个块: hash(前一个块的) 一组交易 “nonce”(可以使任何东西) 当前时间(时间戳) 从上一个块开始,新的块每10分钟包含xactions 收款人知道块上链才会接受交易

谁创造新块? 这就是“mining”(挖矿)通过“proof-of-work”(工作量证明) 要求:hash(block)有N个前导零 每个节点努力找到随机的nonce,知道满足这个条件 试一个nonce是快的,但是大多数都不满足 - 这就像往湖面掷硬币,知道有一枚浮在水面 - 每次投掷都是独立的事件,极小概率成功 - 挖矿并不是有特定的工作量 成功创建一个块很可能花费CPU,以月计算 但是成千的节点同时都这么算 这么做是期望首次发现这个nonce的时间控制在10分钟,虽然浮动很大 算出来的节点把给所有节点群发新块 工作量证明解决了西比尔攻击,但依靠你的CPU

Y->Z交易如何写进区块链?

  1. 开始:所有节点处于…<-B5,下一个要挖块B6
  2. Y发送Y->Z交易,群发给各节点,
  3. 节点缓冲交易,直到B6计算完成
  4. 节点把Y->Z交易放到下一个块里
  5. 最后…<-B5<-B6<-B7,B7包含Y->Z交易

Q:是否B6后可能不同的后继? A:是的 1) 两个节点同时找到nonces,或者 2) 网络慢,第一个找到前,第二个又被发现了

这两个块很不一样:矿工的新交易集合有些许不一样 如果两个后继,那区块链将出现临时的分叉: - 节点将在先收到的块上工作 - 除非发现更长的链,就切换过去

分叉怎么解决?

  • 每个节点初始化他们第一次看到的新块
  • 试图创建后继块
  • 如果看到Bx比By的节点多,那就越可能在在Bx上挖,所以Bx的后继越可能先创建
  • 即使看到的节点同样多,有个分叉也越可能先被拓展,因为挖矿的时间是很重要的变量
  • 节点总是切到最长的分叉上挖矿,重新达到一致性
  • 那被丢弃的分叉呢?
    • 大多数交易都会在两个分叉上,但只在被丢弃的分叉上的交易,就会消失了

要是Y同时发送Y->Z 和 Y->Q?即Y试图重复花费

正常的节点将接受第一个到达的,忽略第二个,因此下一个快也不会同时包含两条的

要是Y告诉一部分节点Y->Z,另一部分Y->Q?

  • 也行使用网络DoS,防止它们泛滥
  • 也许会导致分叉,B6<-BZ and B6<-BQ

因此:

  • 临时的重复花费是可能的,因为分叉
  • 但是,分叉的一个分支很可能很快就消失了
  • 因此如果Z看到Y->Z,并且后面有些块了,那么另一个带有Y->Q的分叉就很不可能替换调它
  • 如果Z卖的很贵的东西,那Z应该等到交易后已经有些块,才可以消费它
  • 如果Z卖的便宜的东西,一些节点看到Y->Z并且验证通过,大概就没问题了

攻击者能否修改区块链中间已存在的块?然后告诉新节点修改的块? 比如删掉攻击者的使用的交易?

no,因为下个块的prev hash值将会错误,节点可以检测出来

攻击者能否从旧块,开始分叉用包含Y->Q的块替换Y->Z的块?

  • yes——但是分叉要更长,其他节点才会接受
  • 因为攻击者的分叉已经落后于主分支,攻击者必须比其他节点全部的挖矿速度都快
  • 就一个CPU,要花几月才能创建一些新块,这期间内,主分支已经更长了,不会有节点切到攻击者的分叉上的
  • 如果攻击者的CPU资源比所有诚实的节点都多,那么攻击者将会创建更长的分叉,每个人都会切到这个分叉,攻击者就能重复花费了

为什么挖矿这种模式可以运行?

  • 所有参与者中随机选择,沿着那个分叉拓展:CPU的权重
  • 如果大多数参与者都是诚实的,那么就会增强最长分支的一致性
  • 如果攻击者控制了大部分CPU的算力,就会使得诚实的节点切到攻击者创建的分叉上

验证检查:

  1. 节点,新xaction:
    • 交易不能花费同一个之前的交易
    • 前一个交易的签名可以被验证
    • 然后把交易加到txn列表,挖下一个块
  2. 节点,新块
    • hash值要有足够的前导零(nonce是对的,工作量的证明)
    • 前一个块的hash值存在
    • 所有块中的交易都是有效的
    • 节点发现有更长的链,就切过去
  3. Z:
    • (一些client依赖节点做上述的检查,一些不做)
    • Y->Z在块中
    • Z的公钥和地址在交易里
    • 链中有足够的块(还要检查很多,很多细节)

每个比特币最开始是从哪里来的?

  1. 每次节点挖一个块,获得12.5比特币(当前)
  2. 节点把自己的公钥加到块里一个特殊的交易
  3. 这就是人们挖矿的动力

Q:10分钟?可以更短吗?

Q:如果许多矿工参加,块会建的更快吗?

Q:为什么比特币总拓展最长的链?为什么不是其他的规则?

Q:交易匿名?

Q:如果我窃取了比特币,我可以安全的花掉吗?

Q:比特币可以伪造吗,创造假币?

Q:对手可以利用世界上大多数的CPU算力做什么?

  • 通过分叉,可以撤回支付或重复花费
  • 无法窃取他人的比特币
  • 可以防止xaction进入连锁

Q:要是要改块的格式呢? 特别是新格式不能被之前的软件版本接受? “硬分叉”(hard fork)

Q:节点如何找到彼此?

Q:要是一个节点被限制在只能和腐败的节点通信? 要是只能和一个好的节点和许多联合的坏节点通信?

Q:一个全新的节点会被欺骗,而完全使用错误的链? 要是节点失联多年以后,在重新加入网络? 只失联几天?

Q:用一台机器挖矿,你可能赚多少?

Q:为什么挖矿的奖励随时间递减,这没有问题?

Q:比特币的数量是定额的,是个问题吗? 要是真实的经济涨或跌?

Q:为什么比特币是有价值的?比如人们愿意支付$8,935购买一比特币(2020/5/5数据)

Q:比特币扩展性号吗? CPU时间? 显然,CPU限制为4,000 tps(签名检查) 比Visa多,但比现金慢 存储呢? 你是否需要很老的块? 你是否需要扩展整个区块链? merkle树:块头部和txn数据 网络负载? 美10分钟一块,几Mbits 不幸的是,最大块的大小限制几Mbits

Q:比特币只是一个账簿,而没有新货币? 比如,美元能否成货币?因为货币的部分缺失尴尬(结算、挖矿激励)

设计有哪些不足?

  • 作为新货币和支付系统还太糟
  • 交易确认至少要10分钟,或者60分钟更可靠
  • 群发限制了性能,可能成为攻击点
  • 最大块的大小和10分钟,限制了每秒的交易量
  • 易受到大多数(majority)的攻击
  • 工作量证明浪费CPU资源
  • 不是很匿名
  • 太匿名——非法使用可能会引发法律责任
  • 用户保存私钥麻烦

核心想法:区块链

  • 公共的一致性账簿是很棒的想法
  • 去中心化可能也很棒
  • 在公开的系统,挖矿是解决西比尔攻击的聪明办法,也确保了大多数块都是诚信的节点创建的