區塊鏈學習筆記之比特幣(一)

一、比特幣

1.密碼學基礎

比特幣被稱爲加密貨幣crypto-currency。區塊鏈上內容都是公開的,包括區塊的地址,轉賬的金額。比特幣主要用到了密碼學中的兩個功能: 1. 哈希 2.簽名

1.1 哈希

密碼學中用到的哈希函數被稱爲cryptographic hash function,它有兩個重要的性質:
(1)collision(這裏指哈希碰撞) resistance :例如x≠y H(x)=H(y) 兩個不同的輸入,輸出卻是相等的,這就稱哈希碰撞。它是不可避免的,因爲輸入空間總大於輸出空間。給出x,很難找到y,除非蠻力求解(brute-force)。

  • 該性質的作用:對一個message求digest,比如message取m, m的哈希值是H(m)=digest 如果有人想篡改m值而H(m)不變,則無法做到。
  • 哈希碰撞無法人爲製造,無法驗證,是根據實踐經驗得來的
  • 關於這個性質的應用:上傳一個文件到cloud,如何防止該文件被篡改?用這個文件作爲一個輸入input,計算這個input的哈希值H(input)存在本地並把文件上傳,之後將cloud上的文件下載下來再計算其哈希值,比較兩個哈希值是否一致即可知道文件是否被篡改。
  • MD5,曾經很流行的一個哈希函數,但是目前已經知道如何去製造一個MD5的哈希碰撞

(2)hiding:哈希函數的計算過程是單向的,不可逆的。(從H(x)無法推導出x) hiding性質前提是輸入空間足夠大,分佈比較均勻。如果不是足夠大,一般在x後面拼接一個隨機數,如H(x||nonce)。該性質的作用:和collision resistance(耐碰撞) 結合在一起,用來實現digital commitment(數字承諾)(又稱爲digital equivalent of a sealed envelope數字等效的密封信封)把預測結果作爲輸入x,算出一個哈希值,將哈希值公佈,hiding讓人們知道哈希值而不知道預測值,最後再將x公佈,因爲有collision resistance的性質,預測結果是不可篡改的。

除了密碼學中要求的這兩個性質外,比特幣中用到的哈希函數還有第三個性質:
(3)puzzle friendly 指哈希值的預算事先是不可預測的。假如哈希值是00…0XX…X,一樣事先無法知道哪個值更容易算出這個結果,還是要一個一個帶入。

  • 比特幣挖礦的過程中實際就是找一個nonce,nonce跟區塊的塊頭裏的其他信息合一起作爲輸入,得出的哈希值要小於等於某個指定的目標預值。H(block header)≤target。block header 指塊頭,塊頭裏有很多域,其中一個域是我們可以設置的隨機數nonce,挖礦的過程是不停的試隨機數,使得block header取哈希後落在指定的範圍之內。
  • puzzle friendly是指挖礦過程中沒有捷徑,爲了使輸出值落在指定範圍,只能一個一個去試。所以這個過程還可以作爲工作量證明(proof of work)。挖礦很難,驗證很容易。(difficult to solve ,but easy to verify)。比特幣中用的哈希函數叫作SHA-256(secure hash algorithm )以上三個性質它都是滿足的。

1.2 簽名

(1)在比特幣系統中開賬戶:在本地創立一個公私鑰匙對(public key ,private key),這就是一個賬戶。公私鑰匙對是來自於非對稱的加密技術(asymmetric encryption algorithm)。什麼叫做非對稱加密,先讓我們來了解一下對稱加密。兩人之間信息的交流可以利用密鑰(encryption key),A將信息加密後發給B,B收到後用密鑰解密,因爲加密和解密用的是同一個密鑰,所以叫對稱加密。前提是有渠道可以安全地把密鑰分發給通訊的雙方。因此對稱加密的缺點就是密鑰的分發不方便,因爲在網絡上很容易被竊聽。非對稱密鑰是用一對密鑰而不是一個,加密用公鑰,解密用私鑰,加密和解密用的都是接收方的公鑰和私鑰。公鑰是不用保密的,私鑰要保密但是私鑰只要保存在本地就行,不用傳給對方。公鑰相當於銀行賬號,別人轉賬只要知道公鑰就行,私鑰相當於賬戶密碼,知道私鑰可以把賬戶上錢轉走。公鑰用來驗證,私鑰是用來簽名。如下圖:

