比特幣執行機制

weixin_33912246發表於2018-03-14
4328038-f6df25c1d0126bdf.png

我們知道,為了解決交易信用問題並提升交易效率,產生了比特幣,那比特幣的執行機制是怎麼樣子的呢?

首先比特幣是一個基於區塊鏈的分散式賬本,也就是說,交易記錄並不是記錄在某一箇中央節點(使用者)上,而是所有參與的節點都會持有這樣的一個交易記錄賬本(人手一份),在比特幣世界中發生的每一筆交易,都會通過一定的機制,最終通知給所有的節點,寫到他們的賬本中。

因為所有的節點都持有一份交易賬本,某一個節點試圖篡改交易資訊(比如否認了此次交易)都是徒勞的,因為在比特幣世界中,大多數節點記錄的,才是真理,除非你把網路中大部分節點的賬本資訊都篡改了,但這需要你花費驚人的代價。

交易成本

有的同學可能會好奇,發生了一次交易,需要同步給所有的節點,那麼交易的時間本會不會很高。

確實,使用比特幣發起的一筆交易需要至少1個小時才能最終確定是否成功,主要的耗時花在 資料的傳輸共識的達成

資料的傳輸

比特幣是基於區塊鏈技術的,所有的交易都是儲存在區塊中,在比特幣中區塊的大小限制在了1M以內,並且每10分鐘才產生1個區塊。

我們以一個交易0.25KB計算,每秒平均能打包1024Kb/0.25Kb/10Min/60s = 6.826個交易,這就是說每秒處理7筆交易左右,對比VISA平均5萬筆/秒、支付寶峰值25.6w筆/秒來說差的不是一點兩點。

為啥是1M

比特幣剛發行的時候,交易非常的少,當時認為1M的區塊足夠使用,太大則會影響其在網路上的傳播。

1M限制並不是不能擴大的,目前1MB的限制已經成了比特幣高效交易的一個瓶頸,所以擴容也被提上日程,目前的一個改進方案是BIP101:先提升區塊體積上限至8MB,然後每兩年上限加倍,直至每塊達到8GB 上限,之後每秒交易數8*1024*1024/0.25/60/10 = 5.6萬筆/秒,並不遜色於現在的VISA處理能力,當然,對節點所在網路的頻寬也是有要求的(能夠快速的傳輸8GB的區塊)。

共識達成

當A支付1比特幣給B的時候,A首先需要通過比特幣錢包構建相應的一條交易記錄,然後將這條交易記錄廣播到網路中。

在比特幣體系中,有一種角色叫做礦工,任何人都可以無條件的成為礦工,礦工會專門監聽網路中的交易資訊,一旦捕獲到交易資訊,就放到記憶體中的臨時交易池中,礦工會在合適的時機從臨時交易池中選擇一部分交易資訊,打包成為一個區塊:


4328038-f39ddc1002f4c7ca.png

區塊包含了區塊頭區塊體,其中區塊體中主要是一些交易列表資訊,區塊頭包含了版本號、隨機數、上一個區塊的編號、區塊體中的交易列表的merkle樹根hash值、難度值等,區塊頭的總大小是80位元組。

礦工必須不斷的變換區塊頭中的隨機數,使得

SHA256(SHA256(區塊頭)) < 難度值

要想讓上面的這個不等式成立,需要進行大量的計算,實際上這個計算就是礦工的主要工作,也被稱之為“挖礦”。

一旦礦工完成了計算,會立馬將區塊廣播出去,告知其他礦工,自己挖到了一個區塊,其他礦工收到這個區塊後,會校驗區塊合法性(是不是符合上面的那個不等式),一旦校驗成功,該礦工就會停止自己的挖礦工作,然後將該區塊放到之前接收到的所有區塊的最尾端(這樣各個區塊就形成了一個鏈條,所以叫區塊鏈),並對比自己的臨時交易池中的交易和區塊中的交易,將相同的部分移除掉(因為已經被別人挖到了),然後進行新一輪的挖礦工作,也就是從交易池中重新打包一個區塊,重新挖。

所謂的達成共識,就是你挖的的區塊,已經大部分的礦工都認同並加入到自己區塊鏈條中了。

分叉問題

假設你是一個礦工,最開始的時候,你記錄的區塊鏈(主鏈)如下圖所示:


4328038-0bce7b2ba62435b7.png

這時,你同時接收到兩個區塊,一個來自中國的礦工,一個來自美國的礦工,而且這兩個區塊都是有效的,於是你吧兩個區塊連結到主鏈上:


4328038-b54959b283a8e598.png

可以看到,區塊鏈分叉了,如何解決這個分叉問題呢?

出現分叉後,一部分礦工會基於“來自中國的區塊”繼續挖礦,一部分則更加另外一個區塊繼續挖礦,最終導致兩個分支會不同程度的延伸,比特幣規定,長度較長的那個分支會成為主分支!

一般延伸六個區塊之後,兩個分支的長度很難在保持一致,所以比特幣交易的最終確認,要至少等挖出六個區塊(成為6次確認),由於平均每10分鐘挖出一個區塊,所以交易的確認要1個小時以上!

雙花問題

假設我們只有1比特幣,但我們可以構造兩筆交易,每筆交易都花費了1比特幣,如果能夠讓兩筆交易都成功被確認,我們就認為成功進行了一次“雙花攻擊”。

為了進行雙花攻擊,我們可以把第一筆交易向一半網路進行廣播,把第二筆交易向另一半網路廣播,假設兩邊正好有兩個礦工幾乎同時挖到了包含我們的交易的區塊,並把區塊釋出給周圍的節點,這時區塊就會分叉:


4328038-0182320652c979e2.png

但是考慮到比特幣有6次確認機制,最後只有一個分支保留下來,所以這種方式不可行。

不過我們可以採用另外的一種方案,首先向網路當中廣播第一個交易,假設第一個交易被包裝成區塊並通過了6次確:


4328038-02d637a34c237d54.png

為了讓第二筆交易也能夠得到確認,你需要至少構建6個區塊進行分叉:


4328038-8c7d6f6427d840b3.png

只有當交易2所在的分支長度>區塊1所在分支長度的時候,才有可能讓你的交易2被確認,事實上,這是很困難的一件事情,假設你的算力佔據了全網的1/100,那麼交易2被確認的概率是1/100的六次方,概率上幾乎為0,而且擁有全網1/100的算力,本身就是一種奢望。

所有的交易記錄在自己電腦裡,體積會不會很大

因為比特幣每10分鐘產生一個區塊,每個區塊按照1M來算的話,那麼從2009年到現在,總共有:9(年) * 365(天) * 24(小時) * 60(分鐘) / 10(分鐘) / 1024(M) ≈ 462G

如果你把包含了所有交易的區塊全部記錄下來的話,估計會吃不消,不過目前使用了Merkle樹,可以讓我們只儲存區塊中的區塊頭(類似於只存放了目錄),所以雖然比特幣已經發生了數千萬筆交易,但是每個節點儲存的賬本資訊,還是很小的。

相關文章