区块链超入门(第2版)
上QQ阅读APP看书,第一时间看更新

2.比特币是如何转账的——比特币区块链的五个技术性细节

“互联网上的商务交易,几乎都需要借助金融机构作为可信赖的第三方来处理电子支付。”比特币白皮书的第一句话描述了这一现实,中本聪试图改变它。中本聪是如何把可信第三方从比特币的交易中去掉呢?

用两个人之间的转账交易示例,我们来看看比特币系统是如何实现交易的去中介与去中心化的。假设我是甲,要把自己钱包地址中的8枚比特币转给你(乙),即转到你的钱包地址中去。详细讨论这一转账交易过程,我们可以看到比特币区块链是如何工作的,其中涉及的五个技术性细节为(见图1-7):

·分布式账本和去中心网络。

·未花费的交易输出(unspent transaction output,UTXO)。

·比特币区块链的数据结构。

·工作量证明共识机制。

·比特币挖矿机制与代币生成机制。

图1-7 一笔比特币转账交易的过程

在沿着比特币系统所开创的路线开发各类基础公链时,开发者从各个角度调整与改进以上五个技术性细节,形成新的区块链系统。如果你希望先了解区块链全景,可以跳过这一节,稍后再回来看这些重要的技术性细节。

技术性细节之一:分布式账本和去中心网络

所有的区块链系统都包括“分布式账本”和“去中心网络”这一对必备元素。

比特币网络没有一个中心服务器,它是由众多全节点和轻节点组成的,这些节点形成一个去中心网络。其中,全节点包含所有比特币区块链的区块数据,轻节点仅包括与自己相关的区块数据。比特币网络是完全开放的,任何服务器都可以接入或者下载全部区块数据成为全节点。

所有用户持有比特币的相关记录都存放在一个分布式账本中,它可被认为同时存储在所有的全节点中。这个账本是一个不断增长的由数据块组成的链条,数据块连接而成的链条就是狭义的“区块链”。

基于分布式账本与去中心网络,比特币系统实现了去中心化的价值表示和价值转移,它与中心化在线支付系统有很大的不同。

用两个人之间的转账来对比看一下。假设你我二人要通过中心化在线支付系统支付宝进行转账,转账过程是:我们都在支付宝开设有账户(account),账户上有多少钱是支付宝账本上记录的数字,当我转账100元给你,支付宝在我的账户记录上减掉100元,在你的账户记录上增加100元,形成新的账本状态。到此,转账交易结束。

如图1-8所示,中心化在线支付系统维护一个中心化的账本。用户在账本上开设账户,通过账户名、密码与之交互。

图1-8 中心化在线支付系统vs.比特币系统

对比而言,比特币系统使用的是一个分布式账本,用户在其中也开设“账户”,但严格地说是地址(address)。每个人都可以在比特币区块链上建立类似“账户”的东西,我们获得一对公钥与私钥,地址是由公钥的哈希值转换而来的,我们通过私钥与地址进行交互。

我们用区块链钱包管理地址与私钥,钱包中存储的是私钥。两个人在相互转账比特币时,可以通过各自的钱包软件直接进行,我们用私钥签名确认转账。

在这里,比特币的去中心化体现在:不再有一个中心化机构来集中管理账本,账本存放在由众多节点组成的去中心网络中;不再有一个中心化机构来帮我们管理账户、处理交易,每个人管理自己的地址与私钥;交易由分布式账本来记录,账本的变更由众多节点按共识机制来共同确认。

有人会追问,我们地址中的比特币是记录在账本中的,那看起来还是有一个“中心”存储我们的资产。请注意,这个账本是分布式地存储在去中心网络里的,无人可以独自控制网络,因而从这个层面看,这个账本可以看成是去中心化的。

因此对比而言,中心化在线支付系统通常是由一个中心化的服务器来管理集中式账本,中心化服务器的控制者掌控着账本。而比特币系统,它背后是一个去中心网络,所有网络节点按所谓工作量证明共识机制共同维护一个分布式账本,无人可以独自掌控账本(见图1-9)。

图1-9 分布式账本与去中心网络

技术性细节之二:未花费的交易输出(UTXO) 更多的讨论详见本节后“冷知识”专栏的《比特币的UTXO》。