在這裏插入圖片描述在這裏插入圖片描述
注意:在比特幣區塊鏈中,私鑰代表了對比特幣的控制權。交易發起方用私鑰對交易(包括轉賬金額何轉賬地址)簽名,並將簽名後的交易和公鑰公佈,各節點接收到交易後可以用公鑰驗證交易是否合法。在這個過程中,交易發起方無需暴露自己的私鑰,從而實現保密目的。

(2)假如A想向B轉10個比特幣,A把交易放在區塊鏈上,別人怎麼知道這筆交易是A發起的呢?這就需要A要用自己的私鑰給交易簽名,其他人收到這筆交易後,要用A的公鑰去驗證簽名。簽名用私鑰,驗證用公鑰,用的仍然是同一個人的。創建賬戶產生相同公私鑰的可能性微乎其微,所以大量創建賬戶來竊取其他人賬戶是不可行的。

(3)我們假設產生公私鑰時有一個好的隨機源(a good source of randomness),產生公私鑰是隨機的,如果隨機源不好,就有可能產生相同的公私鑰。比特幣中用的簽名算法,不僅是生成公私鑰的時候要有好的隨機源,之後每一次簽名時也要有好的隨機源。只要有一次簽名用的隨機源不好的話,就有可能泄露私鑰。

2.比特幣數據結構

2.1 哈希指針

(1)普通指針存儲的是某個結構體在內存中的地址。假如P是指向一結構體的指針,那麼P裏面存放的就是該結構體在內存中的起始位置。而哈希指針除了要存地址之外,還要保存該結構體的哈希值H()。好處是:從哈希值這個哈希指針,不僅可以找到該結構體的位置,同時還能夠檢測出該結構體的內容有沒有被篡改,因爲我們保存了它的哈希值。如下圖:
在這裏插入圖片描述
在這裏插入圖片描述

(2)比特幣中最基本的結構就是區塊鏈,區塊鏈就是一個一個區塊組成的鏈表。那麼區塊鏈和普通的鏈表相比有什麼區別:

  • ①用哈希指針代替了普通指針(Block chain is a linked list using hash pointers)。區塊鏈第一個區塊叫作創世紀塊(genesis block), 最後一個區塊是最近產生的區塊(most recent block) 每一個區塊都包含指向前一個區塊的哈希指針 。一個區塊的哈希指針怎麼算:是把前面整個區塊的內容,包括裏面的hash pointer ,合在一起取哈希值。通過這種結構,可以實現tamper-evident log(防篡改日誌)。如果有人改變了一個區塊的內容,後面一個區塊的哈希指針就對不上,因爲後一個區塊哈希指針是根據前一個區塊的內容算出來的,所以後一個哈希指針也得改,以此類推,我們保留的是最後一個哈希值也會變化。如下圖:
    在這裏插入圖片描述
    在這裏插入圖片描述

  • ②普通鏈表可以改變任意一個元素,對鏈表中其他元素是沒有影響的。而區塊鏈是牽一髮而動全身,因爲只需要保存最後一個哈希值,就可以判斷區塊鏈有沒有改變,在哪裏改變了。因此比特幣沒有要保存所有區塊的內容,可以只保留最近的幾千個區塊。如果要用到以前的區塊,可以向系統中其他節點要這個區塊。有些節點是有惡意的,怎麼判斷?這裏要用到哈希值一個性質,如下:其他節點給你一個區塊,如何判斷它是正確的?算出它的哈希值,與保留的區塊的哈希值對比,即可。下面是一個區塊鏈實例:
    在這裏插入圖片描述

2.2 Merkle Tree

