與傳統的銀行和支付系統不同,比特幣系統基於去中心化的信任。在比特幣中,信任是比特幣系統中不同參與者的交互的湧現特性達成的。 在本章中,我們將站在比較高的視角研究比特幣,通過在比特幣系統中跟蹤一筆交易,看到它被比特幣分佈式共識機制所信任和接受,並最終記錄在區塊鏈中(所有交易的分佈式賬本)。後續章節將深入探討交易、網路和挖礦背後的技術。
在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毫比特幣"
Bob的銷售系統也會自動創建一個包含_支付請求(payment request)_的特殊二維碼(參見Payment request QR code)。
與僅包含目標比特幣地址的二維碼不同,支付請求是URL的二維碼,其包含目標地址、付款金額以及諸如"Bob’s Cafe"的描述。這允許比特幣錢包應用預先填充用於發送付款的訊息,同時向用戶顯示可讀的訊息。你可以使用比特幣錢包應用掃描二維碼,以查看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用她的手機掃描螢幕上的二維碼。她的手機顯示支付 0.0150 BTC 至 Bob's Cafe,她選擇"發送"以授權付款。在幾秒鐘內(大約與信用卡授權相同的時間),Bob在他的系統中看到交易,交易就完成了。
Note
|
比特幣網路可以以小數值進行交易,例如從millibitcoin(比特幣的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的錢包應用還可以獨立驗證交易數據是格式正確的,使用的是之前未花費的輸入,並且包含足夠的交易費用以包含在下一個區塊中。此時, 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的交易,在她的錢包中創建,傳輸到比特幣網路,礦工將其記錄在區塊鏈上。在本書的其餘部分,我們將研究錢包、地址、簽名、交易、網路以及挖礦背後的具體技術。