與傳統的銀行和支付系統不同,比特幣系統基於去中心化的信任。在比特幣中,信任是透過比特幣系統中不同參與者互動的湧現特性達成的。在本章中,我們將站在比較高的視角研究比特幣,透過在比特幣系統中追蹤一筆交易,看到它被比特幣分散式共識機制所信任和接受,並最終記錄在區塊鏈中(所有交易的分散式帳簿)。後續章節將深入探討交易,網路和挖礦背後的技術。
在 Bitcoin overview 的概覽圖中, 我們看到比特幣系統由包含金鑰的錢包,透過網路傳播的交易,以及產生(透過競爭性計算)共識區塊鏈的礦工組成,區塊鏈是所有交易的權威帳本。
本章中的每個範例均基於在比特幣網路上進行的實際交易,透過從一個錢包向另一個錢包傳送資金來模擬使用者(Joe, Alice, Bob 和 Gopesh)之間的互動。在透過比特幣網路追蹤交易到區塊鏈的同時,我們將使用 Blockchain Explorer 網站視覺化每個步驟。區塊鏈瀏覽器 ( Blockchain Explorer ) 是一個作為比特幣搜尋引擎執行的 Web 應用,它允許你搜尋地址、交易和區塊,並檢視它們之間的關係和流程。
流行的區塊鏈瀏覽器包括:
其中每一個都有搜尋功能,可以採用比特幣地址,交易雜湊值,區塊號或區塊雜湊值,從比特幣網路中檢索相應的資訊。對於每個交易或區塊範例,我們將提供一個URL,以便你可以自己檢視並詳細研究它。
上一章介紹的 Alice 是剛剛獲得了第一個比特幣的新使用者。在 [getting_first_bitcoin] 中,Alice 會見了她的朋友 Joe,用現金交換了一些比特幣。Joe 創造的交易把 0.10BTC 傳送到了 Alice 的錢包。現在,Alice 將進行她的第一筆零售交易,在加利福尼亞州帕洛阿爾託的 Bob 咖啡店購買一杯咖啡。
Bob 咖啡最近開始接受比特幣支付,在其銷售系統中增加了一個比特幣選項。Bob 咖啡的價格以當地貨幣(美元)列出,但在支付時,顧客可以選擇美元或比特幣。Alice 下了一杯咖啡的訂單,Bob 將它輸入到系統中,就像處理所有交易一樣。銷售系統自動將總價從美元轉換為比特幣,並以當前市場匯率以兩種貨幣進行顯示:
Total: $1.50 USD 0.015 BTC
Bob 說:「1.5美元,或者 15 mBTC (毫比特幣)」
Bob 的銷售系統也會自動建立一個包含 支付請求(Payment Request) 的特殊 QRCode(參見Payment request QR code)。
與僅包含目標比特幣地址的 QRCode 不同,支付請求是 URL 的 QRCode,其包含目標地址,付款金額以及諸如 "Bob’s Cafe" 的描述。這允許比特幣錢包應用預先填充用於傳送付款的資訊,同時向用戶顯示可讀的資訊。你可以使用比特幣錢包應用掃描 QRCode,以檢視 Alice 會看到的內容。
Tip
|
嘗試用錢包掃描以檢視地址和金額,但不要傳送金錢。 |
bitcoin:1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA? amount=0.015& label=Bob%27s%20Cafe& message=Purchase%20at%20Bob%27s%20Cafe URL的組成部分 接收比特幣的地址: "1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA" 支付金額: "0.015" 收件人地址的標籤: "Bob's Cafe" 支付詳情: "Purchase at Bob's Cafe"
Alice 用她的手機掃描螢幕上的QRCode。她的手機顯示支付 0.0150 BTC 至 Bob's Cafe,她選擇“傳送”以授權付款。在幾秒鐘內(大約與信用卡授權相同的時間),Bob在他的系統中看到交易,交易就完成了。
Note
|
比特幣網路可以以小數值進行交易,例如從 millibitcoin (mBTC) ( 比特幣的 1/1000 ) 到 聰 ( 比特幣的 1 / 100,000,000 )。在本書中,我們將使用術語“比特幣”來表示從最小單位(1 satoshi)到將要開採的所有比特幣總數(21,000,000)的任何數量的比特幣。 |
你可以使用區塊鏈瀏覽器網站(檢視 Alice 的交易 blockchain.info)在區塊鏈中檢查 Alice 對 Bob’s Cafe 的交易:
https://blockchain.info/tx/0627052b6f28912f2703066a912ea577f2ce4da4caa5a5fbd8a57286c345c2f2
簡而言之,一筆交易告訴網路,一些比特幣價值的擁有者已經授權將該價值轉移給另一個擁有者。新的擁有者現在可以透過建立另一個授權轉讓給另一個擁有者的交易來支付比特幣等等。
交易就像複式簿記帳中的行一樣。每筆交易包含一個或多個“輸入”,就像比特幣帳戶的"借方",在交易的另一端,有一個或多個“輸出”,就像比特幣帳戶中的"貸方"一樣。 輸入和輸出(借方和貸方)加起來不一定數額相同。相反,輸出加起來略少於輸入,差額代表隱含的 交易費用,這是由礦工收取的一筆小額付款,該礦工將交易加入到帳簿中。比特幣交易在 Transaction as double-entry bookkeeping 中顯示為帳簿中的記錄條目。
該交易還包含每個正在被花費的比特幣(輸入)的所有權證明,以擁有者的數位簽章的形式出現,任何人都可以獨立驗證。用比特幣的術語來說,“花費”正在簽署一項交易,它將來自前一筆交易的價值轉移給由比特幣地址標識的新擁有者。
Alice向Bob’s Cafe的付款使用先前交易的輸出作為其輸入。在上一章中,Alice從她的朋友Joe那裡用現金換取了比特幣。該交易建立了一個由Alice的金鑰鎖定的比特幣值。她向Bob’s Cafe的新交易參考之前的交易作為輸入,並創造新的輸出來支付咖啡錢並接收找零。交易形成一個鏈,最近一次交易的輸入與之前交易的輸出相對應。Alice的金鑰提供瞭解鎖先前那些交易輸出的簽名,從而向比特幣網路證明她擁有資金。她將咖啡的錢支付給Bob的地址,從而“留置”輸出,要求Bob必須簽名才能花費這筆金額。這代表了Alice和Bob之間的價值轉移。這個從Joe到Alice到Bob的交易鏈在A chain of transactions, where the output of one transaction is the input of the next transaction中進行了說明。
許多比特幣交易的輸出既參考新擁有者的地址,又參考當前擁有者的地址(這稱為 找零 地址)。這是因為交易輸入(像鈔票一樣)不能分開。如果你在商店購買價值5美元的物品,但使用20美元的美元帳單來支付該物品,你將獲得15美元的找零。相同的概念適用於比特幣交易的輸入。如果你購買的產品需要5比特幣,但只有20比特幣的輸入能使用,你可以將一個5比特幣的輸出傳送給店主,並將一個15比特幣輸出作為找零(減去涉及的交易費用)。重要的是,找零地址不必與輸入地址相同,並且出於隱私方面考慮,通常是來自擁有者錢包的新地址。
在彙集輸入以執行使用者的支付請求時,不同的錢包可以使用不同的策略。他們可能會彙集很多小的輸入,或者使用等於或大於期望付款的輸入。除非錢包能夠按照付款和交易費用的總額精確彙集輸入,否則錢包將需要產生一些零錢。這與人們處理現金非常相似。如果你總是使用口袋裡最大的鈔票,那麼最終你會得到一個充滿零錢的口袋。如果你只使用零錢,你將永遠只有大額帳單。人們潛意識地在這兩個極端之間尋找平衡點,比特幣錢包開發者努力程式設計實現這種平衡。
總之, 交易 將 交易的輸入 的值移至 交易的輸出。輸入是對前一個交易輸出的參考,表示值來自哪裡。交易輸出將特定值指向新擁有者的比特幣地址,並且可以將零錢輸出給原始擁有者。來自一個交易的輸出可以用作新交易的輸入,因此當價值從一個擁有者轉移到另一個擁有者時會產生一個 所有權鏈 (參見 A chain of transactions, where the output of one transaction is the input of the next transaction)。
最常見的交易形式是從一個地址到另一個地址的簡單支付,通常包括一些“零錢”返回到原始擁有者。這類別交易有一個輸入和兩個輸出,參見 Most common transaction:
另一種常見形式是彙集多個輸入到一個輸出的交易 (參見 Transaction aggregating funds)。這類似於現實世界中將一堆硬幣和紙幣換成單一較大面值的紙幣的情況。此類別交易有時由錢包應用產生,以清理收到的大量小額零錢。
最後,比特幣帳簿中經常出現的另一種交易形式是將一個輸入分配給代表多個收款人的多個輸出的交易(參見 Transaction distributing funds)。這類別交易有時被企業用來分配資金,例如在向多個僱員支付工資時。
Alice 的錢包應用包含了選擇合適的輸入和輸出的所有邏輯,根據Alice的具體設定建立交易。Alice 只需要指定目的地和金額,剩下的事情交給錢包應用,Alice 不用關心細節。重要的是,即使錢包應用完全離線,錢包應用也可以建立交易。就像在家裡寫一張支票,然後透過信封傳送給銀行一樣,交易不要求在連線到比特幣網路時進行建立和簽署。
Alice 的錢包應用首先必須找到可以支付她想要傳送給 Bob 的金額的輸入。大多數錢包追蹤屬於錢包中地址的所有可用輸出。因此,Alice 的錢包將包含 Joe 的交易輸出的副本,該交易是由現金交換建立的 (參見 [getting_first_bitcoin])。作為完整節點客戶端執行的比特幣錢包應用實際上包含區塊鏈中每筆交易的未使用輸出的副本。這允許錢包建立交易輸入,以及快速驗證傳入的交易具有正確的輸入。但是,由於全節點客戶端佔用大量磁碟空間,所以大多數使用者錢包執行“輕量級”客戶端,僅追蹤使用者自己未使用的輸出。
如果錢包應用未儲存未花費的交易的輸出的副本,它可以使用不同提供商提供的各種 API,查詢比特幣網路,詢問完整節點來檢索該資訊。Look up all the unspent outputs for Alice’s bitcoin address 展示了一個 API 請求,向特定的 URL 發起 HTTP GET 請求。該 URL 將返回這個地址上所有未使用的交易的輸出,為應用提供建構交易輸入的資訊。我們使用簡單的命令列 HTTP 客戶端 cURL 來請求。
$ curl https://blockchain.info/unspent?active=1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK
{
"unspent_outputs":[
{
"tx_hash":"186f9f998a5...2836dd734d2804fe65fa35779",
"tx_index":104810202,
"tx_output_n": 0,
"script":"76a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac",
"value": 10000000,
"value_hex": "00989680",
"confirmations":0
}
]
}
Look up all the unspent outputs for Alice’s bitcoin address中的響應展示了在Alice的地址 1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK 下有一筆未花費的輸出。響應內容包括包含這筆輸出的交易的參考,以及它的價值,1000萬(單位是聰),相當於0.10比特幣,利用這些資訊,Alice的錢包應用可以建構一個交易,將該值轉移到新的擁有者地址。
Tip
|
如你所見,Alice 的錢包包含支付一杯咖啡的足夠的比特幣。否則,Alice的錢包應用可能需要"翻遍"一堆較小的未使用的輸出,就像從錢包中找硬幣一樣,直到它能夠找到足夠的錢來支付咖啡。在這兩種情況下,可能都需要進行一些找零,我們將在下一部分中看到,錢包應用建立交易輸出(付款)。
交易的輸出是以指令碼形式建立的,該指令碼在比特幣價值上建立了一個“留置”,只能透過提供指令碼解決方案來進行提取。簡而言之,Alice的交易輸出將包含一個指令碼,其內容如下:“這筆支出屬於能使用Bob的公共地址對應的私鑰進行簽名的人。” 因為只有Bob擁有與該地址對應的私鑰,所以只有Bob的錢包可以提供這樣的簽名來提取該輸出。因此,Alice可以透過要求Bob的簽名,來“限制”這筆輸出的使用。
這筆交易還包括第二筆輸出,因為 Alice 的資金為0.10BTC,對於0.015BTC的咖啡來說太多了,需要找零0.085BTC。Alice的找零付款由Alice的錢包建立,作為Bob的付款的同一筆交易中的輸出。Alice 的錢包將其資金分成兩筆付款:一筆給Bob,一份給自己。然後,她可以在後續交易中使用(花費)這次找零的輸出。
最後,為了讓網路及時處理這筆交易,Alice的錢包應用將增加一筆小額費用。這在交易中並不明確;這是由輸入和輸出的差值隱形包含的。如果Alice不建立0.085的找零,而是0.0845,就會剩下0.0005BTC(半毫比特幣)。輸入的0.10BTC沒有完全用於兩個輸出,因為它們的總和小於0.10。由此產生的差值就是礦工收取的_交易費用_,用於驗證交易並將交易包括到區塊鏈中。
產生的交易可以使用區塊鏈瀏覽器檢視,如 Alice’s transaction to Bob’s Cafe 所示。
Alice的錢包應用建立的交易長度為258個位元組,包含確認資金所有權和分配新的擁有者所需的所有內容。現在,交易必須傳輸到比特幣網路,併成為區塊鏈的一部分。在下一節中,我們將看到交易如何成為新區塊的一部分,以及區塊如何被“挖掘”。最後,我們將看到當區塊加入區塊鏈後,會隨著區塊的增加越來越被網路信任。
交易包含了處理所需的所有資訊,因此傳送到比特幣網路的方式或位置無關緊要。比特幣網路是一個點對點網路,每個比特幣客戶端透過連線到其他幾個比特幣客戶端來參與。比特幣網路的目的是向所有參與者傳播交易和區塊。
任何遵守比特幣協議,加入到比特幣網路的系統,如伺服器,桌面應用程式或錢包,都稱為_比特幣節點(bitcoin node)_。Alice的錢包應用可以透過任何型別的連線(有線,WiFi,移動等)將相關交易傳送到任何比特幣節點。她的比特幣錢包不必直接連線到Bob的比特幣錢包,她不必使用咖啡館提供的網際網路連線,但這兩種選擇都是可能的。任何比特幣節點接收到一個它沒見過的有效交易之後,會立即轉發到它連線到的所有其他節點,這被稱為_泛洪(flooding)_傳播技術。因此,交易在點對點網路中迅速傳播,可在幾秒鐘內達到大部分節點。
如果Bob的比特幣錢包應用直接連線到Alice的錢包應用,則Bob的錢包應用可能是第一個接收到該交易的節點。即使Alice的錢包透過其他節點發送交易,它也會在幾秒鐘內到達Bob的錢包。Bob的錢包會立即將Alice的交易識別為收款,因為它包含可由Bob的私鑰提取的輸出。Bob的錢包應用還可以獨立驗證交易資料是格式正確的,使用的是之前未花費的輸入,並且包含足夠的交易費用以包含在下一個區塊中。此時,鮑勃可以認為風險很小,即交易將很快包含在一個區塊中並得到確認。
Tip
|
關於比特幣交易的一個常見誤解是,它們必須等待10分鐘新區塊的產生才能被“確認”,或者最多60分鐘才能完成6個確認。雖然確認確保交易已被整個網路所接受,但對於諸如一杯咖啡等小值物品,這種延遲是不必要的。商家可以接受沒有確認的有效小額交易。沒有比沒有身份或簽名的信用卡支付風險更大的了,商家現在也經常接受。 |
Alice的交易現在已經傳播到比特幣網路上了。但在它被驗證並經歷一個名為 挖礦(mining) 的過程包含在區塊中之前,不會成為 區塊鏈 的一部分。有關詳細說明,請參閱[mining]。
比特幣的信任系統基於計算。交易被捆綁到 區塊 中,這需要大量的計算來提供工作證明,但只需少量的計算進行驗證。挖礦過程在比特幣中有兩個作用:
-
挖礦節點透過遵從比特幣的 共識規則 來驗證所有交易。因此,挖礦透過拒絕無效或格式錯誤的交易來為比特幣交易提供安全保障。
-
每個區塊被挖出時會創造新的比特幣,就像中央銀行印錢一樣。按照固定的發行時間表,每個區塊建立的比特幣數量是有限的,隨著時間的推移會逐漸減少。
挖礦在成本和回報之間達到了良好的平衡。挖礦用電解決數學問題。一位成功的礦工將透過新的比特幣和交易費的形式獲得一份 獎勵。只有礦工正確地驗證了所有交易,並且符合 共識 的規則,才會獲得獎勵。這種微妙的平衡為沒有中央管理機構的比特幣提供了安全性。
描述挖礦的一種好的類別比是數獨遊戲,這種大量競爭的遊戲,每次有人找到解決方案時都會重置,其難度會自動調整,因此需要大約10分鐘才能找到解決方案。想象一下,數以千計的行和列的巨大數獨謎題。如果我告訴你一個完整的謎題,你可以很快驗證它。但是,如果拼圖有幾個方格填充,其餘的都是空的,則需要花費大量工作來解決!數獨的難度可以透過改變它的大小(更多或更少的行和列)來調整,但即使它非常大,它仍然可以很容易地被驗證。比特幣中使用的“謎題”基於密碼雜湊,具有相似的特徵:它不對稱,難以解決,但易於驗證,並且可以調整難度。
在 [user-stories] 中, 我們介紹了 Jing,一個上海的企業家。Jing 經營著一個礦池,包含數千臺專業採礦計算機,爭奪獎勵。每10分鐘左右,Jing的採礦計算機就會在全球競賽中與成千上萬的類似的系統競爭,尋找解決方案。 為了找到解決方案,所謂的 工作量證明 (Proof-of-Work, PoW),比特幣網路需要每秒進行數千萬億(quadrillions) 次雜湊運算。工作量證明的演算法涉及使用SHA256密碼演算法重複地對區塊的頭部資料和隨機數進行雜湊,直到出現與預定模式匹配的結果為止。找到這種解決方案的第一位礦工贏得一輪競爭,並將該區塊發佈到區塊鏈中。
Jing 於 2010 年開始使用一台速度非常快的桌上型電腦進行挖礦,以找到適用於新塊的工作量證明Proof-of Work。隨著越來越多的礦工加入比特幣網路,解題的難度迅速增加。很快,Jing 和其他礦工升級到更專用的硬體,如高階顯示卡(GPU)。在撰寫本書時,難度已經大到需要採用專用積體電路(ASIC),將數百種挖礦演算法印刷到硬體上,在單個矽片上並行執行。Jing的公司也參與了一個礦池,這就像一個彩票池,允許參與者共享他們的算力和獎勵。Jing的公司現在運營著一個儲存庫,其中包含數千名ASIC礦工,每天24小時進行比特幣挖礦。該公司通過出售開採出來的比特幣來支付其電力成本,從利潤中獲取收入。
新的交易不斷從使用者錢包和其他應用流入網路。當被比特幣網路節點看到時,會被新增到由每個節點維護的未經驗證的臨時交易池中。隨著礦工建構一個新的區塊,他們將未驗證的交易從該池中取出新增到新的區塊,然後嘗試用挖礦演算法(Pow)來證明新區塊的有效性。挖礦的詳細過程請參見[mining]。
交易新增到新的區塊後,根據交易費高低和其他一些條件按優先順序排列。每個礦工透過網路收到前一個區塊時,便知道它已經輸掉了上一輪競爭,會開始挖掘新的區塊。他立即建立一個新塊,填入交易資料和前一個區塊的指紋,並開始計算新區塊的PoW。每個礦工在他的區塊中都包含一筆特殊交易,一筆支付給它自己的比特幣地址的獎勵(目前為12.5個新比特幣)加上該區塊中包含的所有交易的交易費用總和。如果他發現一個可以使這個區塊有效的解決方案,就會“獲得”這些獎勵,因為他成功挖掘的區塊被新增到全域性區塊鏈中。他建立的這筆獎勵交易也變得可花費。 加入採礦池的Jing建立了自己的軟體來建立新的區塊,將獎勵分配到礦池的地址,一部分獎勵將按照上一輪貢獻的工作量比例分配給Jing和其他礦工。
Alice的交易首先被網路接收,並被包括在未經驗證的交易中。一旦被挖礦軟體驗證,它就被包含在一個叫做 候選區塊 的新塊中(由 Jing 的礦池產生的)。參與該採礦池的所有礦工立即開始計算候選區塊的PoW。在 Alice 的錢包傳輸交易後約五分鐘,Jing的一位ASIC礦工找到了候選區塊的解決方案並將其發佈給網路。一旦其他礦工驗證了這個獲勝的區塊,他們將開始競爭挖掘下一個塊。
Jing 挖到的區塊作為 #277316 區塊成為了區塊鏈的一部分,包含419筆交易,其中包括Alice的交易。Alice 的交易被包含到一個區塊中,視為該交易的一個“確認”。
Tip
|
檢視包含 Alice’s transaction 的區塊。 |
大約19分鐘後,另一個礦工開採出#277317區塊。由於這個新塊建立在包含Alice交易的#277316區塊的頂部,因此它為區塊鏈增加了更多計算量,從而加強了對這些交易的信任。在包含交易的塊的頂部開採的每個塊都為Alice交易增加確認數。隨著區塊堆疊在一起,修改歷史交易變得極其困難,從而使其越來越受到網路的信任。
在圖 Alice’s transaction included in block #277316 中, 我們可以看到包含Alice的交易的#277316區塊。在它下面有277,316個區塊(包括區塊#0),在區塊鏈(blockchain)中彼此連結,一直到區塊#0,稱為_創世區塊(genesis block)_。隨著時間的推移,隨著塊的“高度”增加,每個塊和整個鏈的計算難度也會增加。在包含Alice的交易的塊之後開採的塊作為進一步的保證,因為它們在更長的鏈中堆積更多的計算。按照慣例,任何具有多於六個確認的塊都被認為是不可撤銷的,因為需要巨大的計算量來重新計算六個塊。我們將在 [minig] 中更詳細地探討採礦過程及其建立信任的方式。
既然Alice 的交易作為一個區塊的一部分嵌入在區塊鏈中,它就是比特幣分散式帳簿的一部分,並且對於所有的比特幣應用程式都是可見的。每個比特幣客戶端都可以獨立驗證該交易的有效性和可用性。完整節點客戶可以從比特幣首次在一個塊中產生的那一刻開始追蹤資金來源,從一筆交易到另一筆交易,直到到達Bob的地址。輕量級客戶可以透過確認交易在區塊鏈中,計算其後又開採了多少個區塊,來做所謂的簡單支付驗證(參見 [spv_nodes]),從而保證礦工接受它為有效的。
Bob現在可以花費這筆交易和其他交易的輸出了。例如,Bob可以透過將價值從Alice的咖啡支付轉移給新的擁有者,支付費用給承包商或供應商。最有可能的是,Bob 的比特幣軟體將許多小額付款合併為一筆更大的款項,例如將全天的比特幣彙集到一筆交易中。有關彙集交易,請參閱Transaction aggregating funds。
當Bob花費從Alice和其他客戶收到的款項時,他擴充套件了交易鏈。假設Bob向在班加羅爾的網頁設計師Gopesh支付了一個新頁面的設計費用。現在,交易鏈看起來像Alice’s transaction as part of a transaction chain from Joe to Gopesh。
在本章中,我們看到交易如何建立一個鏈條,將價值從一個擁有者轉移到另一個擁有者。我們還追蹤了Alice的交易,在她的錢包中建立,傳輸到比特幣網路,礦工將其記錄在區塊鏈上。在本書的其餘部分,我們將研究錢包、地址、簽名、交易、網路以及挖礦背後的具體技術。