比特币系统综述
2020-08-19刘海房吴雨芯
刘海房,吴雨芯
(广东白云学院大数据与计算机学院,广州510000)
0 引言
2008 年10 月30 日,一个化名中本聪的人在一个隐秘的密码学论坛上发布了一篇题目为《比特币:一种点对点电子现金系统》的报告[1],报告阐述了他对电子货币的构想。2009 年1 月3 日,中本聪在位于芬兰赫尔辛基一个小型服务器上挖出了第一批比特币50 个,从此比特币正式诞生。2010 年5 月22 日,佛罗里达程序员Laszlo Hanyecz 用1 万比特币向比特币论坛用户购买了两个披萨,比特币首次实现了由名义货币向实物货币的转变[2]。
比特币是一个点对点的电子现金系统,任何人可以随时加入比特币系统,成为比特币网络中的一个节点。比特币系统中可以通过匿名地址互相转账交易,某个时间段产生的交易会被整理成一个区块,将新生成的区块链接到上一个区块后面,从而形成了区块链,区块链的概念正是由此而来。比特币系统里的区块链也称账本,账本结构如图1 所示。比特币账本记录了比特币自诞生以来所有的交易记录,分布在网络中各个节点上。
图1 比特币账本结构
根据BLOCKCHAIN.COM[3]网站上显示的数据,截止 2020 年 5 月 5 日 12 点 20 分,比特币系统共有628995 个区块,已经发行1836.24375 万枚比特币,单价8920.2 美元,总价值约为1637.97 亿美元。
1 比特币系统体系结构
比特币系统大致可划分为五个层次,分别是数据层、网络层、共识层、合约层和应用层,如图2 所示。数据层采用链式数据结构对区块、交易数据进行组织管理,采用文件和LevelDB 对数据进行存储;网络层采用P2P 协议完成节点间交易、区块数据的传输;共识层采用PoW 算法和奖励机制,支持拜占庭容错,解决分布式系统一致性问题;合约层是一段比特币脚本代码,是智能合约的雏形,通过脚本实现对交易的控制;应用层提供用户可编程接口,实现了比特币交易[4]。
图2 比特币系统体系结构
2 数据层
2.1 数据存储
比特币系统主要采用文件存储,同时采用LevelDB[5]数据库存储索引数据,提高数据检索效率。比特币核心[6](Bitcoin Core)是一个完整的比特币客户端,它组成了整个比特币网络的支架,可直接从官网[7]下载安装或通过源码编译安装[8],安装完在本地可查看到比特币的存储目录和文件,如表1 所示[9]。
表1 Bitcoin Core 目录及文件说明
2.2 数据结构
比特币系统采用链式结构对区块数据进行组织管理,将一个个区块链接起来。比特币区块数据大小不超过1M,包括区块头和区块体两部分,区块体保存交易信息,区块头保存区块基本信息,固定80 个字节,包括 版本(Version)、时 间 戳(Timestamp)、随 机 数(Nonce)、难度目标(Bits)、前一区块哈希值(PrevBlock⁃Hash)、默克尔根(MerkleRoot),区块数据结构如图 3 所示,区块头各个字段含义及占用字节数如表2 所示。区块链系统要求每个区块必须加盖时间戳,由于比特币系统中没有中心节点,没有统一的标准时间,每个节点时间戳可能不一样,比特币系统规定最新区块时间戳要大于前面11 个区块的平均时间且不超过当前网络时间两小时,所以有可能存在后一个区块时间戳比前一个区块时间戳小的情况[10]。随机数占32 位,取值范围是[0,232),随机数和难度目标是共识层挖矿的重要参数。每个区块保存了前一区块头哈希值,从而将当前区块链接到比特币系统的区块链中。比特币系统使用了最简单的二叉Merkle 树[11],一个区块中第一笔交易是挖矿所得的Coinbase 交易,对剩下的交易根据手续费由高到低进行排序,计算出每笔交易的哈希值作为Merkle 树的叶子结点,两个叶子结点的值连在一起后再进行哈希得到父结点的值,再依次将两个父结点的值连在一起进行哈希,如此反复执行两两哈希,直到生成根哈希值,即默克尔根[12]。
图3 比特币区块数据结构
表2 区块头字段说明
3 网络层
比特币网络层基于P2P 协议设计,基于TCP 协议实现,网络中没有中心节点,任意两个节点都是对等的,每个节点存储了相同的数据具有相同的功能。P2P网络具有高容错、耐攻击等优点,节点可自由加入或者退出网络,部分节点受到攻击或者宕机时不会影响整个比特币网络。所以比特币网络简单,鲁棒性强,但并不高效[13]。
在比特币网络中,任意两个节点之间可直接进行数据传输,每个节点时刻监听网络中广播的数据,当接收到邻居节点发来的新区块时,首先验证收到的区块是否有效,无效则直接丢弃,有效则链接到本地区块链末尾,同时转发该区块。当接收到邻居节点发来的新交易时,首先验证收到的交易是否有效,无效则直接丢弃,有效交易加入到待确认交易集合,同时转发该交易。在该节点获得记账权时,即获得创建区块的权利,将待确认交易打包到新创建的区块中,广播发布新区块[14]。
4 共识层
4.1 比特币共识机制和挖矿
在比特币网络中,时时刻刻都可能发生着交易,每个节点都是平等的,都可以收到比特币系统中发生的交易信息,所以需要一套共识机制来决定由哪个节点记账。比特币网络中采用的共识机制是PoW(Proof of Work),即要求完成一定计算工作量并提供证明的节点才可以获得记账权,生成并发布区块。每个节点利用自身计算资源不断进行哈希运算以竞争记账权的过程称为挖矿,参与挖矿的人称为矿工。第一个被挖出来的区块称为创世区块,从任意一个区块开始溯源,最终都能追溯到创世区块。创世区块是由中本聪在2019年1 月3 日挖出,中本聪在比特币创世块的Coinbase交易中引用了一句话“The Times 03/Jan/2009 Chancel⁃lor on brink of second bailout for bank”,是当天泰晤士报的头版文章标题。中本聪的引用,说明了创世区块产生的时间,也嘲讽了旧银行系统面对金融危机时脆弱的表现[15]。挖矿过程中需要不断调整随机数进行哈希运算,直到计算出来的值刚好小于等于目标哈希值(target),具体挖矿过程如下:
步骤一接收保存所有未确认的有效交易,并额外新建一个Coinbase 交易,作为挖矿后的区块奖励。将这些交易经过两两哈希运算得到区块头的默克尔根字段。
步骤二将区块头中的随机数设置为0,并将六个字段按照版本号、前一区块哈希值、默克尔根、时间戳、难度目标、随机数的顺序依次连接在一起,进行两次SHA-256[16]哈希运算,将计算结果转码为小端排序的32 字节数值。其中时间戳、默克尔根、随机数是可变的,版本号、前一区块哈希值、难度目标在挖矿过程中保持不变。
步骤三将步骤二得出的数值和难度目标值进行比较,如果小于等于目标哈希值,则挖矿成功,获得记账权,将该区块加入本地区块链并全网广播。如果大于目标哈希值,则随机数加1,根据当前接收到的有效交易重新计算默克尔根,重复执行步骤二,继续挖矿。
步骤四全网节点同时参与挖矿,挖矿过程中,当接收到新区块时,验证新区块是否有效,若有效则加入本地区块链,并在新区块的基础上再挖矿。
其中目标哈希值是根据难度目标(Bits)计算出来的,计算公式如下:
target 是目标哈希值,coefficient 是难度系数,是难度目标Bits 中的后3 个字节,exponent 是指数,是难度目标Bits 的第1 个字节,决定了目标哈希值中实际有效的字节数。SHA-256 共有2256个哈希输出值,所以每个哈希值出现的概率是1/2256,所以进行一次哈希运算,值落在0 至target 之间的概率是target/2256,即进行一次挖矿,挖矿成功的概率是target/2256。
4.2 挖矿难度
挖矿难度是对挖矿困难程度的度量,值越大表示挖矿越难,挖矿难度具体计算公式如下:
difficulty 是挖矿难度,difficulty_1_target 表示比特币网络最初的目标哈希值,长度为256 位,前32 位为0,后面全部为1,值为0x00000000FFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,接近2224,current_target 是当前块的目标哈希值。由此可以看出,Bits 值越小,目标哈希值也越小,挖矿难度越大,当current_target 值等于其最小值1 时,挖矿难度达到最大值 difficulty_1_target,当 current_target 等于difficulty_1_target 时,挖矿难度达到最小值1[13]。
算力是计算能力的简称,做一次哈希运算的算力是1,算力单位及相互之间关系为:1EH/s=103PH/s=106TH/s=109GH/s=1012MH/s=1015KH/s=1018H/s,全 网 算力是比特币网络中参与竞争挖矿的所有机器算力总和,根据 BTC.COM[17]显示,当前(2020 年 5 月 5 日)比特币全网算力为120.17EH/s,挖矿难度16.10 T。比特币网络规定每10 分钟(600 秒)左右生成一个新区块。假设某台设备算力为hash_count H/s,即一秒钟可执行哈希运算次数为hash_count,10 分钟可执行哈希运算hash_count*600 次,则挖矿成功的概率 p 等于hash_count*600*(target/2256),将 式(2)和 difficulty_1_target 代入可得挖矿成功的概率为:
若要保证在10 分钟内100%能挖矿成功,总共需要执行的哈希运算次数是2256/target,即最低算力hash_count 为 2256/target/600H/s,将 式 2 和 difficulty_1_target 代入可得最低算力为:
随着全网参与挖矿的设备计算能力不断提升或降低,区块生成时间也会随之减少或增加,为了维持10分钟左右出一个区块,全网每新增2016 个区块(新增2016 个区块大概需要14 天左右)就要调整一次挖矿难度。新挖矿难度将根据前一周期全网算力决定,难度调整公式如下:
其中expected_time 等于20160 分钟,是产生前一周期2016 个区块的期望时间,actual_time 是产生前一周期2016 个区块的实际时间。
以 2020 年 5 月 5 号 12 点 11 分生成的 628994 号区块为例,Bits 值 0x17117a39,则 coefficient 系数是0x117a39,exponent 指数是0x17,表示目标哈希值中实际有效的字节数是23 个,难度系数是这23 个字节中的前3 个字节,剩下低位20 个字节用0 补齐。此外,为了凑够32 字节的哈希值,还需要在高位用0 补9 个字节,得出目标哈希值为0x000000000000000000117a 390000000000000000000000000000000000000000[12],再根 据 式(2)计 算 出 挖 矿 难 度(difficulty)为16105053229139.447,在该挖矿难度下,若想挖矿成功,根据式(4)可以计算出要求的最低算力是115.284461532488530000EH/s。若使用一台算力大概是 4.8GH/s 的个人电脑(Intel Core i5 双核 2.4 GHz)进行挖矿,根据式(3)可以计算出10 分钟内挖到矿的概率是1/(8.646334614936639*1033),这个概率是极低的,所以现在用个人电脑几乎是不可能挖到矿了。
4.3 矿机、矿场和矿池
运行比特币客户端的机器就是一个节点,其中拥有完整区块链账本的节点称为全节点,全节点可以验证和广播交易及区块,对于整个比特币网络来说非常重要,目前全球大约有 9672 个全节点,美国占19.27%,中国占2.07%[18]。不拥有完整区块链账本的节点称为轻节点,轻节点一般只保存了区块头和默克尔树路径数据,可以进行交易和验证交易是否完成。挖矿节点是具有挖矿功能的全节点,也称为记账节点。矿机是专门用来挖矿的专业设备,一般只执行单一的计算程序,耗电量大,发热量大,算力比普通电脑设备强很多,一台蚂蚁矿机S19 Pro 算力高达110TH/s[21]。将多台矿机集中起来放在一起挖矿就形成了矿场,矿场耗电量巨大,一般会选择设在电力便宜的地方。随着越来越多的矿工入场,挖矿的总算力越来越高,单个矿工的产出也变得越来越不稳定,为了获得更加稳定的挖矿收益,矿工们联合起来与其他矿工进行竞争,因此逐渐出现了比特币矿池的概念。矿池是一个开放的、全自动的挖矿平台,矿工将自己的矿机接入矿池,贡献自己的算力共同挖矿获得收益。矿池本身并不进行挖矿计算,而是将计算任务分配给连接到矿池的矿机,矿池根据投入的算力占比进行收益分配,保证矿工获得更稳定的收入。根据BTC.COM 网站显示,截止到2020 年5 月5 日,根据最近1 年出块数据计算,全球算力占比前 5 名的矿池分别是 BTC.COM(15.64%)、F2Pool(15.37%)、Poolin(14.18%)、AntPool(11.65%)、ViaBTC(7.05%)。
4.4 奖励机制
挖矿成功可以获得区块奖励,创世区块的区块奖励是50 个比特币,每新增210000 个区块,奖励减半,根据每个区块产生平均时间10 分钟计算,大概每4 年左右区块奖励减半一次。从BTC.COM 可以获知,2012日 11 月 28 日 23 点 24 分 38 秒,210000 号区块被挖出,区块奖励第一次减半为25 个比特币。2016 年7 月10 日 0 点 46 份 13 秒,420000 号区块被出,区块奖励再次减半至12.5 个比特币,预计下一次减半时间是2020 年5 月12 日。此外,挖矿成功还可以获得区块中所有交易的交易费,交易费是由交易发起者规定给多少交易费,一笔交易的输出值与输入值之间的差值视为交易费,交易需要打包进区块上链才能被确认,为了能尽快上链确认交易,一般每笔交易会有少量交易费。随着区块奖励越来越低,将来系统将主要依靠交易费维持正常运行。
5 合约层(比特币脚本)
比特币系统合约层是一段比特币脚本代码,是智能合约的雏形,采用一种类Forth、基于栈模型、无状态的、非图灵完备的脚本语言实现。比特币脚本中不存在流控制和循环,极大降低了复杂性和不确定性,并且避免了陷入死循环等逻辑炸弹而造成拒绝服务等安全问题,但同时也降低了灵活性。比特币脚本本质上是一组指令的集合,常用指令如表3 所示[19]。比特币交易中包含两类脚本,即锁定脚本(scriptPubKey)和解锁脚本(scriptSig),锁定脚本也称为输出脚本,一般包含在一笔交易的输出中,规定了这笔交易输出的花费条件,解锁脚本也成为输入脚本,是满足花费条件的脚本,分别执行交易的输入脚本和上一笔交易的输出脚本,若执行正确,则表示解锁脚本满足锁定脚本规定的花费条件,将允许该输出被消费。比特币系统通过这两种脚本的组合,可以实现灵活的交易控制。
表3 比特币脚本常用指令
6 应用层(比特币交易)
比特币系统每个用户都拥有自己的私钥和公钥,私钥是保密不公开的,公钥是公开的,同时还拥有基于公钥生成的地址,用于比特币交易[20]。比特币系统中没有余额的概念,它使用UTXO(Unspent Transaction Out⁃puts,未花费的交易输出)模型,一个UTXO 可以是1 聪(satoshi,1 个比特币等于 1 亿聪)的任意倍数,一个UTXO 在一次交易中只能作为一个整体被花费,一个地址的所有UTXO 之和可以理解成是这个地址的余额。比特币交易包含输入和输出,输入和输出都可以有多个,表示一次交易可以将先前多个交易输出中的比特币合并后转给另外多个地址。Coinbase 交易是一种特殊交易,用于给挖矿成功的矿工发奖励,可以没有输入。普通交易输入对应上一笔交易的输出,主要由上笔交易的哈希、上笔交易的输出索引和输入脚本组成,上笔交易输出索引对应上笔交易的第几个输出,输入脚本包含了发送者对当前交易的签名信息。每个输出包括转账金额、输出脚本,输出脚本中包含了接收者公钥哈希。所有交易都包含上笔交易哈希值,从而构成了多条以交易为结点的交易链,每笔交易可一直向前追溯至源头的Coinbase 交易,向后可追踪至尚未花费的交易。如果一笔交易的输出没有任何另一笔交易的输入与之对应,则说明该输出中的比特币未被花费[14]。
比特币交易类型主要包括P2PKH(Pay-to-Public-Key-Hash)、P2PK(Pay-to-Public-Key)、P2SH(Pay-to-Script-Hash)。P2PKH 交易输出脚本锁定为接收者公钥哈希值,即我们常说的比特币地址,需要花费这笔交易输出,需要在创建一笔交易时提供自己的公钥和私钥签名来解锁,从而证明自己拥有这笔交易输出的支配权。P2PK 是支付到公钥的交易,锁定脚本中直接包含了接收者的公钥,解锁脚本包含需要花费这笔交易输出者的私钥签名。P2SH 是多重签名脚本交易,锁定脚本设置了N 个公钥,解锁脚本至少提供M 个私钥签名来解锁才能使用这笔输出,这也称为M-N 方案[20],P2SH 可以应用在遗产分配、担保交易、财务监督、公司决策等场景[10]。
用户间普通转账一般是P2PKH 交易,交易的流程如下:
步骤一系统搜索支付方的UTXO 集合,判断支付方是否有足够的资金进行支付,若有则进入步骤二,若无法交易。
步骤二创建交易,将上笔未花费的交易哈希和输出索引写入当前交易的输入中,构建输入脚本解锁上一笔交易的锁定脚本,将转账金额写入当前交易的输出,构建输出锁定脚本,若转账金额与交易费之和小于未花费金额,此时增加一个输出,输出的地址是支付方地址,该地址也称找零地址。
步骤三交易创建后,在比特币网络中广播该交易,全节点收到该交易后,会验证该交易是否合法,如验证交易输入是否对应的是UTXO 等。若通过验证,则将该交易加入到待确认交易集合,等待打包上链。
步骤四挖矿节点开始挖矿时会从待确认交易集合中根据优先级选取若干待确认交易加入到区块中,若挖矿成功则发布该区块,全网广播。
步骤五全网记账,各个节点接收到新区块后,验证是否合法,若合法则加入本地区块链末端,同时挖矿节点从本地待确认交易集合中移除新区块中的交易,同时需要更新本地UTXO 索引数据。
步骤六被添加到区块链上的交易称为确认交易,一笔交易经过6 次“确认”之后,大约需要1 个小时,就认为该交易是安全不可更改的了,此时交易接收方就能花费这笔交易所得的比特币,至此,一笔交易完成。
7 问题和展望
为了避免恶意节点生成一堆交易费为0 的无效交易导致网络瘫痪等问题,2010 年7 月中本聪引入了区块大小最大为1M 的限制,平均每笔交易约0.25K,每个区块能容纳的交易数量约为4194 笔,按照10 分钟出一个区块计算,比特币系统交易吞吐量为7TPS,即平均每秒能处理7 笔交易。当网络中发生大量交易时,大部分交易只能等待上链确认,会极大延长交易上链确认的时间,同时会导致交易费直线上升,因为想尽快上链确认的交易只能提高交易费。此外,10 分钟出块限制也是导致交易确认时间长的一个原因,为了保证交易是在主链(最长链)上,最终完成交易需要6 次“确认”,也就是完成一笔交易需要60 分钟。针对比特币系统交易吞吐量低和交易确认时间长的问题,目前有链上扩容和链下扩容两种方案。链式扩容是启动硬分叉提高区块大小,比特币现金正是采用这种方式在2017 年8 月1 日从原来的比特币网络中分离出来,这种方式每个区块可以包含更多的交易数据,降低交易费用,但是可能导致区块传输和同步时间变长等问题。链下扩容不增加区块大小,通过在链下建立一个支付通道(如闪电网络)来实现快速交易,任意两个用户可以直接建立点对点的支付通道进行多次转账交易,在通道关闭时将最终结果上链,这种方式提高了交易吞吐量,大大降低高频率小额交易的确认时间,降低交易费,通道关闭前多次转账的交易细节不会上链,牺牲了部分全程可追溯的特性[25-29]。
针对比特币挖矿耗费巨大电力资源和计算资源的问题,目前可取的方案有PoS(权益证明)以及在PoS 基础上衍生出来的DPoS,以太坊共识算法已经从PoW改为PoS。PoS 算法获得记账权的概率与币龄(货币数量*货币持有时长)成正比,不需要挖矿,也就避免了电力和计算资源浪费的问题。DPoS 是议会制的PoS,权益集中在议会成员中,共识效率更高,但是牺牲了部分去中心化特性[30-32]。
8 结语
比特币系统自诞生以来,总体运行安全稳定,仍在不断发展和完善中,同时开启了区块链快速发展的十年,区块链不仅仅是一个用于记账的账本,更是一场基于互联网的技术革命。对于比特币系统安全、比特币系统改进、比特币应用等问题有待进一步研究。