(1)比特幣中的另外一個結構是:Merkle tree,如下圖。其中最下面一層是數據塊(data blocks),上面三層內部節點都是哈希指針(hash pointers),第一層是根節點,根節點的區塊也可以取個哈希,叫根哈希(root hash)。這裏我們提一個另外一個概念:binary tree(二叉樹),學過數據結構的人都知道,這裏不做贅述。這種Merkle tree結構的好處:只要記住根哈希值,就能檢測出對樹中任何部位的修改。
注意:它們的區別:①用哈希指針代替了普通指針。
在這裏插入圖片描述
注:上圖中TX爲transaction(交易),H()爲取哈希。


(2)比特幣當中各區塊之間用哈希指針連接在一起,每個區塊所包含的交易組織成merkle tree的形式,最下面一行data blocks每個區塊實際上是一個交易,每個區塊分爲兩部分,分別是塊頭和塊身(block header ,block body)。塊頭裏面有根哈希值,每個區塊所包含的所有交易組成的merkle tree的根哈希值存在於區塊的塊頭裏面,但是,塊頭裏沒有交易的具體內容,只有一個根哈希值,塊身裏面是有交易的列表的。

(3)merkle tree 的作用:①提供merkle proof ,比特幣中的節點分爲兩類:全節點(保存整個區塊的內容,即塊頭塊身都有,有交易的具體信息)和輕節點(例如手機上的比特幣錢包,只有塊頭)。這時存在一個問題:如何向一個輕節點證明某個交易是寫入區塊鏈的?

  • 這時需要用到merkle proof :找到交易所在的位置(最底行的其中一個區塊),這時該區塊一直往上到根節點的路徑就叫merkle proof。

  • 實例如下圖:最上面一行是小型的區塊鏈,該圖展現的是一個區塊的merkle tree,最下面一行是包含的交易。假設某個輕節點想知道圖中黃色的交易,是否包含在了merkle tree裏面。該輕節點沒有包含交易列表,沒有這顆merkle tree的具體內容,只有一個根哈希值。這時輕節點向一個全節點發出請求,請求證明黃色的交易被包含在這顆merkle tree裏面的merkle proof。全節點收到這個請求之後,只需要將圖中標爲紅色的這三個哈希值發給輕節點即可。有了這些哈希值之後,輕節點可以在本地計算出圖中標爲綠色三個哈希值。首先算出黃色交易的哈希值,即它正上方的那個綠的哈希值,然後跟旁邊紅色的哈希值拼接起來,可以算出上層節點綠色的哈希值。然後再拼接,再算出上層綠色哈希值,再拼接,就可以算出整棵樹的根哈希值。輕節點把這個根哈希值和block header裏的根哈希值比較一下,就能知道黃色的交易是否在這顆merkle tree裏。
    在這裏插入圖片描述

  • 全節點在merkle proof裏提供的這幾個哈希值,就是從黃色的交易所在的節點的位置到樹根的路徑上用到的這些哈希值。輕節點收到這樣一個merkle proof之後,只要從下往上驗證,沿途的哈希值都是正確的即可。(驗證時只能驗證該路徑的哈希值,其他路徑是驗證不了的,即該圖中紅色的哈希值是驗證不了的)

(4)這樣是否不安全呢?假如黃色交易被篡改,它的哈希值發生了變化,那能不能調整旁邊紅色的哈希值,使得它們拼接起來的哈希值是不變的呢?

  • 不行,根據collision resistance,這是不可行的。
  • merkle proof可以證明merkle tree裏面包含了某個交易,所以這種證明又叫proof of membership或 proof of inclusion。
  • 對於一個輕節點來說,驗證一個merkle proof 複雜度是多少?假設最底層有n個交易,則merkle proof 複雜程度是θ(log(n))

