比特幣學習筆記——————2、比特幣原理

FLy_鵬程萬里發表於2018-06-12


2.1 交易、區塊、挖礦和區塊鏈

與傳統銀行和支付系統不同,比特幣系統是以去中心化信任為基礎的。由於比特幣網路中不存在中央權威信任機構,“信任”成為了比特幣使用者之間存在的一種突出特性。在本章中,我們將從一個較高層面檢視比特幣,通過追蹤一筆比特幣系統中的單獨交易,來看看它在比特幣分散式共識機制中變得“被信任”和“被接受”的情形,以及最終成功地被儲存到區塊鏈(區塊鏈是一個分散式的公共賬簿,包含所有發生在比特幣系統中的交易)。

書中每一個例子都是比特幣網路中發生的真實交易,通過將資金從一錢包傳送到另一錢包來模擬使用者(Joe、Alice和Bob)間的互動。我們在追蹤一筆通過比特幣網路和區塊鏈的交易時,將用到一些區塊鏈資料庫查詢網站使每個步驟可以方便在網頁上直接被呈現。提供區塊鏈資料查詢的網站就像是一個比特幣的搜尋引擎,你可以搜尋比特幣的地址、交易和區塊,以及可以看他們之間的關係和資金流動。

常見的區塊鏈資料查詢網站包括:

▷ Blockchain info
▷ Bitcoin Block Explorer
▷ insight
▷ blockr Block Reader

以上每一個查詢網站都有搜尋功能,可以通過地址,交易雜湊值或區塊號,搜尋到在比特幣網路和區塊鏈中對應的等價資料。我們將給每個例子提供一個連結,可以直接帶你到相關條目,方便你做詳細研究。

2.1.1 比特幣概述



圖2-1 比特幣概述

如圖2-1所示的概述圖中,我們可以看到比特幣系統由使用者(使用者通過金鑰控制錢包)、交易(每一筆交易都會被廣播到整個比特幣網路)和礦工(通過競爭計算生成在每個節點達成共識的區塊鏈,區塊鏈是一個分散式的公共權威賬簿,包含了比特幣網路發生的所有的交易)組成。在本章中,我們將通過追蹤在網路上傳輸的一筆交易,從整個比特幣系統的的視角檢視各個部分之間的互動。後續章節將詳細闡述錢包、挖礦、商家系統背後的技術細節。

2.1.2 買咖啡

在之前章節裡,Alice是一名剛剛獲得第一枚比特幣的新使用者。在“1.4.2 獲取你的第一枚比特幣 ”一節中,Alice和她的朋友Joe會面時,用現金換取了比特幣。由Joe產生的這筆交易使得Alice的錢包擁有了0.10比特幣。現在Alice將第一次使用比特幣在加利福尼亞州帕羅奧圖的Bob咖啡店買一杯咖啡。Bob咖啡店給他的銷售網點系統新增加了一個比特幣支付選項,價格單上列的是當地貨幣(美元)的售價,但在收銀臺,顧客可以選擇用美元或比特幣支付。此時,Alice點了杯咖啡,然後Bob將交易鍵入到收銀機,之後銷售系統將按照當前市場匯率把美元總價轉換為比特幣,然後同時顯示兩種貨幣的價格,並顯示一個包含這筆交易支付請求的二維碼(如圖2-2所示):


圖2-2

總價:
<br>$1.50 USD
<br>0.0150 BTC

這個二維碼中的URL是:

bitcoin:1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA?
amount=0.015&
label=Bob%27s%20Cafe&
message=Purchase%20at%20Bob%27s%20Cafe

根據BIP0021的定義,此URL的意思是:

A bitcoin address: "1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA"
The payment amount: "0.015"
A label for the recipient address: "Bob's Cafe"
A description for the payment: "Purchase at Bob's Cafe"

與一個簡單包含目的比特幣地址的二維碼不同,當前支付請求的是一個二維編碼過的URL,它包含有一個目的地址,一筆支付金額,和一個像“Bob咖啡”這樣的交易描述。這使比特幣錢包應用在傳送支付請求時,可以預先填好支付用的特定資訊,給使用者顯示一種友好易懂的描述。你可以用比特幣錢包應用掃描這個二維碼來看Alice可能看到的資訊。

