浅谈区块链(一)—比特币

The Times 03/Jan/2009 Chancellor on brink of second bailout for banks.

2008 年金融危机的海啸席卷全球,同年 11 月,化名中本聪的「神秘人」发表了论文《比特币:一种点对点式的电子现金系统》(Bitcoin: A Peer-to-Peer Electronic Cash System),并

在次年挖出了第一个区块同时获得了 50 比特币的奖励。这一创世区块中,中本聪写下了本文的开头「2009 年 1 月 3 日,财政大臣正处于第二轮银行紧急援助的边缘」,这也是当日《泰晤士报》的头版文章标题。

一个新的时代就此诞生,而笔者将通过这篇文章从最基本的货币交易切入,围绕着比特币的重要特性,最终深入去中心化的思想。本文尽量从设计的角度出发,精简出区块链的核心理念,避免让读者过度纠结于实现细节或可以作为参考资料的前置知识。那么现在就让我们进入一个神奇的共识世界!

货币之困

在深入比特币前,我们还是先讨论下纸币和传统电子货币(例如支付宝上的交易),笔者在这抛出几个问题供读者思考:

  1. 如何相信交易的货币是真实的,而不是伪造的?
  2. 如何确保一个人持有的纸币/数字货币,只能在一个交易中被使用,而不同时支付两笔交易呢(俗称「双花」问题)?
  3. 如何确保我持有的货币,不会被其他人冒认,被声明属于其他人呢?

我们分类进行讨论

传统纸币

对于最简单的纸币交易模型,Alice 将自己拥有的 100 元纸币面对面支付给 Bob:

  1. 通常会使用水印,凹印等印刷技术来进行防伪。
  2. 纸币交易的物理特性保证了同一张纸币只能转移给一个人。
  3. 物理意义的持有存储保证了纸币不会被他人冒认。

传统电子货币

对于传统的数字货币,存在一个中心化的支付系统用来管理交易,Alice 和 Bob 各自在中心交易系统上拥有 MA 和 MB 的存款储蓄,Alice 向 Bob 发起一笔交易,但实际动作是由中心系统 X 来完成的:

显而易见,可信的中心交易系统是最为重要的

  1. 货币的真实性由中心系统 X 来保证。
  2. 双花问题由中心系统 X 保证,Alice 发起多笔交易时由 X 校验其账号余额是否足够。
  3. 一般由 X 进行对交易的身份校验,确保交易是由 Alice 发起的(例如密码,人脸验证等)。

区块链货币

对于基于区块链的电子货币,其交易模型又发生了巨大的改变:

每一个区块链账户的拥有者都持有一个账本,其中记录了所有参与者的合法交易,当 Alice 向 Bob 发起一笔 100 元的转账时,Alice,Bob,Charlie 三个参与者的账户同时记录了这笔交易。在这样一个去中心化的交易模型中,没有一个必须的可信第三方参与,这就避免了中心交易所对交易的篡改,审计。人人都是参与者,人人都是监督者,每个人「确实」的拥有属于自己的财富,这也是区块链设计哲学的基本出发点之一。

那么如何回答之前提到的三个问题,如何保证每个人账户的一致性,如何确保交易的合理性,等等在中心化交易中可以轻松解决的问题,都需要重新设计来谋求真正的「人人可信」,带着这些疑问让我们进入下一章。

拜占庭问题

在分布式系统中有一个经典而有趣的问题:拜占庭将军攻城问题。简化条件来分析,有三个将军商量攻城,不能相互见面只能通过信使沟通,大于一半的将军选择攻城才会胜利,否则攻城就会失败。将军中可能出现叛徒,叛徒可以任意发出攻城或撤退的命令,甚至不发出命令。

例一:三个都是忠诚,其中一个发出撤退命令,另外两个发出攻击命令,最终三个将军都决定攻城,达成一致意见。

例二:两个忠诚,一个叛徒。叛徒对其中一个发出进攻命令,另一个发出撤退命令,自己选择撤退,那么只有一个忠诚发起进攻导致了失败,没有达成一致。

这就是存在消息篡改或伪造(也称为拜占庭节点)的分布式场景中,如何达成系统最终共识一致的问题,将其复杂化也就是上文所说的在分布式场景中,多个用户如何对一份账本达成一致的问题。经过数学推导,可以得知当叛徒大于等于三分之一时将永远无法达成共识,具体推导可以阅读:拜占庭问题阈值3f+1推导,这也是各类拜占庭算法实现的大前提。

