Michael.W深度剖析Bitcoin系統第3期——比特币的UTXO模型
-
- 1 比特币的賬戶模式
- 2 coinbase交易中資料域的秘密
- 3 挖礦“對于每個參與者都是平等的麼?
- 4 比特币發行總量
1 比特币的賬戶模式
比特币采用的是基于交易的賬本模式,
transaction-based ledger
。賬本中并不像傳統銀行的中心資料庫那樣,記錄着所有開戶人的資産資訊。如果你想知道某個比特币位址上的所有資産量,隻能通過計算與該賬戶有關的所有交易而得出。
此時,我要引入UTXO(
Unspent Transaction Output
)模型 ,即所有未被花銷的交易輸出集合。一個位址下的所有UTXO的金額之和可以認為是目前位址中有多少可消費的比特币餘額。
UTXO中的每個元素要給出産生這個輸出的交易哈希值以及它是這筆交易中的第幾個輸出。依靠這以上兩個資訊就可以在比特币區塊鍊中精确定位到該UTXO。
為什麼會出現UTXO集合這種設計呢?個人覺得中本聰的本意是用來防止交易中産生**”雙花“現象**。簡單地說,你要花銷的比特币如果不在UTXO集合中,就說明你發起的交易是無效的,是僞造的,是不堪的!
既然每個人在發起一筆交易時都需要查詢UTXO集合,那麼所有的全節點都要在本地記憶體中維護UTXO這樣的一個資料結構的大集合,以便快速校驗出"雙花"交易。
每筆交易都會消耗一筆UTXO,同時也會産生新的一筆UTXO。形象地說,A給B成功轉了5BTC,那麼以前屬于A的UTXO就變成無效,同時生成屬于B的有效UTXO。
迄今為止,比特币的全賬本已經超過200個G,但目前網絡内的所有UTXO加在一起大概在2個G左右徘徊(隻要有交易,UTXO就會變化)。這對于一個維護全網UTXO的伺服器記憶體來說,還是綽綽有餘的的。
一筆交易可以有多個輸入或多個輸出。同時支援1對1、1對多、多對1、多對多,像極了現在的愛情。
一筆交易的輸入與輸出的差額将會成為礦工的手續費。這是為了激勵礦工來為所有人來打包交易而設計的,即比特币系統中的第二種激勵機制。
除了基于交易的賬本模式外,區塊鍊世界中還有一種基于賬戶的賬本模式,
account-based ledger
。後來誕生的以太坊的就是基于這種模式設計。
以太坊系統要顯式地記錄每個使用者賬戶中共有多少資産,跟銀行的中心伺服器有異曲同工之妙。
由于比特币是基于交易的賬本模式,是以每一筆比特币交易都需要把錢的來源和有效性說明白。因為比特币中完全沒有賬戶的概念,沒人知道你的賬戶還有多少錢可以使用。以太坊則不然,并不用這樣顯式地說明每一筆錢的來源和走向。
2 coinbase交易中資料域的秘密
這是最近一個區塊的屬性:
可以看到所有符合難度要求的區塊頭哈希值轉成16進制後,前面都是一大長串的0。這與比特币的挖礦機制有關,後面我會寫篇文章細說。
來看一下比特币源碼中的區塊頭屬性:
注意一下
nonce
這個成員屬性。它是個32位無符号整形變量,是以它的最大值也就是2^32-1。
按照現在比特币網絡内的挖礦難度來算,很有可能周遊0~2^32-1之間所有的整數也找不到滿足條件的nonce值。
如果周遊了所有可能的nonce值也無法滿足H(block header)<=target條件,那麼我們還能更改比特币區塊頭中的哪些屬性的?
答案是:改
merkle root
!你一定很奇怪,merkle root用來校驗交易是否被篡改,這怎麼還可以随便改呢?
每個區塊都會包含有一個coinbase交易(區塊體中的第一筆交易),礦工通過這個交易擷取出塊獎勵。coinbase交易中有個coinbase資料域。這裡面是礦工的地盤,他想寫什麼就可以寫什麼,因為所有交易的驗證工作都不涉及這個區域!
上面是中本聰在比特币的創世區塊的coinbase域中寫下的話。大家注意,如果我改變coinbase資料域中的内容,那麼coinbase交易的哈希值就會改變,接着會直接影響到merkle tree的根哈希值,最後可以導緻改變整個區塊頭的哈希值。
是以比特币礦機挖礦的真正邏輯是包含兩層循環。外層循環調整coinbase資料域的前八個位元組,内層循環調整區塊頭中的nonce值。這樣輸出空間擴大了2^64倍,根本不存在找不到合适的nonce值的情況了。
來看剛剛産生的一筆比特币交易記錄:
1個輸入,2個輸出。輸入為0.0091298BTC,輸出為0.0075293BTC,手續費0.0016005BTC。
下面是這筆交易的解鎖腳本和鎖定腳本:
比特币中驗證交易的合法性就是把每筆交易的Input Scripts和Output Script拼裝到一起後執行。
注意,不是将本交易中的輸入和輸出腳本配對,而是将本交易的輸入的腳本和該輸入在前面那個提供币的來源的交易的輸出腳本拼裝到一起。一定要注意!注意!再注意!
如果輸入腳本和輸出腳本拼接在一起能夠順利執行不報錯,那麼這個交易就是合法的。
比特币的挖礦難度值每2016個區塊調整一次,時間大約為2周(每個區塊出塊時間大約在10分鐘左右)。這種挖礦難度自調整模式也是為了穩定出塊時間而設計的。
3 挖礦“對于每個參與者都是平等的麼?
每次”挖礦“就是一個伯努利試驗(
Bernoulli trial
)。
生活中最典型的伯努利試驗的例子就是抛硬币。理想情況下,抛硬币的勝負機率均為50%,但對于”挖礦“來說,挖不到占很大機率,挖到占很小機率。
而連續挖礦就可以認為是一個伯努利過程(
Bernoulli process
),是無記憶性的。
形象地了解就是前面的試驗對後面的試驗沒有任何影響。這就好像:假如你抛硬币扔了5把都是反面,那麼是不是你第6次抛出正面的機率就要比反面更高呢?答案是否定的。因為每一次試驗都是獨立事件。
如果當”挖礦“次數足夠多的時候,這個伯努利過程就可以近似看成一個蔔瓦松過程(
Poisson process
)。
假如整個比特币網絡中各節點”挖礦“已經挖了十分鐘還沒有出礦,那麼從現在開始還需要多久能挖出礦呢?直覺上給我們的感覺是那應該是快了,但是數學告訴我們距離下次挖出礦的時間還是大約十分鐘!
比特币系統中某一個礦工能挖到下一個區塊所需的時間可以認為是取決于他的算力占整個比特币系統算力的百分比。比如:一個礦工它的算力是整個比特币網絡所裡的千分之一,那麼他平均挖到下一個區塊的時間間隔為10*1000=10000分鐘。
如果一種加密數字貨币的POW模型算法不具備無記憶性(
progress free
),會出現一個什麼問題?
就是算力強的礦工會有不成比例的優勢。
舉個栗子:如果礦工A的算力是礦工B的十倍,那麼礦工A挖到礦的機率也應該是礦工B的十倍這才叫公平(pow模型滿足progress free)。但是如果不滿足這個性質,那麼礦工A挖到礦的機率就要遠遠超過礦工B的十倍了。因為前面不成功的操作越多回到導緻後面成功的機率增大。
是以不要覺得比特币挖礦這種progress free屬性很無情,這恰恰是保證挖礦公平的根本。
4 比特币發行總量
比特币協定規定:出塊獎勵每21萬塊後減半(最開始出塊獎勵為50BTC),這樣比特币總量就構成了一個幾何序列:
21*50+21*25+21*12.5+….
=21*50*(1+1/2+1/4+1/8+….)
=21*50*(1/(1-1/2))
=2100(萬)
大家要注意:挖礦的過程是沒有任何實質意義的,但是挖礦的行為對于維護比特币系統的安全是至關重要的 。
在一個沒有
membership
控制的分布式系統中,挖礦提供了一種憑借算力投票的有效手段。隻要大部分算力掌握在誠實節點手裡,那麼這個系統的安全就可以得到保障。
那是不是随着比特币出塊獎勵越來越少,礦工挖礦的動力就降低了呢?
從比特币價格走勢圖上看,非也非也。雖然獎勵少了,但是比特币單價提高了。
那麼,假如有朝一日比特币的出塊獎勵變成0,還有人挖礦麼?答案是肯定的,因為還有手續費可以作為盈利手段。
ps:
本人熱愛圖靈,熱愛中本聰,熱愛V神,熱愛一切被梨花照過的姑娘。
以下是我個人的公衆号,如果有技術問題可以關注我的公衆号來跟我交流。
同時我也會在這個公衆号上每周更新我的原創文章,喜歡的小夥伴或者老夥計可以支援一下!
如果需要轉發,麻煩注明作者。十分感謝!
公衆号名稱:後現代潑痞浪漫主義創始者