Bob說到,“總共1.50美元,或15毫比特幣”

Alice用她的智慧手機掃描了顯示的條形碼。她的智慧手機顯示一筆給Bob咖啡的0.0150比特幣的支付請求,然後她按下傳送鍵授權了這筆支付。在幾秒鐘時間內(大約與信用卡授權所需時間相同)Bob將會在收銀臺看到這筆交易,並完成交易。

在接下來的章節中,我們將更詳細地檢視這筆交易,觀察Alice的錢包是怎樣構建交易,交易又是怎樣在網路中廣播、怎樣被驗證,以及Bob在後續交易中怎樣消費那筆錢。


從千分之一比特幣(1毫比特幣)到一億分之一比特幣(1聰比特幣),比特幣網路可以處理任意小額交易。在本書中,我們將用“比特幣”這個術語來表示任意數量的比特幣貨幣,從最小單元(1聰)到可被挖出的所有比特幣總數(21,000,000)。

2.2 比特幣交易

簡單來說,交易告知全網:比特幣的持有者已授權把比特幣轉帳給其他人。而新持有者能夠再次授權,轉移給該比特幣所有權鏈中的其他人,產生另一筆交易來花掉這些比特幣,後面的持有者在花費比特幣也是用類似的方式。

交易就像複式記賬法賬簿中的行。簡單來說,每一筆交易包含一個或多個“輸入”,輸入是針對一個比特幣賬號的負債。這筆交易的另一面,有一個或多個“輸出”,被當成信用點數記入到比特幣賬戶中。這些輸入和輸出的總額(負債和信用)不需要相等。相反,當輸出累加略少於輸入量時,兩者的差額就代表了一筆隱含的“礦工費”,這也是將交易放進賬簿的礦工所收集到的一筆小額支付。如圖2-3描述的是一筆作為記賬簿記錄的比特幣交易。


圖2-3

交易也包含了每一筆被轉移的比特幣(輸入)的所有權證明,它以所有者的數字簽名形式存在,並可以被任何人獨立驗證。在比特幣術語中,“消費”指的是簽署一筆交易:轉移一筆以前交易的比特幣給以比特幣地址所標識的新所有者。

交易是將錢從交易輸入移至輸出。輸入是指錢幣的來源,通常是之前一筆交易的輸出。交易的輸出則是通過關聯一個金鑰的方式將錢賦予一個新的所有者。目的金鑰被稱為是安全鎖(Encumbrance)。這樣就給資金強加了一個要求:有簽名才能在以後的交易中贖回資金。一筆交易的輸出可以被當做另一筆新交易的輸入,這樣隨著錢從一個地址被移動到另一個地址的同時形成了一條所有權鏈(如圖2-4)。



圖2-4

Alice支付Bob咖啡時使用一筆之前的交易作為輸入。在以前的章節中,Alice從她朋友Joe那裡用現金換了點比特幣。那筆交易有一些比特幣被Alice的金鑰鎖定(阻塞)。在她支付Bob咖啡店的新交易中使用了之前的交易作為輸入,並以支付咖啡和找零作為新的輸出。交易形成了一條鏈,最近交易的輸入對應以前交易的輸出。Alice的金鑰提供瞭解鎖之前交易輸出的簽名,因此向比特幣網路證明她擁有這筆錢。她將咖啡的支付附到Bob的地址上,同時“阻塞”那筆輸出,指明要求是Bob簽名才能消費這筆錢。這就描述了在Alice和Bob之間錢的轉移。上圖展示了從Joe到Alice再到Bob的交易鏈。

2.2.1 常見的交易形式

最常見的交易形式是從一個地址到另一個地址的簡單支付,這種交易也常常包含給支付者的“找零”。一般交易有一個輸入和兩個輸出,如圖2-5所示:


圖2-5

另一種常見的交易形式是集合多個輸入到一個輸出(如圖2-6)的模式。這相當於現實生活中將很多硬幣和紙幣零錢兌換為一個大額面鈔。像這樣的交易有時由錢包應用產生來清理許多在支付過程收到的小數額的找零。