(5)如何證明merkle tree裏面沒有包含某個交易?即proof of non-membership。

  • 可以把整棵樹傳給輕節點,輕節點收到後驗證樹的構造都是對的,每一層用到的哈希值都是正確的,說明樹裏只有這些葉節點,要找的交易不在裏面,就證明了proof of non-membership。問題在於,它的複雜度是線性的θ(n),是比較笨的方法。

  • 如果對葉節點的排列順序做一些要求,比如按照交易的哈希值排序。每一個葉節點都是一次交易,對交易的內容取一次哈希,按照哈希值從小到大排列。要查的交易先算出一個哈希值,看看如果它在裏面該是哪個位置。比如說在第三個第四個之間,這時提供的proof是第三個第四個葉節點都要往上到根節點。如果其中哈希值都是正確的,最後根節點算出的哈希值也是沒有被改過的,說明第三、四個節點在原來的merkle tree裏面,確實是相鄰的點。要找的交易如果存在的話,應該在這兩個節點中間。但是它沒有出現,所以就不存在。其複雜度也是log形式,代價是要排序。排好序的叫作sorted merkle tree。比特幣中沒有用到這種排好序的merkle tree,因爲比特幣中不需要做不存在證明。

(6)小結:這節講了比特幣中兩種最基本的結構:區塊鏈和merkle tree,都是用哈希指針來構造的。除了這兩種之外,哈希指針還能用於另一個方面。只要一個數據結構是無環的(非循環鏈表),都能用哈希指針代替普通指針。有環的話存在一個問題,他們的哈希值沒法計算,沒法確定一個哈希值固定的區塊。

3.比特幣的共識協議

3.1 數字貨幣&&比特幣

(1)首先我們引入一個問題,央行CB如何發行數字貨幣?
方案一:asymmetric encryption algorithm(非對稱加密算法),央行發行一張貨幣如下,發行的貨幣都有央行的私鑰簽名,央行的公鑰是公開的,任何人都可以通過公鑰來認證數字貨幣的真僞。
在這裏插入圖片描述

  • 注意:這種方案無法防止Double Spending Attack(雙花攻擊),即一張貨幣被多次花費

方案二:在方案一的基礎上,加一張表,記錄每一張貨幣目前在誰手中,在交易前驗證這張數字貨幣是否是支付者的。這種方式是中心化的,每次交易都要經過央行驗證。所謂去中心化,即將這種驗證的職責,從由央行承擔改爲由大衆來承擔。

在這裏插入圖片描述

  • 這種方案沒有問題,但是每次交易都需要央行驗證

(2)由上面分析我們可以知道,數字貨幣和紙質貨幣區別是,數字貨幣可以複製並且被多次花費,叫作雙花攻擊 即double spending attack。那麼去中心化貨幣要解決兩個問題:①數字貨幣的發行②怎麼驗證交易的有效性,防止double spending attack。回答如下:

  • ①比特幣的發行是由挖礦決定的
  • ②依靠區塊鏈的數據結構