接下来的讨论比特币系统的一个关键技术性细节:UTXO。

在比特币系统中其实并不存在所谓的账户,而只有“地址”。只要你愿意,你可以在比特币区块链上设无限多个钱包地址,每个地址都有对应的私钥。你拥有的比特币总量是你所有钱包地址中的比特币之和。比特币系统并不会帮你把这些地址汇总起来形成你的账户。

从我(甲)到你(乙)的一笔比特币转账,是从我的一个钱包地址转到你的一个钱包地址上去。严格地说,这个过程是把我的地址的一个UTXO用一个交易输出给你,成为你的地址的一个UTXO。

我们来看一个两个人进行转账交易的过程,以深入理解UTXO:

假设我有8枚比特币。这实际指的是,之前有一个交易把这些比特币转入我的地址,而这个交易的输出(即8枚比特币)在我的地址中、未被花费出去,因此我有这8枚比特币。

现在,我要发起一个新的转账交易,将这8枚比特币转账给你。新转账交易的输入,是让我拥有这些比特币上一个交易的输出,我把这一新转账交易的输出地址设为你的钱包地址,并用自己的私钥对新转账交易进行签名。

这样,我就发起了一个转账交易。

等矿工将这一交易打包进新的区块,转账交易完成,这8枚比特币就属于你了。类似地,你拥有的比特币是我向你转账的这个交易中的UTXO。

对一个转账交易进行签名确认所涉及的比特币的公钥和私钥的非对称加密机制,我们之后再讨论。你可以先这样类比看:钱包地址相当于房间号和门锁,私钥则相当于钥匙,一把钥匙可以打开对应房间的锁。我发起一个转账交易,相当于把自己房间的财物放入另一房间,有第二个房间钥匙的人就拥有了这个财物的所有权。

总的来说,以上两个人的转账交易过程是:我用私钥(从一个输出是我的地址的交易中)取出比特币,并用私钥对从我的地址转到你的地址的新交易进行签名。一旦交易完成,这些比特币就转到你的钱包地址中去了。你的钱包中新交易的UTXO(即现在属于你的比特币),只有你的私钥才可以动用它。

从以上讨论我们可以看到,其实在比特币系统中并不存在比特币,只有UTXO,每一笔比特币都源自上一个交易,是上一个交易的未花费的交易输出。

我们可以沿着这样的交易链条一直向上追溯。在源头,每一枚比特币都是通过挖矿被创造出来的,在每一笔比特币的源头是一种特殊的交易——比特币矿工因挖矿生成区块而获得奖励的币基交易(coinbase transaction)。假设我作为比特币矿工挖矿成功赢得了25枚比特币,那么这个特殊交易是:它的输入是0,输出是25枚比特币进到矿工的钱包地址中。25枚比特币是这个币基交易的UTXO。

到这里我们可以看出,UTXO和我们熟悉的银行账户有着很大的不同。为什么要采用这样的设计?对比银行账户和比特币的UTXO,我们可以看到UTXO的两个优点。

第一,UTXO设计易于确认比特币的所有权。

如果采用传统的账户设计,当我要转账8枚比特币时,为了避免造假,我们就需要逐一向上追溯,确认之前的每一笔交易,从而证明我的确拥有8枚比特币。

采用现在的UTXO设计,要确认我拥有8枚比特币,只要确认上一个交易我的确获得了它们即可。在比特币区块链中,一个区块经过6次确认后,其中的交易可被认为是真实无误的。因此,通常只要上一个交易是真实的,我就的确拥有这些比特币。

第二,UTXO设计与区块链账本是完全融为一体的。

银行账本与区块链账本都是一种所有权管理系统,它的首要任务有两个:一是记录某一时刻谁拥有什么,二是通过转账交易把钱从一个人转给另一个人。银行账本的记录方式是每一刻形成一个快照,把重心放在第一个任务上;UTXO的记录方式是把重心放在第二个任务上,然后反过来完成第一个任务,由转账交易来记录所有的所有权转移过程。转账交易累积成的区块链账本可在某一刻来确认谁拥有什么,这一刻的记录也就是区块链的状态。

现在,几乎所有的区块链都采用这一设计,每一个新区块和它之前的所有区块一起形成一个新的状态,如此重复地持续下去。在经过一定区块数量的确认之后,之前记录的所有状态就不可篡改了。