圖2-6

最後,另一種在比特幣賬簿中常見的交易形式是將一個輸入分配給多個輸出,即多個接收者(如圖2-7)的交易。這類交易有時被商業實體用作分配資金,例如給多個僱員發工資的情形。


圖2-7

2.3 交易的構建

Alice的錢包應用知道如何選取合適的輸入和輸出以建立Alice所希望的交易。Alice只需要指定目標地址和金額,其餘的細節錢包應用會在後臺自動完成。很重要的一點是,錢包應用甚至可以在完全離線時建立交易。就像在家裡寫張支票,之後放到信封發給銀行一樣,比特幣交易建立和簽名時不用連線比特幣網路。只有在執行交易時才需要將交易傳送到網路。

2.3.1 獲取正確的輸入

Alice的錢包應用首先要找到一些足夠支付給Bob所需金額的輸入。大多數錢包應用維護著一個含有用錢包自己金鑰鎖定的“未消費交易輸出”小型資料庫。因此Alice的錢包會包含她用現金從Joe那裡購買的比特幣的交易輸出副本(參見在“1.4.2 獲取你的第一枚比特幣 ”一節)。完整客戶端含有整個區塊鏈中所有交易的所有未消費輸出副本。這使得錢包即能拿這些輸出構建交易,又能在收到新交易時很快地驗證其輸入是否正確。然而,完整客戶端佔太大的硬碟空間,所以大多數錢包使用輕量級的客戶端,只儲存使用者自己的未消費輸出。

如果錢包客戶端沒有某一未消費交易輸出,它可以通過不同的服務者提供的各種API或完整索引節點的JSON PRC API從比特幣網路中拿到這一交易資訊。例子2-1展示了用HTTP GET命令對一個特定URL建立了一個RESTful API的請求。這個URL會返回一個地址的所有未消費交易輸出,以提供給需要這些資訊的任何應用作為建立新交易的輸入而進行消費。我們用一個簡單的HTTP命令列客戶端 cURL來獲得這個響應資料。

例2-1 查詢Alice的比特幣地址所有的未消費的輸出

$ curl https://blockchain.info/unspent?active=1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK

例2-2 查詢返回的響應資料

{
  "unspent_outputs": [
    {
      "tx_hash":"186f9f998a5...2836dd734d2804fe65fa35779",
      "tx_index":104810202,
      "tx_output_n":0,
      "script":"76a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac",
      "value":10000000,
      "value_hex":"00989680",
      "confirmations":0
    }
  ]
}

例2-2的響應資料顯示了在Alice的地址 1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK 上面有一個未消費輸出(還未被兌換)。這個響應包含一個交易的索引。而從Joe那裡轉過來的未消費輸入就包含在這個交易裡面,它的價值是一千萬聰(satoshi),即 0.10比特幣。通過這個資訊,Alice的錢包應用就可以建立新的交易將錢轉賬到新地址。

點選檢視Joe和Alice間的交易資訊

如你所見,Alice的錢包在單個未消費的輸出中有足夠的比特幣支付一杯咖啡。假如不夠的話,Alice的錢包應用就不得不搜尋一些小的未消費輸出,像是從一個存錢罐裡找硬幣一樣,直到找到足夠支付咖啡的數量。在兩種情境下,可能都需要找回零錢,而這些找零也會是錢包所建立的交易的輸出組成部分。我們會在下一節會有所描述。

2.3.2 建立交易輸出

交易的輸出會被建立成為一個包含這筆數額的指令碼的形式,只能被引入這個指令碼的一個解答後才能兌換。簡單點說就是,Alice的交易輸出會包含一個指令碼,這個指令碼說 “這個輸出誰能拿出一個簽名和Bob的公開地址匹配上,就支付給誰”。因為只有Bob的錢包的私鑰可以匹配這個地址,所以只有Bob的錢包可以提供這個簽名以兌換這筆輸出。因此Alice會用需要Bob的簽名來包裝一個輸出。