實例如下圖:
在這裏插入圖片描述

  • 比特幣的發行者A擁有鑄幣權(createcoin) 假如發行10個比特幣 A(10)分別給B和C各五個B(5)C(5) 該交易需要有A的簽名,證明經A同意(Signed by A)。同時還要說明花掉的10個比特幣從哪來的。圖中第二個方框中的錢是從第一個框內鑄幣交易中來的。

  • 比特幣系統中每個交易都包含輸入(input)和輸出(output)兩部分。輸入部分要說明幣的來源以及支付者公鑰,輸出部分要給出收款人公鑰的哈希。有的交易部分比較複雜,如C的貨幣來源是第二個框和第三個方框,要標識清楚。

  • 上圖就構成了一個小型的區塊鏈,這裏有兩種哈希指針,一種哈希指針是連接在各個區塊之間的,把它們串起來構成一個鏈表,前面學的就是這種哈希指針。而在該圖中還有第二種哈希指針,是指向前面某個交易的指針,用來指明幣的來源。爲什麼要說明幣的來源:證明幣不是憑空捏造的是有記錄的,同時也是防範double spending。

  • 現在來看第二個方框裏A向B的轉賬,該交易需要A的簽名和B的地址。比特幣系統裏收款的地址是通過公鑰推算出來的。比如B的地址就是B的公鑰取哈希然後經過一些轉換得到的。

  • 關於上圖的一些問題
    ①A如何知道B的地址?
    ----比特幣系統中沒有查詢對方地址的功能,必須通過其他渠道。比如某個電商網站,接受比特幣支付,就可以公開它的地址或公鑰。
    ②A需要知道B的地址,B需要知道A的什麼信息嗎?
    ----B其實也要知道A的公鑰,這代表A的身份。不僅是B,所有節點都需要知道A的公鑰。而簽名是用私鑰簽名,公鑰驗證(注意不要跟前面知識弄混了,加密是用接收人的公鑰加密私鑰解密),所以區塊鏈上每個節點都要獨立驗證。
    ③那如何才能知道A的公鑰?
    ----實際上交易裏就包含了。輸入時不僅要輸入幣的來源,還要輸入公鑰。那就存在了安全漏洞,假如B的同夥僞造了這次交易呢?其實第一個方框裏鑄幣交易的輸出就有A的公鑰的哈希,所以第二個方框交易裏A的公鑰要跟前面哈希對的上。
    ④如果有個B’宣稱自己是A,使用A的公鑰發起交易,如何防範?
    ----前面我們講到了,比特幣系統中每個交易都包含輸入(input)和輸出(output)兩部分。輸入部分要說明幣的來源以及支付者公鑰,輸出部分是要給出收款人公鑰的哈希,即第一個框中A的鑄幣交易(coinbase tx)輸出有A公鑰的哈希,如果B’發起轉賬交易,那麼交易中使用的A的公鑰要和前面A的公鑰的哈希要對的上,否則就說明這比交易非法。







  • 在比特幣系統當中,前面這些驗證過程,是通過執行腳本來實現的。每個交易的輸入是一段腳本,包括給出公鑰的過程,公鑰也是在輸入的腳本里指定的。每個交易的輸出也是一段腳本,驗證其的合法性,就需要把當前交易的輸入腳本跟前面交易(提供幣來源的交易)的輸出腳本拼在一起,然後看看能不能順利執行,如果能執行說明是合法的。比特幣腳本(BitCoin Script),後面詳細說明。

  • 該圖對交易系統進行了簡化,實際上每個區塊(對應圖中的每個方框)可以有很多交易,這些交易就組成merkle tree。每個區塊分爲塊頭和塊身。塊頭包含的是區塊的宏觀信息,比如:用的是比特幣哪個版本(version)的協議,區塊鏈當中指向前一個區塊的指針(hash of previous block header),整顆merkle tree 的根哈希值(merkle root hash),還有兩個域是跟挖礦相關的,一個是挖礦的難度目標預值(target),另一個是隨機數nonce。這裏的target,就是前面講到的,整個塊頭的哈希要小於這個預值,即H(block header)≤target。block header裏存的就是這個目標預值的編碼(nBits)。這裏需要注意,前一個區塊的哈希只算的是前一個區塊的塊頭,所以前面畫的,一個區塊引出一個箭頭指向另一個區塊中間,是不正確的,所以有的書箭頭是指向前一個區塊的上面。取哈希時是把塊頭的所有部分都取哈希,這是因爲只有block header纔有哈希指針篡改權。如下圖,其中塊身(block body)裏面有交易列表(transaction list),塊頭中的Merkel root hash就已經能夠保證block body裏面的transaction list不被篡改。在這裏插入圖片描述

(3)前面我們提到,每個節點都需要驗證所有的交易,實際上系統中的節點分全節點(full node)和輕節點(light node),全節點是保存區塊鏈所有的信息的,驗證每一個交易,所以全節點又叫fully validating node。輕節點只保存block header的信息,一般來說輕節點沒法獨立驗證交易的合法性。

  • 比如一個交易是不是double spending,輕節點沒有存以前的交易信息所以它沒法驗證。系統中大多數節點是輕節點,本節內容主要針對全節點,因爲輕節點沒有參與區塊鏈的構造和維護,只是利用了區塊鏈的一些信息做一些查詢。