关于分布式协议有众多的场景和算法,针对是否存在拜占庭节点我们可以大致分为两类:

经过对现实世界中复杂问题的抽象,我们可以精简出算法实现的目标,并针对具体的应用场景进行设计,接下来我们就针对比特币的基础 POW 共识算法进行分析,来让读者体会到中本聪的精妙设计。

前置知识

在谈及比特币之前,笔者假设读者已经拥有了一定的密码学和网络知识基础,比特币正是基于这些基础工具组合设计出来的,这里笔者不展开具体的技术细节,有需要的读者自行点击链接阅读或者 Google 搜索。

  1. 非对称加密

  2. 数字签名

  3. Hash函数

  4. P2P网络(例如迅雷,BT下载)

  5. 区块链的基本结构:每个人维护一个「账本」,「账本」结构由一个一个区块构成的有序链表,每一个区块都记录了一系列交易,并且,每个区块都指向前一个区块(通过前一个区块的Hash值),从而形成一个链条。

去中心化交易

我们先简单看一次比特币(去中心化)的交易过程:

  1. 小明想要转账 10000 元给小红

  2. 首先小明创建一对非对称密钥,并通过 P2P 网络将其公钥进行广播

  3. 小明使用自己的私钥对「小明付款给小红1万元」这句话签名,并通过P2P协议广播出去,任何人都可通过小明的公钥验证这句话确实是小明发出的,并且这个消息不会被篡改。

  4. 收到通知的参与节点在自己的账本中记录下这笔交易。此时有的请求是正常的交易,但有的交易确是双花的,两部分参与者可能记录了双花中的任意一笔,这就是导致了整个系统的账本不能达成一致,那么究竟该怎么决定账本的统一更新呢?这就交由比特币中最为核心的共识算法。

我们稍微回顾一下目前为止,比特币通过数字签名(例如 ESDSA)解决了

  1. 信息发送的身份追溯,也就是由谁发起的这笔交易;
  2. 信息的私密性;
  3. 不可伪造的签名;

那么剩下的就是如何让大家达成一致的共识问题,避免双花等账本不一致的问题。

共识算法 POW

工作量

POW 中文名为工作量证明算法,举个简单的例子:通过改变随机数 nonce,能够获得不同的 hash 值,首位为 0 的可能性时 1/16,所以大致得到一个首位为 0 的hash值需要算 16 次,前置 0 越多,越难算出来,比特币设置在 0 到 2 的 256 次方进行调整难度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
hash256("Hello1") = ffb7a43d629d363026b3309586233ab7ffc1054c4f56f43a92f0054870e7ddc9
hash256("Hello2") = e085bf19353eb3bd1021661a17cee97181b0b369d8e16c10ffb7b01287a77173
hash256("Hello3") = c5061965d37b8ed989529bf42eaf8a90c28fa00c3853c7eec586aa8b3922d404
hash256("Hello4") = 42c3104987afc18677179a4a1a984dbfc77e183b414bc6efb00c43b41b213537
hash256("Hello5") = 652dcd7b75d499bcdc61d0c4eda96012e3830557de01426da5b01e214b95cd7a
hash256("Hello6") = 4cc0fbe28abb820085f390d66880ece06297d74d13a6ddbbab3b664582a7a582
hash256("Hello7") = c3eef05b531b56e79ca38e5f46e6c04f21b0078212a1d8c3500aa38366d9786d
hash256("Hello8") = cf17d3f38036206cfce464cdcb44d9ccea3f005b7059cff1322c0dd8bf398830
hash256("Hello9") = 1f22981824c821d4e83246e71f207d0e49ad57755889874d43def42af693a077
hash256("Hello10") = 8a1e475d67cfbcea4bcf72d1eee65f15680515f65294c68b203725a9113fa6bf
hash256("Hello11") = 769987b3833f082e31476db0f645f60635fa774d2b92bf0bab00e0a539a2dede
hash256("Hello12") = c2acd1bb160b1d1e66d769a403e596b174ffab9a39aa7c44d1e670feaa67ab2d
hash256("Hello13") = dab8b9746f1c0bcf5750e0d878fc17940db446638a477070cf8dca8c3643618a
hash256("Hello14") = 51a575773fccbb5278929c08e788c1ce87e5f44ab356b8760776fd816357f6ff
hash256("Hello15") = 0442e1c38b810f5d3c022fc2820b1d7999149460b83dc680abdebc9c7bd65cae