以太坊是对比特币区块链的改进,在以太坊白皮书中,以太坊创始人维塔利克分析了比特币系统的设计,他称比特币账本可以被认为是一个状态转换系统 微观地看,区块链中的每一个交易都是一个状态转换函数。以太坊白皮书就用“以太坊状态转换函数”(ethereum statetransition function)来讨论在区块链中一个交易的进行过程。(state transition system)。以太坊也采用这种状态转换系统的设计,同时又对其进行了改进,主要是引入了智能合约,让对状态转换进行编程更方便。

技术性细节之三:比特币区块链的数据结构

让我们回到两个人的转账交易过程中,去理解比特币区块链的数据结构。

我发起一笔交易。我向整个区块链网络广播:我向你的地址中转入了一笔比特币。

只有当这笔交易被打包进最新的比特币区块中时,这笔交易才完成。当在一笔交易所在的区块之后又增加5个区块,即包括它自己在内一共经过6次确认时,这笔交易可认为被完全确认。按比特币每个区块产生的间隔时间为10分钟估算,一笔交易最终被确认要经过约1小时。

如上过程包括的步骤是:交易被打包进候选区块,每个节点可以按规则生成不同的候选区块;某个节点挖矿成功,候选区块被成功地加到区块链的尾部,成为新的正式区块。

那么,把一笔交易打包进区块是什么意思?要理解这一点,我们要了解区块链最基础的数据结构,这也是区块链上所记录数据不可篡改的基础。

以下讨论可能略显枯燥,但又是认识比特币与区块链的最基础的知识,我尽量以通俗的语言来为你解读。

区块链之所以被称为blockchain,是因为它的区块(block)以链(chain)的形式存储。从第一个区块(即所谓的创世区块)开始,新增的区块不断被连到上一个区块的后面,形成一个链条。

每个区块由两部分组成:区块头部和区块数据。其中,区块头部中有一个哈希指针指向上一个区块,这个哈希指针包含前一个数据块的哈希值。哈希值可以被看成数据块的指纹,即在后一个区块的头部中均存储有上一个区块数据的指纹。那么,如果上一个区块中的数据被篡改了,那么数据和指纹就对不上号,篡改行为就被发现了。要修改一个区块中的数据,其后的每个区块都必须相应地进行修改。因此,时间越久,一个区块就越难被篡改。

一个区块中的数据是被打包进这个区块的一系列交易,这些交易按照既定的规则被打包形成特定的二叉树数据结构——梅克尔树(Merkle trees)。按目前比特币区块的大小,一个区块中能容纳的交易数量在2000个左右,比如在第526 957个区块中容纳了1804个交易。

比特币区块链的数据结构中包括两种哈希指针,它们均是不可篡改特性的数据结构的基础:一个是形成“区块+链”的链状数据结构,另一个是哈希指针形成的梅克尔树(见图1-10)。链状数据结构使得对某一区块内数据的修改很容易被发现;梅克尔树的结构起类似作用,使得对二叉树型结构的任何交易数据的修改很容易被发现。

图1-10 比特币区块链的链状数据结构与梅克尔树

技术性细节之四:工作量证明共识机制

比特币的去中心网络采用的是工作量证明共识机制。去中心网络之所以需要共识机制,是因为这是一个非基于信任的网络,任何人无须许可都可以接入这个网络。这些节点分散在网络条件差异非常大的全球互联网之中。在完全无中心的情况下,这些节点也要保持各自存储的账本数据能在共同认可的情况下添加新数据并同步一致,共识机制即为这些节点达成一致的机制。

关于分布式网络的共识机制,有著名的“Fisher-Lynch-Paterson不可能结果”,即在一定条件下达成共识在技术上是不可能的。但是,比特币的工作量证明共识机制又在实践中被验证是有效的,这是因为它采用了一个实用主义的解决方案:技术与经济的组合。

比特币的工作量证明的特点是,它巧妙地融合了技术和经济因素,不是纯粹地试图通过技术本身来达到这一点,而是纳入了经济激励。这是比特币作为一个电子现金系统的优势,它为节点提供所谓的挖矿奖励。按《比特币:技术驱动金融》一书的分析,比特币的共识机制有两个与过去不同的特点,我们在此略做引申讨论:

