2.3 比特幣區塊鏈的運作方式
比特幣區塊鏈是第一個成功的區塊鏈項目,其運作方式與傳統的支付系統完全不同。本章將通過介紹比特幣網絡和區塊鏈的交易流程及運作方式,展示交易在比特幣分布式共識機制中“被信任”和“被接受”的過程,以及如何成功地被存儲在區塊鏈中。
2.3.1 區塊鏈如何運作
比特幣區塊鏈的運作并不復雜,共涉及3個概念:首先是交易,每一次對賬本的操作都會導致賬本狀態的改變;其次是區塊,每記錄一段時間內發生的所有交易和狀態結果,都是對當前賬本狀態的一次共識;最后是鏈,區塊是按照發生時間順序串聯起來的,是整個賬本狀態變化的精確日志記錄。
在運行中,先假設存在一個分布式記賬的賬本,在這個賬本中只允許添加,不允許刪改,賬本的基本結構是一個線性的鏈表,鏈表由一個個“區塊”串聯而成,后繼區塊記錄前導區塊的哈希值,當加入新數據時,必須放到一個新的區塊內,而這個塊中的交易是否合法,要通過計算哈希值的方式快速檢驗出來,任何一個節點都可以提議建立新的區塊,但是必須通過一定的共識機制來對最終選擇的區塊達成一致。
舉個簡單的例子來解釋一下區塊鏈的運行機制,這個過程主要分三步:
第一步是賬本公開,我們把區塊鏈假設成一個封閉的區域,這個區域中的每戶人家都是區塊鏈上的一個節點,每個節點都擁有記載著這個區域每一筆交易的賬本,而且這個賬本是公開的。只要這個賬本的初始狀態是確定的,并且每一筆交易的記錄都是可靠而有序的,當前每個人持有的錢都是可以推算出來的。
但是,參與的用戶必然不想讓區域內所有人知道自己到底有多少錢。因此,在區塊鏈中交易是公開的,但是參與的每個節點都是匿名的。節點之間不使用真實身份進行交易,而使用自己的唯一ID。當兩個節點發生交易之后,交易的報文中會顯示此ID的數字簽名,以確保交易是在雙方之間展開的。
第二步是身份簽名。假設在這個區域中老李和老王是區塊鏈中的兩個節點,老李的ID名為BLOCK,老王的ID名為CHAIN。如果老李要向老王支付1比特幣,那么老李首先要詢問老王的ID,這時區塊鏈中就會產生一個交易:BLOCK要向CHAIN支付1比特幣,于是老李要寫一張交易單給老王。
在區塊鏈中,為了追溯資金的來源,在這個交易單上除了記載付款和收款信息,還要寫上比特幣的來源信息,如這個比特幣來源于賬本第一頁。交易單寫完后,老李還要加上自己的簽名,即私鑰加密,以便老王驗證比特幣的來源。老王收到簽名后,會有老李的ID對其進行簽名驗證,以證明交易單是老李發的,如圖2-1所示。

圖2-1 老李老王的交易過程
第三步是礦工挖礦。在一個傳統中心化的系統中,老李是否有足夠的錢支付給老王,這個過程要通過第三方中介機構(如銀行)來確定。而在區塊鏈系統中,做這個工作的是礦工組織。
當老李給老王發送交易單時,他們兩個的交易信息會廣播給礦工組織,而礦工組織的每個礦工小組收到交易信息后,就負責把交易補充到賬本中去。
礦工小組的具體工作就是生成賬單,如圖2-2所示。當礦工小組收到老李和老王的交易信息時,在交易清單上記錄上這個交易,接著礦工小組的成員找到當前賬本的最后一頁,將編號抄寫在“上一賬單編號”一欄中。隨后礦工小組的成員會把交易清單、上一賬單編號及隨機數通過哈希運算,生成一個本賬單編號。由于交易清單和上一交易編號是不能改變的,因此,礦工小組成員必須不斷變化隨機數值來生成符合規定的賬單編號。