挖矿与收益

有了这么一个如何表示工作量的前提,那么我们可以描述一个熟知的名词——「挖矿」。比特币设置一个 target 目标,要求 hash 值小于 target 为挖矿成功,矿工通过改变随机值来暴力遍历找到合适的 nonce(这个过程根据全网算力调整,平均为10分钟算出一个)。

挖出一个区块,可以奖励给矿工一定量的 btc(交易小费 + 基础奖励),这个奖励通过交易的方式 coinbase,交易输出地址是矿工自己的公钥地址,矿工将这笔交易写在第一个交易。奖励的定义如下:

  • 交易小费:根据交易数据大小按照一定公式进行计算。
  • 基础奖励:2016年12.5个,每四年减半,2140年挖完2100万个 btc。

目前矿工的收益主要还是来自基础奖励,当2140年挖完最后一块 btc 时,挖矿的收益将只有交易小费构成。

组装区块

矿工在挖矿时会将广播收到的「有效交易信息」进行组装,一般使用二叉哈希树的形式来快速验证交易是否存在。成功挖出区块后会将交易信息,目标值 target,nonce 随机数,前一个区块的 hash 等数据组成一个新的区块。

广播区块

挖出区块的矿工会通过 P2P 网络立刻进行广播,其他节点验证通过后,会放弃本轮自己的挖矿,并将收到的成功区块更新到自己的本地账本中,下图中其他节点都将绿色区块更新到自己的最新账本上。

分叉问题

显而易见,我们看到可能存在在同一轮挖矿竞赛中,出现两个甚至多个节点都算出 nonce 满足并进行广播,因为网络延迟等因素,不同部分的节点收到的区块可能不同,那么究竟是按照哪个区块为准呢?比特币节点总是以「最长」的链为正确的,下面举例进行说明:

  1. 在这一轮挖矿中基础区块时五角星,有两个节点同时算出来区块,结果分别是正三角和倒三角,广播给其他节点:

  2. 此时节点产生分叉,有的节点先收到正三角,有的先收到倒三角,但是节点将两个块都保存记录下来。

  3. 分区域计算:先收到正三角的节点以正三角为基准计算下一个区块,先收到倒三角的区块以倒三角为基准作为区块。此时有一个以正三角的节点算出了下一个区块棱形,并进行广播。

  4. 分支合并:菱形被广播出去,倒三角的节点比较两个分叉的工作量,正三角-棱形分支工作量 > 倒三角。替换主链为正三角-棱形分支,将倒三角认为为次链,除非倒三角后面的链接长度反超,才会被更新回去。但是因为挖矿计算的难度,当计算了6个区块后的深度,几乎是不可能被修改的,因为全网的总计算量不够来修改。

同时计算出同一个区块可能每天出现,但是两次分叉的情况因为算力问题可能几周才会出现一次。因此比特币就是通过 降低了区块产生的频率(交易确认的频率),来减少分叉数据不一致的可能性;通过工作量的难度,避免了交易被否认。从分布式 CAP 原理来看就是牺牲了一定的一致性 C,保证了可用性 A 和分区容错性 P,有兴趣的读者可以深入了解一下 CAP 相关的知识。

通过以上的一些列操作,这就保证了整个比特币系统的稳定统一性,避免了双花等交易共识不一致问题,只要符合拜占庭容错恶意节点不要超过 1/3,那么整个系统的账本总能保持一致安全的活性,支持系统内交易的正常进行。

衍生安全问题

关于区块链的安全攻击问题不是本文的重点,暂时列举几个常见的例子,后续的文章中会进行更加详细的阐述:

  1. 密钥泄漏:私钥被窃取。
  2. 51%攻击:掌握大量算力,创建一个高度更高的链来覆盖原来的链
  3. 中心化交易中心受到攻击。
  4. ……

回顾总结

通过前文对比特币核心思想和算法的分析解释,我们可以看出中本聪对未来金融,乃至世界的前瞻看法,「人人可信,去中心化,共识机制,不可篡改,分布式……」等自由的核心理念透出了其中的设计哲学。基于区块链,每个人都可以切实的拥有属于自己应该拥有的,而不必须交由第三方进行保管,往后的以太坊, Web3.0 等等新概念都是基于这些基础的设计思想诞生的。

笔者常常认为一个优秀的架构更像是一件艺术品,当阅读并理解比特币后,更加惊叹其中的瑰丽思想与巧妙设计,区块链的世界已经为我们打开!