第一,它引入了奖励机制。在这样一个加密数字货币应用中引入了经济激励,维护网络的节点就可以得到有价值的比特币作为奖励。

为什么比特币网络中的节点愿意打包交易、维护账本?它们并非出于“善意”,而是因为,它们能因这些挖矿行为获得比特币形式的经济激励。这是一个自行发行代币的电子现金系统的独特优势,如果所开发的是其他没有自行发行代币的IT系统,我们就无法方便地引入矿工挖矿奖励这样的经济激励机制。

激励挖矿节点参与挖矿的,除了与新区块相关的奖励之外,挖矿节点还可以得到区块中包含的所有交易付出的交易费。到目前为止,这个数值还较小,大概为新区块奖励的1%。

第二,它包含了随机性的概念。比特币系统形成的共识不是完全可靠的,但是在等待了6个区块约1个小时之后,出问题的概率呈指数下降。在确认6个区块之后,一个交易发生双花情况的概率可被认为是零。从纯理论上看,完美的共识不可能达成。但从实用的角度看,这个共识是高度可信的。

技术性细节之五:比特币挖矿机制——代币生成机制

节点计算机在挖矿时要做两个任务。第一个任务是把比特币网络中未被确认的交易按梅克尔树组合成候选区块,未被纳入的交易往下顺延。在创建候选区块时,除了普通的交易之外,矿工还增加了一个特殊的交易——币基交易。如果它的候选区块成为正式区块即挖矿成功,币基交易会凭空转出新区块奖励比特币到矿工的钱包地址中,从而实质上将这些比特币凭空发行出来。这个特殊交易也被叫作“创币交易”,新的比特币就是在这一交易中被创造出来的。

第二个任务是真正的算力竞争,即进行加密哈希计算,解决一个计算难题。在众多争夺记账权的节点中,谁最先完成这个计算,谁打包的区块就被加到区块链的最后面,成为最新的正式区块并获得奖励。最初,成功挖出一个区块,矿工可以获得50个比特币的奖励,按规则,这个挖矿奖励约每四年减半一次,奖励依次变成每个区块25个、12.5个,以此类推。

我们接着往深处走以进一步了解比特币的工作量证明共识机制与它的挖矿机制。

先向内看,比特币矿工挖矿是在做什么?

在候选区块的头部有一个32位的随机数区域,矿工需要反复调整随机数并计算,目标是让这个区块的哈希值小于一个所谓的“目标值”。如果试过所有32位随机数的可能性后,计算仍未成功,那么就要反复改变币基的一个随机数,进行计算,以让这个区块的哈希值小于目标值。

这里所需要进行的加密哈希函数计算(对比特币来说是SHA-256),除了反复计算别无他法,也就是各个节点完全凭借计算能力进行竞争。这种所谓的挖矿竞争的计算量非常大,比如在2015年年底,在大约2的68次方(这个数字比全球总人口的平方还要大)个随机数中,只有一个可以成功。

有意思的是,这种挖矿计算是非对称性的,你挖矿需要经过2的68次方个哈希计算,而我要验证你的确找到了有效的随机数,只需要一次就可以。这种非对称性是区块链在技术上的重要特性:矿工需要消耗大量算力,检验者与使用者却不需要。

第一个完成这个计算难题的节点所打包的区块会成为正式区块。节点向全网广播告知自己已经完成计算,由其他节点确认后(即有别的挖矿节点在这个区块之后进行下一个区块的计算竞争,生成更新的区块)。在等待6个区块确认后,该挖矿节点就可以正式获得奖励。

我们再向外看,在加入挖矿的计算机的算力不断增加的情况下,这个挖矿机制是如何保持稳定的?

比特币挖矿的芯片已经经过几轮演变,计算能力越来越强:从CPU演变到GPU(显卡),再到现场可编程门阵列(FPGA),再到现在的专用集成电路技术(ASIC)。现在矿机中的计算芯片是只能进行比特币挖矿所需的哈希计算的专用芯片。

随着矿机的升级迭代和数量增多,接入比特币区块链网络、参与挖矿竞争的算力越来越大。如图1-11所示,在过去10年间比特币算力持续上升,2018年后增长尤为显著。

图1-11 比特币全网算力