區塊鏈裏的內容是如何寫到區塊鏈裏面的呢?

  • 每個節點,每個賬戶都可以發佈交易,交易是廣播給所有節點的。有些交易是合法的,有些是非法的。誰來決定哪些交易應該被寫入下一個區塊中呢?按照什麼順序寫呢?如果每個節點自己決定可以嗎?如果每個人在本地維護一個區塊鏈,那區塊鏈的統一性得不到保證,而賬本的內容是要取得分佈式的共識(distributed consensus)。

下面的內容是有關分佈式的,幫助更好理解區塊鏈。

①分佈式的共識一個簡單的例子就是分佈式的哈希表(distributed hash table),比如系統裏有很多臺機器,共同維護一個全局的哈希表。

- 這裏需要取得共識的內容是什麼?
哈希表中包含了哪些鍵值對(key valve pair)。假如有人在自己電腦上插入一個鍵值對,'xiao’這個pair對應的是12345,即’xiao’→12345。那麼別人在另一臺讀的時候也要能把這個讀出來,這就叫一個全局的哈希表。

②關於分佈式系統有很多不可能結論(impossibility result),其中最著名的是FLP。這三個字母是三個專家的名字縮寫,他們的結論是:在一個異步的(asynchronous)系統裏,(網絡傳輸遲延沒有上限就叫異步系統),即使只有一個成員是有問題的(faulty),也不可能取得共識。

③還有一個著名結論:CAP Theorem。(CAP是指分佈式系統的三個我們想要的性質,Consistency【系統狀態的一致性】 Availability【別人都可以用】 Partition tolerance【分區容錯性】)。該理論內容是:任何一個分佈式系統,比如分佈式哈希表,這三個性質中,最多隻能滿足兩個,假如想要前兩個性質,那麼就不會得到第三個性質。

④分佈式共識一個著名的協議是Paxos,該協議能夠保證一致性,即第一個性質。如果該協議打成了共識,那麼這個共識一定是一致的,即每個成員所認爲的共識都是相同的。但是,某些情況下,該協議可能永遠無法達成共識,這種可能性比較小但是客觀存在的。

3.2 比特幣中的共識協議(consensus in BitCoin)

比特幣中的共識協議(consensus in BitCoin):比特幣中共識要解決的一個問題是,有些節點可能是有惡意的。我們假設系統中大多數節點是好的,那麼該如何設計一個共識協議?
(1)第一種方案是投票,首先應該確定哪些區塊有投票權,有些membership是有嚴格要求的,這種情況下基於投票的方案是可行的。但比特幣系統創建賬戶是很容易的,甚至一個人產生了公私鑰對別人都無法得知,只有轉賬時別人才知道。所以有些人可以不停的創建賬戶,當超過賬戶總數的一半時就有了控制權,這種稱爲女巫攻擊(sybil attack)。因此簡單的直接投票方法不可取。
(2)比特幣賬戶巧妙的解決了這個問題,不是按照賬戶數目投票,而是按照計算力來投票。每個節點都可以在本地組裝出一個候選區塊,把它認爲合法的交易放在裏面,然後開始嘗試各種nonce值(佔4 byte),看哪一個能滿足不等式H(block header)≤target的要求。如果某個節點找到了符合要求的nonce,它就獲得了記賬權。

  • 所謂的記賬權,就是往比特幣賬本里寫入下一個區塊的權利。只有找到這個nonce,獲得記賬權的節點纔有權利發佈下一個區塊。其他節點收到這個區塊之後,要驗證這個區塊的合法性。
  • 比如括號裏block header的內容填的對不對;block header裏面有一個域,叫nBits域,實際上它是目標預值的一個編碼檢查一下nBits域設置的是不是符合比特幣協議中規定的難度要求;該不等式是否成立。假設都符合要求,然後檢查block body 裏面的交易列表,驗證一下每個交易都是合法的:①要有合法的簽名 ,②以前沒有被花過。如果有一項不符合要求,這個區塊就是不能被接受的。如果所有條件都符合,也不一定接受(後面詳細解釋)。