圖2-2 礦工小組生成賬單
此外,區塊鏈會自動調整賬單編號規則,使其在10分鐘之內生成。礦工小組得到一張賬本紙(區塊)以后,必須馬上向其他小組確認自己的工作成果才能得到獎勵。
其他小組在接到賬本紙后,必須立刻停下挖礦工作,對賬本進行確認。首先將送來的賬本紙放入編碼生成器中,來確認賬本編號是否有效。然后將賬本紙上的“上一頁賬單編號”和這個小組目前保存的有效賬本最后一頁進行編號比對,如果相同,則確認;如果不同,則需要順著已有賬本向前比對,直到找到這個編號的賬本紙;如果沒有找到,則這個小組會將此頁丟掉,不予確認。最后還要確認當前每筆交易的付款人有足夠的余額支付這筆錢,來保證交易清單的有效性。當完成了所有驗證并通過后,這個小組就認可了其他小組發來的賬本紙有效。
其他小組確認該區塊有效以后,這個區塊就會進入主賬本,后面的挖礦工作就會再基于這個更新之后的賬本進行。
對于這個礦工小組來說,如果后面收到其他小組送來的賬本紙中的“上一賬單編號”是自己以前送去的賬單,那么就表示已經有小組是基于他們交完賬單以后新生成的主賬本工作了,這就表示他們的工作被其他小組認可,而老李和老王看到大多數小組認可,就認為這個交易已經成功。
總結一下,在區塊鏈中比特幣的交易過程如下:
A利用自己的私鑰對比特幣的來源和下一位所有者B簽署一個數字簽名,并將簽名附在交易單后面。
這個交易單通過P2P網絡傳播到了全網,B和礦工組織都會收到這張交易單;礦工組織通過哈希運算,解出對應的隨機數,生成符合條件的哈希值,然后去爭取創建新區塊并獲得比特幣獎勵。
礦工節點找到解時,會向全網通告該區塊記錄的蓋有時間戳的交易,并由其他節點核對。
當其他節點核對區塊確認無誤后,他們就會將該區塊認定為合法,然后去爭取下一個區塊,這樣就形成了一個合法記賬的區塊鏈。
2.3.2 雙重支付如何解決
雙重支付是什么呢?它是同一筆錢(數字貨幣)被重復支付兩次。仍以上文區塊鏈為例,除了老李和老王是區塊鏈中的兩個節點,又增加了老張節點。如果老李寫一個單子并加上自己的簽名,付給老王之后,他又復制了這個單子和自己的簽名給了另外一個人老張。老王和老張確認了老李的簽名正確后都認為自己收到了這筆錢,這個過程就產生了雙重支付的問題。
雙重支付問題在物理貨幣世界并不現實,因為黃金、白銀無法復制。如果是紙幣的話,簽上名交付對方之后,就無法再次使用了(無法同時再將此票據給他人)。在傳統電子貨幣世界中,通過每次將使用過的電子貨幣返回貨幣發行機關,發行機關對返回的電子貨幣進行確認,再發行同等金額的新電子貨幣來避免雙重支付。這就造成了整個金融體系完全依賴發行機關來運行,而且每一次交易都必須經過發行機關。這意味著所有節點的所有交易都必須經過一個中心網絡來監控并強制阻止雙重支付。但是這樣既不能徹底解決雙重支付問題(避免復制數字貨幣的行為),也避免不了交易中介糾紛和交易成本增加等問題。
那么,比特幣是如何解決雙重支付問題的呢?
我們知道比特幣付款人(如老李)會對前一次的交易和下一位擁有者(老王或者老張)的公鑰簽署一個數字簽名,將這個簽名附加在比特幣的末尾發送給下一位所有者(老王或者老張)。由于沒有第三方機構去進行監控,所以,需要一個機制去確保比特幣之前的所有者沒有對更早發生的交易實施簽名。
這個機制就是歷史交易經過全網公認、面向全網公開的共識機制,它包括的內容如下:
(1)所有節點的歷史交易全網公開,每個賬號中有多少比特幣,并不是由一個數據來表示的,而是根據歷史交易得出來的。這個歷史交易鏈是經過全網公認的唯一的合法交易,這樣收款人因為擁有全網公認的作為第一位收到該比特幣的交易歷史證據,從而避免了雙重支付的風險,付款人也因為全網公開交易的歷史記錄而避免雙重支付的行為。
(2)每筆交易都有時間戳(Timestamp),所有交易具有時間先后順序,每一筆交易數據在一個精確特定的時間點發生。當前面一筆交易成功在整個交易鏈被公認后,下一筆交易就基于上一筆交易生成,整個交易就是一個具有精確時間順序信息的交易鏈。
(3)每筆交易都需要投入計算資源來確認,比特幣采用工作量證明(Proof of Work)機制,由礦工投入計算力打包交易,如果有人想篡改某個區塊上的交易,需重新計算歷史的全部區塊,這樣的算力在數學上是不可能的。因此,這個大多數節點公認的交易記錄鏈無法被篡改。
整個比特幣系統中的每一個節點都會獲知每一筆交易的發生,并形成具有精確時間順序信息的歷史交易鏈,全網公認這筆交易是首次出現時,這筆交易才能發生。礦工通過貢獻算力把每筆交易加入不可篡改的公共賬本中,并獲得挖礦獎勵。比特幣就是通過這種巧妙的方式,解決了雙重支付問題和拜占庭將軍問題。