這個交易還會包含第二個輸出。因為Alice的金額是0.10比特幣的輸出形式,對0.015 比特幣一杯的咖啡來說太多了,需要找Alice 0.085比特幣的零錢。Alice錢包建立給她的零錢的支付就在付給Bob的同一個交易裡面。可以說,Alice的錢包將她的金額分成了兩個支付:一個給Bob,一個給自己。她可以在以後的交易裡消費這筆零錢輸出。

最後,為了讓這筆交易儘快地被網路處理,Alice的錢包會多付一小筆費用。這個不是明顯地包含在交易中的;而是通過輸入和輸出的差值所隱含的。如果Alice建立找零時只找 0.0845比特幣,而不是 0.085比特幣的話,這裡就有剩下 0.0005比特幣(50萬聰) 。因為加起來小到 0.10,所以這個 0.10 比特幣的輸入就沒有被完整的消費了。這個差值會就被礦工當作交易費放到區塊的交易裡,最終放進區塊鏈帳薄中。

這個交易的結果資訊可以用區塊鏈資料查詢站點看到,如圖2-8所示。



圖2-8

點選檢視Alice支付Bob咖啡的交易的資訊

2.3.3 將交易放到總賬簿中

這個被Alice錢包應用建立的交易大小為258位元組,包含了金額未來所屬需要的全部資訊。現在,這個交易必須要被傳送到比特幣網路中以成為分散式賬簿(區塊鏈)的一部分。在下一節裡,我們來看下一個交易如何成為新區塊的一部分,以及區塊是如何被挖礦構建的。最後,我們會看看新區塊被加進區塊鏈後,是如何隨更多區塊的新增而增加可信度的。

2.3.3.1 交易的傳送

因為這個交易包含處理所需的所有資訊,所以這個交易是被如何或從哪裡傳送到比特幣網路的就無所謂了。比特幣網路是由參與的比特幣客戶端聯接幾個其他比特幣客戶端組成的P2P網路。比特幣網路的目的是將交易和區塊傳播給所有參與者。

2.3.3.2 如何傳播

Alice的錢包應用可以傳送新的交易給其它任意一個已聯接到網際網路的比特幣客戶端,不論其是由有線網、WiFi、還是通過手機聯接的。她的錢包不必直接連著Bob的比特幣錢包,且她不必使用咖啡廳提供的網路聯網,雖然這兩者都是可能的。任何比特幣網路節點(其它客戶端)收到一個之前沒見過的有效交易時會立刻將它轉發給聯接到自身的其它節點。因此,這個交易迅速地從P2P網路中傳播開來,幾秒內就能到達大多數節點。

2.3.3.3 Bob的視角

如果Bob的比特幣錢包應用是直接連線Alice的錢包應用的話,Bob的錢包應用也許就是第一個收到這個交易的節點。然而,即使Alice的交易是從通過其它節點發過來的,一樣可以在幾秒鐘內到達Bob錢包應用這裡。Bob的錢包會立即確認Alice的交易是一個收入支付,因為它包含能用Bob的私鑰兌換的輸出。Bob的錢包應用也能夠獨立地用之前未消費輸入來確認這個交易是正確構建的,並且由於包含足夠交易費會被下一個區塊包含進去。這時Bob就可以以一個很小的風險假定這個交易會很快被加到區塊且被確認。

一個對比特幣交易的常見誤解是它們必須要等10分鐘後被確認加進一個新區塊,或等60分鐘以得到六次確認後才是有效的。雖然這些確認可以確保交易已被整個網路接受,但對於像一杯咖啡這樣的小額商品來說就沒有必要等待那麼長時間了。一個商家可以免確認來接受比特幣小額支付。這樣做的風險不比接受一個不是用有效身份證領取或沒有簽名的信用卡的風險更大,而後者是現在商家常做的事情。

2.4 比特幣挖礦

這個交易現在在比特幣網路上傳播開來。但只有被一個稱為挖礦的過程驗證且加到一個區塊中之後,這個交易才會成為這個共享賬簿(區塊鏈)的一部分。關於挖礦的詳細描述請見第8章