资料来源:https://bitinfocharts.com/comparison/bitcoin-hashrate.html,2021年3月。

为了应对这种可预见的算力增长,比特币系统有一个对应的机制设计:随着算力的增加,定期调整目标值的难度,使得挖出一个区块的时间始终在10分钟左右。

这就形成了一种动态的平衡,维持区块链网络经济激励的有效性的同时,也维持了区块的时间间隔和系统的稳定性。这个决定难度的公式非常简单明了,每挖出2016个区块,也就是经过约两个星期,挖矿难度会进行一次调整,该公式是:

下一个难度=上一个难度×2016×10分钟/产生2016个区块所需的时间

如果算力突然大幅度增加,产生上一组2016个区块所需的时间变短,那么难度就会上升。在某些特殊情况下,如果产生上一组2016个区块所需的时间变长,那么难度也会下降,但并不多见。

总的来说,比特币节点计算机所做的是,它以算力参与分布式账本的确认,并以这种方式参与这一去中心网络的运维。比特币区块链是由众多节点组成的去中心网络,而这些计算机节点加入这个网络,计算分布式账本、运维网络,是因为中本聪在设计系统时巧妙地加入了经济激励。算力竞争加经济激励就是比特币区块链的工作量证明共识机制。

比特币的经济系统是以“竞争—记账—奖励”循环为核心的(见图1-12),其中竞争指的正是节点进行的算力竞争。在比特币系统这样一个去中心网络中,节点参与记账是出于获得经济激励的自利动机,奖励是通过竞争来获得的。

图1-12 比特币的“竞争—记账—奖励”循环

通过以上对比特币区块链的五个技术性细节的讨论,我们再一次看到,比特币系统在发行和交易层面都实现了完全的去中心化:

·一个转账交易的确认,即被写入分布式账本记录下来,是由去中心网络中互不信任的节点出于自己的利益、以算力进行竞争而确认下来的。账本的确认、转账交易的确认是去中心化的,是由众多节点按共识机制算法完成的。

·在竞争挖矿的过程中,比特币系统凭空发行出比特币。比特币的发行是去中心化的,同样是由众多节点按既定算法完成的。

总的来说,比特币是“区块链1.0”的典范,它开创性地完成了“价值表示”和“价值转移”的概念验证(见图1-13)。比特币系统是非常精妙的设计,它无须任何人的居中协调或领导就能让所有参与者协同一致、长期发展。

图1-13 比特币作为区块链1.0的典型代表,完成了“价值表示”和“价值转移”的概念验证

不过,比特币区块链是专为去中心化的电子现金设计的,而要在各个领域中广泛应用,我们需要有更通用、性能更好的区块链系统。在比特币系统之后,出现了常被认为是“区块链2.0”代表的以太坊。现在,更多项目在竞争成为“区块链3.0”。我们在之后两章会分别讨论它们。

在讨论之前,我们认为还应该接着围绕比特币系统做更多的探讨:区块链给互联网和数字世界带来了哪些巨变?从数字资产角度看,比特币为什么有价值?

「冷知识」比特币的UTXO

每一个比特币其实都是UTXO,它是比特币的最为核心的概念之一。 参考资料:《区块链:技术驱动金融》中相应的讨论,以及文章《比特币和以太坊的记账方式——UTXO和账户余额》(黄世亮/文)。

比特币就是UXTO

比特币的挖矿节点获得新区块的挖矿奖励,比如12.5枚比特币,这时它的钱包地址得到的就是一个UTXO,即这个新区块的币基交易(也称“创币交易”)的输出。币基交易是一种特殊的交易,它没有输入,只有输出。

当甲把一笔比特币转给乙时,这个过程就是把甲的钱包地址中之前的一个UTXO,用私钥进行签名,然后发送到乙的钱包地址。这是一个新的交易,乙得到的是这个新交易的UTXO。

详看从甲转账给乙的过程

假设甲(Alice)向乙(Bob)转账,转账过程可以分成三个阶段(见图1-14)。

图1-14 Alice向Bob发起比特币转账

(1)假设Alice之前通过挖矿获得了12.5枚比特币,在她的钱包地址中,这些比特币是某个币基交易的UTXO。