(3)假如生成了一個新區塊,怎麼知道新區塊插在了哪裏呢?
根據前一個區塊的指針便可知,可根據hash of prev block header。有可能就存在一個問題,如下圖,這兩個交易指A轉賬給B,以及A轉賬給自己。這種情況不是double spending,判斷一個交易是不是double spending ,是看從當前區塊到幣的來源之間,中間這些區塊有沒有花過這些幣。如圖,從1號區塊到3號和3’區塊,幣都沒有花過,所以這個交易是合法的。雖然該交易是合法的,但是它不在最長合法鏈(longest valid chain)上。這種稱爲分叉攻擊(forking attack)。所以接收的區塊應該是擴展最長合法鏈。
在這裏插入圖片描述

(4)區塊鏈在正常情況下也可能出現分岔:兩個節點同時獲得記賬權。每個節點在本地自己組裝一個它認爲合適的區塊,然後去試各種nonce,如果兩個節點在差不多同一個時間找到了符合要求的nonce,就都可以把區塊發佈,這時會出現兩個等長的分岔。這兩條都是最長合法鏈,那該接受那條呢?比特幣協議當中,在缺省(默認的意思)情況下,每個節點是接受它最早收到的那個。所以不同節點根據在網絡上的位置不同,有的節點先聽到新生成的其中一個區塊,那就接受這個區塊;有些節點先聽到另一個區塊,那就接受另一個區塊。

(5)如何判斷接收了一個區塊?
比特幣協議中用到了implicit consign,如果沿着這個區塊往下繼續擴展,就算認可了這個發佈的區塊。比如在新生成的其中一個區塊後面又拓展一個區塊,表明就認可了這個新區塊。區塊鏈會出現分叉,等長的臨時性的分岔會維持一段時間,直到一個分岔勝出。也就是哪一個鏈搶先一步生成了新的區塊,哪一條就是最長合法鏈。另一個作廢的就叫orphan block。這兩個新區塊有可能會各自拉攏,兩個區塊鏈看誰的算力強,有時候也是看誰的運氣好,就會勝出。

(6)競爭記賬權的好處:首先獲得記賬權的節點本身有一定的權力,可以決定哪些交易寫到下一個區塊裏。但這些不應該被設定爲競爭記賬權的動力,所以巧妙地建立了一個機制:出塊獎勵(block reward)。比特幣協議中規定獲得記賬權的節點在發佈的區塊裏可以有一個特殊的交易:鑄幣交易。在這個交易裏可以發佈一定數量的比特幣。

  • 這裏要回到前面的問題,誰來決定貨幣的發行?
    coinbase transaction鑄幣交易是比特幣系統中發行新的比特幣的唯一方法,後面的交易都是比特幣的轉移。這個交易不用指出幣的來源。

  • 那麼能造多少幣呢?
    開始時比特幣剛上線的時候,每一個發佈的區塊可以產生50BTC(BTC就是比特幣的符號)。協議中規定,21萬個區塊以後,初塊獎勵就要減半,就變成了25BTC。再過21萬個區塊,又要減半。

  • 如果出現了分叉,因此當一個區塊勝出後,另一個作廢的區塊(orphan block)得到的出塊獎勵是沒有作用的,大多數誠實的結點是不會承認的。

(7)本章小結:

  • 比特幣系統中要取得什麼共識?
    去中心化的賬本的內容要取得共識。
  • 誰又能決定賬本的內容呢?
    只有獲得記賬權的節點才能寫東西。
  • 怎麼獲得記賬權呢?
    就是求解一個puzzle,即H(block header)≤target。按照算力投票,算力可以用每秒能試多少nonce值的數目表示,即hash rate。
  • 那怎樣防範女巫攻擊(sybil attack)呢?
    按算力記票,即使創建再多的賬戶,也無法使算力增強。
  • 比特幣爭奪記賬權的過程叫作挖礦(mining),比特幣被稱爲數字黃金(digital gold),爭奪記賬權的節點被稱爲礦工(miner),礦工獲得記賬權就說是挖到礦。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章