比特幣系統的信任是建立在計算的基礎上的。交易被包在一起放進區塊中時需要極大的計算量來證明,但只需少量計算就能驗證它們已被證明。挖礦在比特幣系統中起著兩個作用:

▷ 挖礦在構建區塊時會創造新的比特幣,和一箇中央銀行印發新的紙幣很類似。每個區塊創造的比特幣數量是固定的,隨時間會漸漸減少。

▷ 挖礦建立信任。挖礦確保只有在包含交易的區塊上貢獻了足夠的計算量後,這些交易才被確認。區塊越多,花費的計算量越大,意味著更多的信任。

描述挖礦的一個好方法是將之類比為一個巨大的多人數獨謎題遊戲。一旦有人發現正解之後,這個數獨遊戲會自動調整困難度以使遊戲每次需要大約10分鐘解決。想象一個有幾千行幾千列的巨大數獨遊戲。如果給你一個已經完成的數獨,你可以很快地驗證它。然而,如果這個數獨只有幾個方格里有數字其餘方格都為空的話,就會花費非常長的時間來解決。這個數獨遊戲的困難度可以通過改變其大小(更多或更少行列)來調整,但即使它非常大時驗證它也是相當容易的。而比特幣中的 "謎題" 是基於雜湊加密演算法的,其展現了相似的特性:非對稱地,它解起來困難而驗證很容易,並且它的困難度可以調整。

在 “1.3 比特幣的應用、使用者和他們的故事”一節中,我們提到了一個叫Jing的在上海學計算機工程的學生。Jing在比特幣網路中扮演了一個礦工的角色。大概每10分鐘,Jing和其他上千個礦工一起展開一場對一個區塊的交易尋找正解的全球競賽。為尋找這個解,也被稱為工作量證明,整個網路需要具有每秒億萬次雜湊計算的能力。這個工作量證明演算法指的用SHA256加密演算法不斷地對區塊頭和一個隨機數字進行雜湊計算,直到出現一個和預設值相匹配的解。第一個找到這個解的礦工會贏得這局競賽並會將此區塊釋出到區塊鏈中。

Jing從2010年開始挖礦,當時他使用一個非常快的桌面電腦來為新區塊尋找正解。隨著更多的礦工加入比特幣網路中,尋找謎題正解的困難度迅速增大。不久,Jing和其他礦工升級成更專業的硬體,比如遊戲桌面電腦或控制檯專用的高階獨享影像處理單元晶片(即顯示卡GPU)。在寫這本書的時候,解題已經變得極其困難,只有使用整合了幾百個挖礦專用演算法硬體並能同時在一個單獨晶片上並行工作的專用積體電路(ASIC)挖礦才會營利。Jing同時加入了一個類似彩票獎池的、能夠讓多個礦工共享計算力和報酬的礦池。Jing現在執行兩個通過USB聯接的ASIC機器每天24小時不間斷地挖礦。他賣掉一些挖礦所得到的比特幣來支付電費,並可以通過營利獲得一些收入。作為專用挖礦軟體的後臺,他的計算機裡安裝了一個比特幣索引客戶端,名稱為bitcoind。

2.5 區塊中的挖礦交易記錄

網路中產生的一筆交易直到成為整個比特幣大賬簿——區塊鏈的一部分時才會被確認有效。平均每10分鐘,礦工會將自上一個區塊以來發生的所有交易生成一個新的區塊。新交易不斷地從使用者錢包和應用流入比特幣網路。當比特幣網路上的節點看到這些交易時,會先將它們放到各自節點維護的一個臨時的未經驗證的交易池中。當礦工構建一個新區塊時,會將這些交易從這個交易池中拿出來放到這個新區塊中,然後通過嘗試解決一個非常困難的問題(也叫工作量證明)以證明這個新區塊的合法性。挖礦過程的細節會在“8.1 簡介”一節中詳加描述。