(2)Alice发起一个交易,输入是自己的上一个交易,输出是Bob的钱包地址,数量是12.5枚比特币, 这里简化了交易过程,只讨论了将上一个交易的输出全部转账的情况。如果试图转出上一个交易输出的一部分比特币,则要进行略复杂的处理。按照比特币系统的设计,比特币交易要遵循一个原则:每一次交易的输入值都必须全部花掉,不能只花掉部分。假设我的钱包地址中有25枚比特币,那我发起的交易就不是转给你8枚比特币,然后自己的钱包地址中还剩17枚比特币。这时,我发起的交易是:从我的钱包地址中转8个比特币给你,同时转17枚比特币给我的同一地址。Alice用自己的私钥对交易进行签名。

(3)当交易被确认后,Alice的UTXO就变成了0,而Bob的钱包地址中就多了一个UTXO,数量是12.5。

存在Bob的钱包地址中的这些比特币,只有用Bob的私钥签名才可以动用。Bob要将这些比特币转账给其他人,则重复上述过程。

另外,初次接触比特币的人会问:我的比特币是什么样的?它们存在哪里?

如果你头脑中参照的是在物理世界中的金币,那么这里很不一样:你的比特币并不是存在家中或金库中,并不存在一个数字文件表示“你的比特币”。

如果你头脑中参照的是银行存款,那么你可以认为,你的比特币“存在”于一个账本上。在数字世界中,价值是账本中的“记录”。不同的是,比特币账本是由众多网络节点维护的分布式账本,而不是像银行账本那样是一家中心化机构维护的账本。任何人都可以接入比特币网络,把这个账本下载下来,但只有用你的私钥才能动用你钱包地址中的比特币。

为什么采用UTXO的形式

UTXO与我们熟悉的“账户”概念差别很大。我们日常接触最多的是账户,比如我在银行开设一个账户,账户里的余额就是我的钱。在比特币网络中没有账户的概念,你可以有多个钱包地址,每个钱包地址中都有着多个UTXO,你的钱是所有这些地址中的UTXO加起来的总和。

中本聪发明比特币的目标是创建一种点对点电子现金,UTXO的设计可以看成借鉴了现金的思路:我们可以在这个口袋、那个口袋装些现金,在这个抽屉、那个保险柜放些现金。就现金而言,它没有一个账户,你放在各处的现金加起来是你所有的钱。

采用UTXO设计有一个技术上特别的理由——这种数据结构可以让双重花费更容易验证。对比一下:

·如果采用账户和账户余额设计,Alice要转账给Bob,为了确保Alice的确有钱,我们需要核查她之前所有的比特币交易。随着时间的推移,比特币的交易越来越多,这个验证的难度会持续上升。

·采用UTXO设计,我们只要沿着每个交易的输入逐级向上核查,直到查到这笔比特币的创币交易即可。随着时间的推移,这个核查也会变难,但变难的速度要远低于采用账户和账户余额的设计。

采用UTXO设计使得比特币系统作为一种电子现金系统有着非常大的可扩展性。当然,我们很快会看到,通常被认为是区块链2.0的以太坊没有继续采用UTXO设计,而是考虑到其他因素,在UTXO之上覆盖了一层账户余额设计,代价正是中本聪可能已经考虑到的复杂性。

[1] 更多的讨论详见本节后“冷知识”专栏的《比特币的UTXO》。

[2] 微观地看,区块链中的每一个交易都是一个状态转换函数。以太坊白皮书就用“以太坊状态转换函数”(ethereum statetransition function)来讨论在区块链中一个交易的进行过程。

[3] 参考资料:《区块链:技术驱动金融》中相应的讨论,以及文章《比特币和以太坊的记账方式——UTXO和账户余额》(黄世亮/文)。

[4] 这里简化了交易过程,只讨论了将上一个交易的输出全部转账的情况。如果试图转出上一个交易输出的一部分比特币,则要进行略复杂的处理。按照比特币系统的设计,比特币交易要遵循一个原则:每一次交易的输入值都必须全部花掉,不能只花掉部分。假设我的钱包地址中有25枚比特币,那我发起的交易就不是转给你8枚比特币,然后自己的钱包地址中还剩17枚比特币。这时,我发起的交易是:从我的钱包地址中转8个比特币给你,同时转17枚比特币给我的同一地址。