北京⼤学肖臻⽼师《区块链技术与应⽤》公开课笔记5——BTC具体实现篇
北京⼤学肖臻⽼师《区块链技术与应⽤》公开课笔记
⽐特币具体实现篇,对应肖⽼师视频:
全系列笔记请见:
区块链是⼀个去中⼼化的账本,⽐特币采⽤了 基于交易的账本模式 。然⽽,系统中并⽆显⽰记录账户包含⽐特币数,实际上其需要通过交易记录进⾏推算。在⽐特币系统中,全节点需要维护⼀个名为 UTXO(Unspent Transaction Output尚未被花掉的交易输出) 的数据结构。
如图,A转给B五个BTC,转给C3个BTC,B将5个BTC花掉,则该交易记录不保存在UTXO中,C没有花掉,则该交易记录保存在UTXO中
UTXO集合中每个元素要给出产⽣这个输出的交易的哈希值,以及其在交易中是第⼏个输出。通过这两个信息,便可以定位到UTXO中的输出。
为什么要维护这样⼀个数据结构
为了防范“双花攻击”,判断⼀个交易是否合法,要查⼀下想要花掉的BTC是否在该集合中,只有在集合中才是合法的。如果想要花掉的BTC不在UTXO中,那么说明这个BTC要么根本不存在,要么已经被花过。所以,全节点需要在内存中维护⼀个UTXO,从⽽便于快速检测double spending(双花攻击)。
每个交易会消耗输出,但也会产⽣新的输出。
如图,A转给B5个BTC,之后B将其转给D,则UTXO中会删掉A->B这⼀交易记录,同时会添加B->D这⼀交易记录。
假如有⼈收到BTC转账,但⼀直不花,那么这个信息会⼀直保存在UTXO中。这种情况可能是该⽤户
文科生最好的六个专业不想花这些BTC(如:中本聪) ,也有可能是忘记了私钥导致⽆法花掉。所以,UTXO是逐渐增⼤的,但该数据⽬前来说,⼀个普通的服务器硬盘中是可以完全保存这些数据的。
每个交易可以有多个输⼊,也可以有多个输出,但输⼊之和要等于输出之和(total inputs = total outputs)。
存在⼀些交易的total inputs 略⼤于 total outputs,这部分差额便作为交易费,给了获得记账权的节点。在公开课笔记4中最后提及到“区块中保存交易记录,如果仅仅设置出块奖励,那么,会不会存在节点只想发布区块获得出块奖励⽽不想打包交易?”
因此,BTC系统设计了Tranction fee(交易费),对于获得记账权节点来说,除了出块奖励之外,还可以得到打包交易的交易费。但⽬前来说,交易费远远⼩于出块奖励。等到未来出块奖励变少,可能区块链的维护便主要依赖于交易费了。
x战警系列顺序>各省简称BTC系统中每21万个区块,BTC出块奖励减半。根据下图计算,基本上出块奖励每4年减半。
⽐特币是基于交易的模式,与之对应,还有⼀种基于账户的模式(如:以太坊)。基于账户的模式要求,系统中显⽰记录账户余额。
也就是说,可以直接查询当前账户余额是多少货币。可以看到,⽐特币这种模式,隐私性较好,但其也付出⼀定代价。在进⾏交易时,因为没有账户这⼀概念,⽆法知道账户剩余多少BTC,所以必须说明币的来源(防⽌双花攻击)。⽽基于账户的模式,则天然地避免了这种缺陷,转账交易就是对⼀个(多个)账户余额的数字减和另⼀个(多个)账户余额的数字加
BTC系统中具体的区块信息
如下图所⽰,为⼀个区块的信息(取⾃视频中截图,源⾃blockchain.info)
什么是挖矿?
可以看到,区块哈希与前⼀区块哈希都是以⼀长串0开头的,挖矿本⾝就是尝试各种nonce,使得产⽣的区块哈希值⼩于等于⽬标阈值。该⽬标阈值,表⽰成16进制,就是前⾯含有⼀长串的0
下为block header的代码中实现的数据结构。⾥⾯的⼏个域在公开课笔记4中(⽐特币区块信息)已经解释过了,这⾥不再赘述。
dvd转换可以看到,nonce是⼀个32位的⽆符号整型数据,在挖矿时候是通过不断调整nonce进⾏的,但可以看到,nonce的取值最多为2^32 (2的32次⽅)种。但并⾮将这些nonce全部遍历⼀遍,就⼀定能到符合要求的nonce。由于近年来,挖矿⼈员越来越多,挖矿难度已经调整的⽐较⼤了(关于难度调整请关注后续博⽂,会有专门⼀篇介绍难度调整),⽽2^32这⼀搜索空间太⼩,所以仅调整nonce很⼤可能不到正确的结果。
还有哪些域可以调整呢?
下图为block header中对各个域的描述。⽽仅仅调整nonce是不够的,所以这⾥可以通过修改Merkle Tree的根哈希值来进⾏调整。2021年冬至
思考:打包的交易和顺序确定了,根哈希值不就确定了吗?这个怎么能修改呢?
铸币交易(coinbase交易)
在公开课笔记4中提及,每个发布区块者可以得到出快奖励,也就是可以在区块中发布⼀个 铸币交易(coinbase交易) ,这也是BTC系统中产⽣新⽐特币的唯⼀⽅式。下为⼀个铸币交易的内容:
可以看到,有⼀个CoinBase域,其中可以写⼊任何内容,在这⾥写什么都没有影响。所以可以在这⾥添加⼀些任意信息,便可以实现⽆法篡改(也⽆法删除)。(例如:提前写⼊股票预测结果的哈希值、写⼊⼈⽣感想,写⼊爱情誓⾔(⽆法删除,想想删不掉⼗年前发表的QQ 空间⾮主流说说是多么痛苦吧,嘿嘿嘿))
所以,只要我们改变了写⼊内容,便可以改变Merkle Tree 的根哈希值。
下图为⼀个⼩型的区块链,假定左下⾓交易为coinbase交易,可以看到,该交易发⽣改变会逐级向上传递,最终导致Merkle Tree根哈希值发⽣改变。qq网络游戏大全
所以,在实际的挖矿中,包含两层循环。外层循环调整coinbase域(可以规定只将其中前x个字节作为另⼀个nonce),算出block header 中根哈希值后,内层循环再调整nonce。
普通转账交易
如果将输⼊脚本和输出脚本拼接起来可以顺利执⾏不出现错误,则说明交易合法。
挖矿过程的概率分析
挖矿本质上是不断尝试各种nonce,来求解这样⼀个puzzle。每次尝试nonce,可以视为⼀次伯努利试验。最典型的伯努利试验就是投掷硬币,正⾯和反⾯朝上概率为p和1-p。在挖矿过程中,⼀次伯努利试验,成功的概率极⼩,失败的概率极⼤。挖矿便是多次进⾏伯努利试验,且每次随机。这些伯努利试验便构成了a sequence of independent Bernoulli trials(⼀系列独⽴的伯努利试验)。根据概率论相关知识知道,伯努利试验本⾝具有⽆记忆性。也就是说,⽆论之前做多少⼤量试验,对后续继续试验没有任何影响(车牌摇号也是如此,,⼼痛…)。
对于挖矿来说,便是多次伯努利试验尝试nonce,最终到⼀个符合要求的nonce。在这种情况下,可以采⽤泊松分布进⾏近似,由此通过概率论可以推断出,系统出块时间服从指数分布。(需要注意的是,出块时间指的是整个系统出块时间,并⾮挖矿的个⼈)
系统平均出块时间为10min,该时间为系统本⾝设计,通过难度调整维护其平均出块时间。
指数分布本⾝也具有⽆记忆性。也就是说,对整个系统⽽⾔,已经过去10min,仍然没有⼈挖到区块,那么平均仍然还需要等10min(很不符合⼈的直觉)。也就是说,将来要挖多久和已经挖多久⽆关。
虽然这样看起来是⼀个冷酷的事情,过去的⼯作可能都会⽩做。但实际上这才是挖矿公平性的保障。对算⼒有优势的矿⼯来说,其之前所做⼤量⼯作仍有可能会⽩费。
⽐特币总量计算
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论