這些交易被加進新區塊時,以交易費用高的優先以及其它的一些規則進行排序。礦工一旦從網路上收到一個新區塊時,會意識到在這個區塊上的解題競賽已經輸掉了,會馬上開始下一個新區塊的挖掘工作。它會立刻將一些交易和這個新區塊的數字指紋放在一起開始構建下一個新區塊,並開始給它計算工作量證明。每個礦工會在他的區塊中包含一個特殊的交易,將新生成的比特幣(當前每區塊為25比特幣)作為報酬支付到他自己的比特幣地址。如果他找到了使得新區塊有效的解法,他就會得到這筆報酬,因為這個新區塊被加入到了總區塊鏈中,他新增的這筆報酬交易也會變成可消費的。參與礦池的Jing設定了他的軟體,使得構建新區塊時會將報酬地址設為礦池的地址。然後根據各自上一輪貢獻的工作量將所得的報酬分給Jing和其他參與礦池挖礦的礦工。

Alice的交易被網路拿到後放進未驗證交易池中。因為包含足夠的交易費,它被Jing的礦池放到了生成的新區塊中。大約在Alice的錢包第一次將這個交易傳送出來五分鐘後,Jing的ASIC礦機發現了新區塊的正解並將之釋出為第277,316號區塊,包含419個其它交易。Jing的ASIC礦機將這個新區塊釋出到網路上後,其它礦機就會驗證它,並投身到構建新區塊的競賽中。

你可以檢視包含Alice交易記錄的這個區塊的資訊。

幾分鐘後,第277,317號新區塊誕生在另一個挖礦節點中。因為這個新區塊是基於包含Alice交易的第277,316號區塊的,在這個區塊的基礎上增加了更多的計算,因此就加強了這些交易的可信度。包含Alice交易的區塊對這個交易來說算一次"證明"。基於這個區塊每產生一個新區塊,對這個交易來說就會增加了一次"證明"。當區塊一個個堆上來時,這個交易變得指數級地越來越難被推翻,因此它在網路中得到更多信任。


圖2-9

在圖2-9中,我們可以看到包含Alice的交易的第277,316號區塊。在它之下有377,361個區塊(包括0號區塊),像鏈子一樣一個連著一個(區塊鏈),一直連到0號區塊,即創世區塊。隨著時間變長,這個區塊鏈的高度也隨之增長,每個區塊和整個鏈的計算複雜度也隨之增加。包含Alice的交易的區塊後面形成的新區塊使得信任度進一步增加,因為他們疊加了更多的計算在這個越來越長的鏈子上。按慣例來說,一個區塊獲得六次以上“證明”時就被認為是不可撤銷的了,因為要撤銷和重建六個區塊需要巨量的計算。在第8章我們會詳細描述挖礦和信任建立的過程。

2.6 消費這筆交易

既然Alice的這筆交易已經成為區塊的一部分被嵌入到了區塊鏈中,它就成為了整個分散式比特幣賬簿的一部分並對所有比特幣客戶端應用可見。每個比特幣客戶端都能獨立地驗證這筆交易是有效且可消費的。全索引客戶端可以追錢款的來源,從第一次有比特幣在區塊裡生成的那一刻開始,按交易與交易間的關係順藤摸瓜,直到Bob的交易地址。輕量級客戶端通過確認一個交易在區塊鏈中且在它後面有幾個新區塊來確認一個支付的合法性。這種方式叫做簡易支付驗證(參見“6.7 簡易支付驗證(SPV)節點”)。

Bob現在可以將此交易和其它交易的結果資訊作為輸入,建立新的所有權為其他人的交易。這樣就實現了對此交易的消費。舉個例子,Bob可以用Alice支付咖啡的比特幣轉賬給承包商或供應商以支付相應費用。大多數情況下,Bob用的比特幣商戶端會將多個小額支付聚合成一個大的支付,也許會將一整天的比特幣收入聚合成一個交易。這樣會將多個支付合成到咖啡店財務賬戶的一個單獨地址。圖2-6為交易集合示例。

當Bob花費從Alice和其他顧客那裡賺得的比特幣時,他就擴充套件了比特幣的交易鏈條。而這個鏈條會被加到整個區塊鏈賬簿,使所有人知曉並信任。我們假定Bob向在邦加羅爾的網站設計師Gopesh支付一個新網頁的設計費用。那麼區塊交易鏈會如圖2-10所示。


圖2-10


相關文章