比特幣 (Bitcoin) 系統是如何運行的?——一文讓你精通比特幣!

一、什麼是比特幣

比特幣是一種在網路世界裡的電子貨幣、虛擬貨幣。

而「電子」貨幣跟你手裡的紙幣的區別就是:它沒有實體,它只是計算機世界裡的一串數字。

可能你會說:沒拿到手裡的錢還是錢嗎?我覺得「電子」貨幣根本不能用來買東西的~

但為什麼不能呢?就因為它是計算機世界裡的一串數字,就不能用來買東西了?

這很可能是每個人的直觀感受:一串計算機里存儲的數字,它沒有任何價值啊,我們為什麼要接受它,並把我的有價值的商品給對方?

可是想想你手裡的鈔票吧,它也只是一張普普通通的紙而已,一張紙的實際價值不比計算機里的數字高多少吧~那你為什麼就相信這張紙了呢?

所以關鍵點在這裡:一種貨幣能不能用來買東西,不是它自身的價值決定的,而是你身邊的每一個人是否相信這種貨幣?如果大家都相信這種貨幣,不論這個貨幣是什麼形態的,都可以用來買東西。

與「是否能信任電子貨幣」相對應的是,手裡的紙幣就值得人們信賴嗎?一個國家的紙幣是由這個國家央行發行並提供信用擔保的,也就是由國家確保你手裡的紙幣一定能夠花出去。但是如果國家耍無賴,你手裡的紙幣也會貶值,甚至一文不值。那些提著一塑料袋鈔票才能買到一個雞蛋的國家,是真實存在的。

那麼為什麼大家會相信比特幣?我們在下一章節展開介紹。

延伸閱讀1——石幣之島的故事之一:雅蒲島是在太平洋西部加羅林群島中的一個島,也是密克羅尼西亞聯邦(西太平洋的一個島國)最西的一個州。上面的原著土著居民使用石頭作為貨幣。1903年美國人類學家William Henry Furness在雅浦島上住了幾個月,並把土著人使用石頭作為貨幣的情況記載在他的著作《石幣之島》中。據書中記載,德國政府1898年從西班牙殖民者手中買下這個島嶼,並要求幾個部落的酋長組織修路。但修路對於土著居民完全沒有意義,而德國殖民者許諾給予土著的德國馬克(德國的貨幣)在土著人的眼裡可能只能用來生火(因為那時土著們連擦屁股都用樹葉),所以德國人的命令下達了多遍都無人理睬。後來德國政府研究了雅浦島的文化習俗,突然找到了突破點:他們下令對違抗命令的部落徵稅,徵稅的方式是,派酷吏到每家每戶,把他們最珍貴的石幣上塗上黑十字標記,並聲明這些石幣已經歸的過政府所有了。這個辦法奏效了,所有的土著人都覺得政府搶劫了自己,為了使那些石頭不被搶走,只得乖乖去替政府修路。故事的結尾,路修好了,德國政府就把那些標記抹去了,於是土著們的生活又恢復了自己「富有」的生活。

延伸閱讀2——一個國家貨幣的淪陷:2015年6月,辛巴威央行宣布採取「換幣」行動,從6月15日起至9月30日內,175千萬億辛巴威元可換5美元(對於2009年以前發行的津元,250萬億津元可兌換1美元)。從最早的比美元更值錢,到現在連計算器都按不過來,津元如何一步步成為人類貨幣史上的恥辱?辛巴威是一個礦產資源豐富,土地肥沃的非洲南部國家,於1980年獨立,曾經經濟實力僅次於南非,曾被譽為「非洲麵包籃」。津元最早比美元值錢,1980年獨立的時候,津元與美元匯率為1:1.47。但在2000年時,辛巴威政府推行了激進的土地改革政策,簡單點說就是把白人農場主的土地沒收,然後分配給自己的「黑人兄弟」,致使辛巴威的農業、旅遊業和採礦業一落千丈,經濟逐漸瀕於崩潰。2001年開始,辛巴威政府財政上出現嚴重赤字,為了貼補這種入不敷出的局面,津政府開始大規模印發鈔票,引發的通貨膨脹令人觸目驚心。2006年8月,津央行以1比1,000的兌換率用新元取代舊幣。2008年5月,津央行發行1億面值和2.5億面值的新津元,時隔兩周,5億面值的新津元出現(大約值2.5美元),再一周不到,5億、25億和50億新津元紙幣發行。同年7月,津央行發行100億面值的紙幣。同年8月,政府從貨幣上勾掉了10個零,100億新津元相當於1新新津元(新津元二代)。2009年1月,津央行發行100萬億面值新新津元。於是,一個在2001年,還可以以100比1兌換美元的貨幣,在十年不到的時間裡,就變成要以10的20幾次方比1兌換美元的垃圾。2009年4月,津政府宣布,新津元退出法定貨幣體系,以美元、南非蘭特、波札那普拉作為法定貨幣,以後的幾年中,澳元、人民幣、日元、印度盧比又加入到津國法定貨幣體系。(下圖為面值100萬億的辛巴威元)

二、為什麼信賴比特幣

1、你會相信什麼樣的貨幣?

一種貨幣,如何才能讓大家都信賴它呢?

最重要的一點,當然就是這種貨幣是否可靠!人們對於一種貨幣是否「可靠」的最初認知就是:看得見摸得著。

回想一下你們的長輩,是不是有過「把錢存在銀行不安全,壓在箱底才最安全」的想法?這就是老一輩人對於「可靠」的理解。甚至後來,即便大家開始接受把錢存在銀行中,但老一輩人仍然更傾向選擇更像貨幣實物的存摺,而非銀行卡。他們感覺每月明細清清楚楚打在摺子上會讓人更加放心,而如果是銀行卡,則只能到櫃面讓櫃員幫你查到裡面的內容(那時ATM還少的可憐,更沒有什麼網銀、手機銀行云云)。因此,即便手裡已經沒有鈔票了,即便鈔票已經變為了存摺本上一行行密密麻麻的小字,也要拿在手裡看在眼裡最有安全感。這就是對於貨幣實物的依賴。

但是隨著時代的發展,越來越多的人開始接受看不見的貨幣了。拿到錢先存到銀行是最普遍的做法,而且存摺在很多銀行已經開始退出歷史舞台。通過轉款等非現金交易的方式在大額交易中已經非常普遍,現如今,用手機微信零錢包里的一串數字作為零錢進行支付的方式,大家也已經習以為常了。

為什麼老一輩人覺得「看得見摸得著」更有安全感?因為在哪個年代,只有貨幣在我的手中,才能控制好兩件事情:

1、我手中(收到)的貨幣數量是不可被更改;

2、只有我的授權才能支付;

看得見摸得著=我手中(收到)的貨幣數量不可被更改+只有我的授權才能支付

後來,人們開始逐漸信任銀行,並把「看得見摸得著」的錢存入銀行,這是因為銀行具備保證「我手中(收到)的貨幣數量不可被更改+只有我的授權才能支付」的能力。銀行通過建立龐大的IT系統,存儲每個客戶資金的數據,確保這些數據不被篡改,並通過技術手段確保資金在得到所有者的授權後才能支付。所以在銀行的系統里,通常會有一個存儲了所有儲戶賬戶餘額的表單,我們把它叫做Ledger,即賬本。就像下面這樣:

Ledger告訴了我們,Alice有5.3元,Bob有100元……銀行會投入大量的精力和物力去保證系統中這張表的準確性,確保每個人對應的金額不能隨意的增減。他們建立自己的機房、搭建獨立的網路環境、購買最先進的伺服器、聘請最資深的專家。也正是因此,我們才相信銀行能夠保證Ledger的準確性,於是我們就把錢存到了銀行。

後來,就像相信銀行存儲的Ledger一樣,我們還同樣相信政府存儲的每個人的社保信息,相信支付寶里的餘額信息,相信微信里的零錢信息……

漸漸的,我們的「身家性命」真的全部變成了這些機構伺服器上存儲的一個文件、一串數據。這些機構也在想盡辦法讓自己的數據更加的安全、系統更加健壯,比如:採用各種數據備份機制、採用分散式存儲技術……但即便如此,也偶有災難事件發生。

延伸閱讀3——舊聞兩則: (1)這是《經濟學人》雜誌比較著名的一個故事:2009年宏都拉斯警方衝進了Mariana Catalina Izaguirre家裡並驅逐她離開她住了30多年的家。原因是來自當地政府房屋委員會的資料顯示,該房屋屬於另外一個人,而這個「房主」向法院申請驅逐令,最終 M.C.Lzaguirre女士被迫離開。而等到政府房屋委員會糾正了自己資料上的錯誤時,M.C.Lzaguirre女士的家已經被拆掉了。(2)2015年5月28日11時起,攜程官網及APP無法使用,直至當天23時29分,才全面恢復正常。官方消息是由於刪除了生產伺服器上的執行代碼導致。也有消息表示是由於資料庫數據遭到惡意刪除導致此次事件。

於是人們開始思考一個問題:是否可以有一種不依靠某一家機構的人力、物力、技術能力,而是藉助整個互聯網的力量,為每個人的財富數據提供保障的方案呢?

就這樣,比特幣出現了!

2、比特幣去中心化的存儲機制

與傳統的存儲方案不同,比特幣採用了一種特殊的去中心化的賬本存儲方案。簡單說就是:所有加入比特幣網路的電腦上,都會存儲一份這樣的賬本。

由於賬本存儲在網路的各個節點上,其中一個節點出現問題,還是可以從網路上的其他節點獲取到正確數據的。可以對比一下傳統中心式的存儲體系與比特幣去中心化的存儲體系的區別。

由於這種去中心化存儲賬本的特點,在某一個節點更新賬本數據的時候,就要通知其他節點一起修改賬本記錄。舉一個例子,如果Alice給Bob轉了5個比特幣(BitCoin,也稱做BTC),那麼最初進行這筆轉賬處理的節點,就要把這個處理的情況傳播給臨近的其他節點,然後其他節點再傳播給臨近的節點……直到網路上所有的節點賬本都被更新了。

3、比特幣交易——如何實現「只有我的授權才能支付」

在這種去中心化的環境下,沒有銀行這種機構的統一管理,不需要建立伺服器集群或聘請龐大的維護團隊,所有比特幣的交易業務都是基於預先設定好的程序或演算法,在互聯網上自發生長。

那麼,在這樣一種去中心化的環境中,如何能保證收款和支付的安全性,最終達到「我手中(收到)的貨幣數量不可被更改+只有我的授權才能支付」的目標呢?

首先,來看「只有我的授權才能支付」這一點,比特幣是用「私鑰」和「公鑰」來實現的。

「公鑰」「私鑰」是現代密碼學非對稱性加密裡面的概念,而非對稱性加密又與對稱性加密相對應。對稱性加密中只有一個密鑰,即用來加密又用來解密。比如以前戰爭年代常用一本密碼字典(比如什麼字對應哪本書中的第幾頁第幾個字)把一句話加密為密文。這本密碼字典就是密鑰,可以看出密鑰十分關鍵,如果密鑰泄露,那拿到密鑰的人就可以進行解密。這種加密方式的缺點顯而易見,你要讓對方解密你的密文,就要把這個密鑰也給對方,這樣就極大的增加了密鑰泄露的概率。

這一情況,直到非對稱加密出現後才得到改觀!

非對稱加密中,每個人都有兩個密鑰,一個「公鑰」,一個「私鑰」。「公鑰」是公開的。而私鑰只有自己手裡才有。「公鑰」、「私鑰」的特點可以簡單理解為:用一個人的「公鑰」加密,只能用這個人的「私鑰」解密;而用一個人的「私鑰」加密,只能用這個人的「公鑰」解密。

這樣,就解決了傳遞「密鑰」過程中,「密鑰」泄露的問題。因為如果我想給你一個只有你能看的信息,因為我手裡有你的「公鑰」,而你的「私鑰」只在你手裡才有,因此我只要用你的「公鑰」加密就行了。

比特幣系統就是採用了這一加密方式。但你可能會好奇,比特幣系統里的「私鑰」、「公鑰」機制是怎麼實現的?

簡單來說,比特幣系統讓每個參與交易的人,先隨機產生一個字元串,作為自己的唯一的「私鑰」。然後會通過「私鑰」生成對應的唯一「公鑰」。生成後,「公鑰」在比特幣網路上公開給每個人,而「私鑰」你要自己藏好,不能讓別人知道。由於「私鑰」生成「公鑰」的過程是不可逆的,因此別人即便拿到了你的「公鑰」,也不可能知道你的「私鑰」是什麼。這樣,我們很容易就能實現下面的功能:當別人用你的「公鑰」鎖定一個數據時,只有擁有「私鑰」的人(也就是你)才可能解鎖這個數據。

註:舉個簡單(但不實際)的例子,比如你隨機生成兩個質數(173、881),拼成一個6位「私鑰」173881,我們生成「公鑰」的規則就是將兩個質數相乘173X881=152413。這時網路上的人都會拿到「公鑰」152413。當某個人想讓某個數據只能被你修改時,他可以在這段數據後面加上「公鑰」152413,並聲明,只有私鑰左3位乘右3位等於公鑰的人,才可以修改這個數據。這樣也就只有你能修改這個數據了。 如果,網路上有個黑客想不經你的同意篡改這個數據,即便黑客知道「私鑰」生成「公鑰」規則是兩個質數相乘,他也不知道是哪兩個質數,因此,他只能進行X乘Y的暴力破解找到「私鑰」:001X001,001X002,001X003,002X001,002X002……。當質數很大時這個過程是比較艱難的。 當然上面例子中所使用的規則太過簡單,用計算機暴力破解是可以很快通過「公鑰」找到「私鑰」的。但是比特幣系統使用的橢圓曲線演算法從「私鑰」生成「公鑰」,現有技術手段很難破解。同時,實際的比特幣系統中私鑰解密過程也是很複雜的,是通過一種基於逆波蘭表示法的堆棧執行語言實現的。如果有興趣深入了解,你可以google一下或者翻閱《精通比特幣》一書。

好了,明白了比特幣系統中的「公鑰」和「私鑰」原理後,後面理解起來就會容易很多:

我們把參與轉賬的人變得多一些,假設有3個人,Charles先給Alice轉了5個BTC,然後,Alice又把這5個BTC轉給了Bob。

我們站在Alice的位置進行分析,Alice為何能給Bob轉這5個BTC呢?因為Alice能夠用自己的「私鑰」解鎖這5個BTC。而這5個BTC是如何鎖定的呢?聰明如你一定想到了,Charles給Alice轉帳時用Alice的「公鑰」鎖住了這5個BTC。

而Alice再給Bob轉賬時,又用Bob的「公鑰」把這5個BTC給鎖定了。只有當Bob要用這5個BTC時,才能用自己的「私鑰」解鎖並使用這5個BTC,其他人因為沒有Bob的「私鑰」,是不能動用這5個BTC的。

所以,比特幣系統里很智慧的一點:就是把一個人的「公鑰」當作這個人的收款賬號(或收款地址)。這樣當你在給別人轉賬時,你輸入了別人的收款賬號——也即別人的「公鑰」,比特幣系統會自動幫你把這筆款用那個人的「公鑰」鎖定。這樣這筆錢就屬於他了,將來他必須用他的私鑰解鎖,才能使用這筆錢。這樣也就達到了「只有我的授權才能支付」這一點。

註:其實公鑰到收款地址還需要做一些轉換,本文為了寫得簡單易懂就忽略這些細節了,但是收款賬號與公鑰是有極強的相關性的。

神奇吧,錢並沒有實際握在你的手裡,只是存在於比特幣的網路里,但它就是屬於你!

延伸閱讀4——觸不到的貨幣:《貨幣的禍害》一書里提到這麼一個故事:1932年,法蘭西銀行擔心美國不再盯住金本位(按20.67美元換1盎司黃金的傳統價格用美元兌換黃金),於是要求紐約聯邦儲備銀行將它存在美國的大部分美元資產的轉換成黃金。美國的黃金儲備開始減少,法國的黃金儲備開始增加,美元走軟,法郎走強,並導致了1933年的銀行業恐慌。但事實上黃金並沒有留到法國,仍然在美聯儲的地下金庫里,法蘭西銀行的美元兌換為黃金的形式是將美聯儲銀行底下金庫中美國抽屜中的金塊搬到法國抽屜中。我們再來看看美國這個神秘的地下金庫,從網上查到的資料看,紐約聯儲金庫位於地下25米,比海平面低15米,比紐約地鐵系統還低10米左右。金庫建成近80年來,從未發生過劫持偷盜等案件。進入金庫的正常通道直郵一個鋼門,重達90噸,高度近3米,TNT炸藥也不能傷其分毫。在金庫里,共有122個儲藏間,最大的可以存放近11萬塊金磚,堆起來有3米高、3米寬、5米多長。整個金庫存放的黃金約7000多噸,約佔全球官方黃金儲備2.9萬噸的四分之一。在紐約聯儲金庫里,交易只是換房間,因為很多國家的黃金儲備存放在紐約聯儲地下金庫中,這主要出於兩點考量:一是交易的便捷性;二是運輸造成的安全成本和經濟成本。交易雙方達成交易後,黃金只是從一個帶有編號的房間搬到另一個編號的房間。在金庫中有許多來自世界各地的金磚搬運工,每天的工作就是將金磚搬到車上運到指定的儲藏室,再卸下來碼放整齊。但是,沒有人知道是金磚是從哪國搬到哪國,因為房間上只有編號。看到這裡,你也許已經有個概念了,貨幣的概念一直在變遷,每個場景下都有不同的含義。在一些地方,例如使用石幣的雅浦島,再例如有著地下金庫的美聯儲銀行,貨幣只是一種記賬方式,比特幣等區塊鏈貨幣也是如此。當Alice宣稱她擁有1000枚比特幣,不是說她的抽屜或某個保險箱里安安靜靜的躺著1000枚比特幣,而是說比特幣網路上有1000枚比特幣是屬於Alice的比特幣地址(即用Alice的公鑰加密過的),只有Alice有權動用。(下圖為美國電影《紐約大劫案》[也譯作:虎膽威龍3]中模擬出的地下金庫場景)

看到這裡,我想你應該不介意再趁熱打鐵多了解一些比特幣交易數據結構方面的知識,因為這對你後面知識的理解會很有幫助:)

上面提到,Alice給Bob轉賬,既要用Alice的「私鑰」解鎖,又要通過Bob的「公鑰」加密,因此,比特幣交易的數據結構分為inputs和outputs兩部分:

inputs主要是Alice(這筆轉賬的輸入方,也即」發起方")的信息,主要包括:

ScriptSig——Alice的數字簽名信息,即:Alice的「私鑰」信息的Hash值,這個Hash值里包含了「私鑰」的特徵,是用來「解鎖」用的。(如果你不明白Hash值是什麼,不要緊,在這裡並不關鍵,而且後文會詳細介紹Hash值)

outputs主要是Bob(這筆轉賬的輸出方,也即「接受方」)的信息,主要包括:

Amount——金額

scriptPubKey——用Bob「公鑰」生成的一段鎖定腳本,裡面包含著Bob「公鑰」的特徵,將這筆金額鎖定後,只有含有Bob「私鑰」特徵的簽名信息才能夠解鎖。

你有沒有覺得少點什麼?對了,上面的數據結構里只有Alice的「私鑰」信息,卻沒有Alice的「公鑰」信息,如何能實現對Alice「私鑰」與「公鑰」的匹配,從而實現解鎖呢?

原來,在inputs里,還要有一個交易序號(txn),這個txn代表Charles給Alice轉5個BTC的那筆交易,因為在那筆交易里,Alice是接收方,交易的outputs裡面有Alice的「公鑰」地址。

當Alice使用比特幣時,比特幣系統會從Alice給Bob轉賬的交易中,找到Alice的ScriptSig(相當於是「私鑰」),再通過這個交易里記載的上一個交易的txn,順藤摸瓜找到上一個交易中Alice的scriptPubKey(相當於是「公鑰」),然後進行「私鑰」和「公鑰」的驗證,驗證通過後,Alice才有權使用這5個比特幣,Alice給Bob轉賬的交易才能成功。

講到這裡,你應該已經了解了比特幣系統中,交易數據是什麼樣子。它們絕大多數都是下面這個樣子的:

inputs txn: 我要轉出的比特幣是從哪筆交易來的? scriptSig: 用我的「私鑰」生成的解鎖腳本,以便解鎖我要轉出的比特幣outputs Amount:我要轉出的比特幣金額多大? scriptPubKey: 將這筆金額用收我錢的那個傢伙的「公鑰」鎖定

而且你可以通過txn一直追溯下去,一直追溯到這筆比特幣的源頭:

到這裡,又出了個新問題,如果Alice轉給Bob的交易是5個BTC,那這筆交易的上一筆交易一定也必須是5個BTC嗎?

比特幣系統給了你一個很靈活的處理體系,在這個體系下,inputs可以是多筆:

例如下面這個例子,Bob收到了Alice的5個BTC,這5個BTC是由Charles給Alice的3個BTC和Fred給Alice的2個BTC組成的。當然Alice收到的這兩筆轉賬交易一樣有它們之前的交易,Fred給Alice的2個BTC是通過一筆之前的交易得到的(inputs里有一筆交易txn#772...),而Charles給Alice的3個BTC是通過兩筆之前的交易得到的(inputs里有兩筆交易txn#343...,txn#05a...)。

在真實的比特幣網路中,你會看到更為複雜的交易結構,比如下面這筆交易,它是由6筆交易作為inputs。6筆交易總共的比特幣金額是139.616 BTC。接下來,你會發現一個有趣事情,就是這筆交易的outputs對應多個「公鑰」腳本(也就是多個收款地址):一個是收款方「公鑰」信息,一個是你自己的「公鑰」信息。收款方「公鑰」信息的Amount是139.606 BTC,你自己「公鑰」信息的Amount是0.01 BTC。它的意思是:前面匯款給我的6筆交易總共包含139.616 BTC,我只要支付其中的139.606 BTC給收款人,剩下的0.01 BTC用我自己的「公鑰」信息鎖定,也就相當於將剩下的「零錢」轉回給我自己。

看到這裡,你已經了解了比特幣交易的主要特點了。比特幣網路里充斥著這樣數以千萬記的比特幣交易,交易間通過交易序號txn連接起來,通過這些由交易序號串聯起來的路徑,你可以了解你拿到的比特幣從哪來的?要到哪裡去?編織成一個錯綜複雜的支付路徑。

3、比特幣賬本——如何實現「我手中(收到)的貨幣數量不可被更改」

還記得上一節中我們提到的賬本Ledger嗎?

保證「我手中(收到)的貨幣數量不可被更改」也意味著保證賬本中我的賬戶餘額不能被隨意的篡改。這是怎麼實現的呢?

其實,在比特幣系統中,這張Ledger中沒有每個人的餘額,有的只是那幾千萬條交易:

那每個人的餘額怎麼來的呢?是的,就是你想到的最麻煩的辦法,比特幣系統按照每個人的收款地址(相當於每個人的「公鑰」),將這個收款地址下所有的轉入、轉出額度加總,就得到了這個收款地址的餘額了。比如:下面例子中,一個以13kjhfg開頭的收款地址,他的餘額就是這麼一點一點累加出來的~

這樣的賬本下,你的餘額是無法篡改的,或者說,如果你要篡改餘額,那就必須偽造交易。但是從前面的文字,你應該也明白交易與交易之間的關係是多麼的緊密,隨便偽造一筆交易是十分困難的。下面的章節會進一步說明偽造、篡改交易的其它困難~

4、區塊鏈上的交易為何無法偽造或篡改?

1)偽造最近的一筆交易

如果你想偽造最近的一筆交易,那麼很不幸,幾乎是不可能的。

還記得上文我們提到的比特幣交易結構嗎?每一筆比特幣交易都能夠追溯到它的上一筆交易。因此,下面的例子中,當Alice從其他3筆交易中分別收到1BTC、2BTC、2BTC後,將這3筆交易作為inputs,向George發起一筆5個BTC的轉賬時,比特幣系統會先去往Alice收到BTC的3筆交易中,檢查一下Alice是否已經用過這3筆交易中的BTC。只有這3筆交易中的BTC都未曾被支付過時,比特幣系統才認為Alice向George的轉賬是合法的。

「檢查Alice收到的BTC是否被支付過」在比特幣系統中是很好實現的,只要先找一下哪些交易的outputs中含有Alice的地址(這些就是支付給Alice的交易),然後檢查一下它們的交易序號txn是否出現在其他交易的inputs里(確認這些交易是否被支付過)。

但是在全網千萬筆交易的環境下進行這個檢查會很耗時,因此比特幣系統會生成一個未被支付交易索引,隨著每次新交易的產生,這個索引會不斷更新:去掉被支付的交易,加入新的未被支付的交易,並隨著新交易信息傳遞給網路上的每一個節點。所以,實際上檢查「Alice收到的BTC是否被支付過」時,看一下inputs里的交易的txn是否在未被支付交易索引中即可~

另外,前文提到的比特幣系統對於交易inputs和outputs的處理方式,也會保證inputs的金額之和與outputs的金額之和相等,從額保證每筆交易的金額不能隨意篡改。

2)篡改歷史交易

既然上面提到,每一筆交易與它前一筆交易是緊密相關的,因此新發生的交易等於被舊交易牽制著,也就不能隨意篡改、偽造。那你可能有疑問了,那麼我是否可以通過偽造或篡改歷史交易,將整個交易鏈條上的交易全部篡改,從而改變你的交易行為以及你的賬戶餘額?

答案是:不可能的。

要了解為什麼「不可能」,我們需要先學習一個小知識——「Hash函數與Hash值」。

「Hash函數」的作用是將一大段文字內容,按照一定的規則輸出為一個定長的摘要信息,這個摘要信息即「Hash值」。這個「Hash值」只與原來的文字有關,即一模一樣的文字的「Hash值」是一樣的,但只要文字稍做修改,「Hash值」就會變化。由文字生成Hash值的過程是不可逆的,也就是說我只能從文字得到Hash值,但是從Hash值是反推不出代表什麼文字的。

如果你覺得不好理解可以想想一串數字求餘數的過程,比如我們有個很大的數字:231451723794,拿它對3111117相除求餘數,得到餘數174579。我們就可以把174579看成231451723794的摘要。此外,如果這時改動231451723794中任意一個數字,這個得到的餘數極大概率是不一樣的,基本實現了數字與摘要的一對一關係。同時,如果先給你餘數174579,你還原回231451723794是很難的。

當然,上面的求餘數太簡單了,每3111117個數字,餘數就會重複一次。Hash演算法採用了複雜得多的取餘數演算法,以盡量保證兩個不同的文本輸出的Hash值不一樣,並盡量保證Hash值不能反推回原始信息。如果很不幸,兩個不同的文本輸出了同樣的Hash值,這種情況就叫做「碰撞」。「碰撞」是我們不希望看到的情況,因此,Hash函數的演算法也在不斷的更新換代,MD4、MD5、SHA等等都是不同的Hash函數演算法,隨著演算法越來越複雜,「碰撞」的概率越來越低,一次Hash運算處理的時間也越來越長。比特幣採用的是SHA256的Hash演算法。對於SHA256的Hash演算法,我們來看一個Hash函數輸出結果的實例:

可以看到,一句話僅僅多了一個句號,它的Hash值就大相徑庭了。

比特幣系統是如何運用Hash函數的呢?

比特幣系統在進行交易數據存儲的時候,會將交易分組打包存儲(目前一個包的大小為1M,而一筆交易數據至少250位元組,基本上每個包可以容納近千條交易),這個包就是我們常說的區塊(Block)。區塊與區塊之間,會通過每個區塊的特徵參數連接起來,即,每個區塊都記錄了前一個區塊的特徵參數,形成了一種鏈式的存儲結構,「區塊鏈」這個聞名遐邇的詞語就是打這兒來的~

那這個將每個區塊都串聯起來的特徵參數到底是什麼呢?

聰明如你一定猜到了,這就是這個區塊所包含「內容」的Hash值。

一般一個區塊中包含哪些「內容」呢?一是上一個區塊的Hash值,二是一堆交易,三是一個叫做Nonce的變數(Nonce做什麼用的後面的章節會詳細介紹,這裡暫時留下一個懸念)。所以,一個區塊的Hash值,可以簡單理解為對上面三項「內容」求出的一個Hash值。

綜上,生成一個區塊的大致過程基本是這樣的:

a、交易發生後進入計算機的內存,先進行一些基本驗證(比如:這筆交易的input中引用的交易,是否是未被支付過的交易)。若驗證不成功,則交易會被認為是invalid Transaction——無效交易。若驗證成功後這些交易會被認為是Unconfirm Transaction——未確認交易,「未確認交易」會靜靜的躺在內存的有效交易池中等待被裝入區塊中。由於前面提到,比特幣是一種全網記賬的系統,因此這筆交易發生後,也會在全網廣播,周邊的計算機節點接到這筆交易後,也一樣先放入內存,再進行驗證,驗證通過即等待被打包進區塊。

b、比特幣網路中負責發起記賬動作的節點會從內存的有效交易池中,抽取近千筆Unconfirmed Transaction,然後進行打包。打包時,會將上一個區塊的Hash值也加入包中。

c、然後對整個包求Hash值,這個Hash值就是這個區塊的特徵參數。這個特徵參數很重要的,因為後面再生成新的區塊時,還要用到它。

d、由於比特幣是一種全網記賬的系統,因此,當該節點生成新區塊後,整個過程並沒有結束,該節點接下來會發起一次全網記賬。它會將新區塊的數據廣播給周邊的節點,周邊的節點再傳遞給周邊的節點,直到全網都收到這個信息。當周邊的節點收到這個信息後,也開始在本地進行一樣的處理,即:將新區塊數據記錄到本地的電腦中,以確保本地的區塊鏈數據更新為最新的數據。

看到這裡,你會發現一個有趣的現象,比特幣這種鏈式存儲的結構,每一個區塊的Hash值都是由上一個區塊的Hash值決定的,因此,如果你要修改了歷史上的一筆交易,那麼這筆交易所在的區塊數據的Hash值就會變化,那麼引用這個Hash值的下一個區塊的Hash值也要變化,影響一直隨著區塊鏈延伸下去。

現在,你應該明白修改歷史交易的難度了。修改歷史交易並不只是修改幾百筆交易那麼簡單,修改歷史交易,意味著該筆交易後面所有的數據記錄全部出現不匹配的情況。如果你要調整後面所有的數據讓他們匹配起來,這幾乎是一項不可能的任務。

5、比特幣系統運行機制的高階知識——雙重支付風險與防控機制

看完上面的內容,你已經基本對比特幣和區塊鏈的知識有了一定了解。下面的內容就是一些進階知識了,有興趣的讀者可以繼續往下看,有些燒腦但很有意思~

你可能會說,哇,比特幣看似無懈可擊嘛,無法偽造和篡改交易,餘額是每筆交易累起來的,非常的安全。

但事實真的是這樣嗎?其實還有一種特殊的風險,我們慢慢來分析。

我們先來回顧一下一筆交易發生的過程:

比特幣交易發生後,會在自己這個節點進行驗證,並同時在全網廣播,周邊的節點接到廣播後,也開始驗證。一旦交易驗證通過,則更新到各自內存的有效交易池中。

由於在全網廣播的過程中,無法控制先到達哪個節點後到達哪個節點,因此,節點先接到哪筆交易,後接到哪筆交易完全是隨機的。

比如,上面這個例子中,最右下角那個節點就先接到了後發起的交易。

這樣,會存在這樣一種情況:Alice給Bob地址轉賬的同時,又發起了一筆給自己地址的轉賬。

在交易進行廣播的時候,一些節點收到了Alice給Bob地址轉賬的交易,另一些節點收到了Alice給自己地址轉賬的交易。於是,先收到Alice給Bob轉賬交易的節點,會驗證通過Alice給Bob轉賬的交易(因為後面來的Alice給自己地址轉賬的交易,會因為inputs中的交易已被支付給Bob而被拒絕),並放入自己的有效交易池中。類似的,先接到Alice給自己轉賬交易的節點,會驗證通過Alice給自己轉賬的交易,並放入自己的有效交易池中,如下圖。

這時,網路上的節點分為兩個陣營,即Bob陣營和Alice陣營。

現在我們進入下一步,組裝區塊。

Bob陣營的節點會組裝出一個區塊,接到整個區塊鏈的最後;而Alice陣營的節點會組裝出另外一個區塊,接到整個區塊鏈的最後。這樣,比特幣系統的區塊鏈就分叉了,出現了兩條鏈,以哪條鏈為準呢?

按照比特幣系統的運行規則,要以最長的鏈為準。

這裡,我們再舉個直觀一些的例子來說明:

最開始,比特幣網路上相安無事,記錄的都是一條統一的鏈條。

在某一時刻,加拿大的節點發現了一個紅色區塊,與此同時,澳大利亞的節點發現了一個綠色的區塊,它們將新區塊接在了鏈條的最末端,各自開始向周圍節點進行廣播,它們周圍的節點逐步都收到了它們的信息。為了形象,我們把加拿大節點的廣播路徑顯示為紅色,把澳大利亞節點的廣播路徑顯示為綠色,可以看到,它們在逐漸把藍色變為自己的顏色。

最終,網路上出現了兩個鏈條。一部分節點記錄著包含紅區塊的鏈,一部分節點記錄著包含綠區塊的鏈。

這時,紅色陣營的節點在不斷的嘗試在自己鏈條(即:末尾為紅色區塊的鏈條)結尾新增區塊,而綠色陣營的節點也在不斷的嘗試在自己鏈條(即:末尾為綠色區塊的鏈條)結尾新增區塊。

突然,綠色陣營位於俄羅斯的節點發現了新的區塊,即粉色區塊,於是這個新節點開始了新一輪廣播。

這次廣播比較有趣,當廣播到綠色陣營的節點,綠節點們很開心的在自己鏈條結尾加上了粉色區塊,而當廣播到紅色陣營的節點,紅節點們則立刻倒戈,遺棄掉自己的紅區塊,而是保留下更長的「綠色區塊+粉色區塊」的鏈條。

如果你的交易剛好在被遺棄的區塊里,那你這筆交易將被重新扔回內存里!

看到這裡你是不是開始有一些擔心了?回到Alice給Bob轉賬買東西的場景。Alice給Bob轉賬的交易被記錄在區塊鏈中後,Bob給Alice寄出了商品。但就在此時,Alice生成了一條更長的包含Alice給自己轉賬交易的區塊鏈,這時,那條包含Alice給Bob轉賬交易的區塊鏈就會被更長的鏈所取代。

而Alice給Bob轉賬的那筆交易,回到內存中後也進不了有效交易池。它會被認為是一筆invalid Transaction,而被遺棄掉。因為,在驗證時會發現,這筆交易inputs里的那筆交易並不是一筆未支付的交易,因為它已被支付給Alice自己。結局是,Bob寄出了物品,卻沒有收到錢~

這就是比特幣里常常提到的雙重支付風險(也叫「雙花」風險)。

為了解決這個問題,比特幣系統就要想出一種辦法,讓Alice不能輕易的製造出更長的鏈條。

這種辦法就是:讓所有的節點計算一道很難的謎題,只有找到答案的節點才有權組裝新的區塊,並發起一次記賬動作。

那麼這道謎題是什麼呢?就是讓新區塊的Hash值小於一個目標值。很難理解吧?來聽我慢慢解釋。

還記得前面章節提到,每一個區塊都會有一個Hash值嗎?而這個Hash值,是通過區塊中的三項內容計算出的:一是上一個的Hash值,二是一堆交易,三是一個叫做Nonce的變數。(講到這裡,Nonce這個變數終於要閃亮登場了!)

每個節點在組包時,節點會不斷的調整Nonce的大小,使得由「1.上一個區塊的Hash值,2.一堆交易,3.Nonce變數」這三項內容組成的文本串發生變化,從而使其對應的Hash值也發生變化~

重點來了,Hash值在不斷的變化,而只有當某次計算出的Hash值小於目標值的時候,這個節點才能宣布自己解出了謎題,並可以發起一次全網記賬動作!而記賬的內容呢?就是以「上一區塊的Hash值、一堆交易、目前的Nonce變數值」等信息組成的一個新區塊。

舉個例子~

一串文本「I am Satoshi Nakamoto」(我是中本聰)如果後面加上一個不斷變化的nonce,那它的Hash值也會不斷的變化:

假設我們要找到的目標值是以0開頭的(即小於10000000....)Hash值,我們發現,當nonce為13時即滿足了條件。而比特幣系統中也是這麼做的:

在上面的例子中,我們會發現很快就找到了答案,這是因為題目太簡單了。如何加大難度呢?找一個00開頭,或者找一個000開頭的Hash值肯定更具挑戰性。而且前面的0越多,謎題也就越難。

在真正的比特幣系統中,目標值通常是一個由多個0開頭的16位數字,這就導致每個節點要進行數以億計次計算,才可以找到滿足條件的Hash。同時,比特幣系統還會調整目標值,以達到控制謎題難度的目的。

其實特別好理解的比喻就是扔骰子,你可以看成是節點們在不斷的扔2個骰子,當扔到小於目標值的數字時就能成功拿到組包記賬的權利。而目標值一開始是12,於是很簡單,只要節點們不扔到兩個6就滿足條件。這時比特幣系統覺得大家玩的太嗨了,要提高一下難度,於是把目標值調整成3了,於是節點們都哭了,因為只有扔到兩個1才能滿足條件~

為什麼要控制謎題的難度呢?因為不斷有新的節點加入到比特幣網路中,解題的節點越多,就越可能在短時間內算出滿足條件的Hash值。於是,比特幣系統就要調整謎題難度,以確保基本每10分鐘才能解出一次謎題。

這種通過解謎題來確立節點組包記賬權的方式,有一個在區塊鏈界響噹噹的名字——工作量證明Proof of Work(PoW)。

所以,在上面的情況下,Alice是不可能迅速形成一條更長的鏈條的。她如果想實現雙重支付,就必須與其它節點賽跑。但是她是不可能贏過其它節點的,因為她只有一個節點~

你可能會說,如果Alice有一台運算速度很快的電腦呢?或者,有1百台、成千上萬台強大的電腦呢?那她也沒有取勝的可能,因為她對抗的是全世界所有的節點~

很明顯,只有當Alice控制了全世界多一半的節點時(如控制了全世界51%的節點),她製造出更長的鏈條的可能性才會更大~這就是一些比特幣相關文章中,經常提到的「51%攻擊」。

6、比特幣系統運行機制的其它知識

其實講到這裡,比特幣系統運行的絕大部分知識就已經介紹完了。下面你看到的一些名詞或短語,是你在看比特幣文章時可能遇到的,所以也在這裡逐一解釋一下。

1)節點

看完上面的文字,相信你對於比特幣系統全網記賬的機制已經有了比較深刻的印象了。在全網記賬的過程中,每個節點在裡面起到的作用就至關重要。上面提到了節點與節點間會進行交易廣播、會進行區塊鏈信息的廣播,節點還可以進行記賬。其實真實比特幣網路中,不同的節點會有不同的功能,下面把比較重要的幾種節點簡單介紹一下:

a.全節點:這種節點會將歷史上所有的區塊數據(包含所有交易)都下載下來,因此,這種節點可以獨立的進行比特幣地址的餘額驗證、交易有效性驗證、歷史交易驗證等工作。由於全節點需要保留比特幣網路上所有的交易數據,因此它會根據網路上廣播的新區塊信息,不斷的新增最新的數據,保證區塊鏈數據處於最新的狀態。由於上述原因,全節點對比特幣交易的驗證是最安全的。我自己安裝的就是這種節點類型的客戶端。但是這種節點的缺點也很明顯,由於需要下載歷史上所有交易數據,這種節點顯得特別笨重。根據我自己的經驗,2013年時全節點大小在幾十個G,最近(2017.8)全節點大小已經達到130G左右。

b.SPV節點:由於移動設備的飛速發展,在手機、Pad等便攜設備上進行比特幣交易的需求越來越旺盛。顯然在存儲空間有限的便攜設備上,無法安裝「全節點」。因此比特幣系統支持一種輕量級的節點客戶端。這種客戶端只會下載區塊的關鍵數據,比如區塊的Hash值,Nonce數值等數據~通過這些數據就可以知道區塊鏈概況。這些關鍵數據只有區塊全量數據的1/1000,因此客戶端會顯得很輕便。但SPV節點的問題是,在進行交易驗證時,必須通過網路從全節點處獲取驗證所需的信息,才可以進行驗證。如果你身邊有黑客建立的偽節點(如受到Sybil攻擊),可能會干擾你的驗證過程。因此,要保證萬無一失的安全性,最可靠的方法還是建立一個「全節點」。

c.礦工節點:前面講到,部分節點要通過大量、不停歇的計算,去爭取組裝區塊及發起全網記賬的權利(上面提到過,這個過程叫工作量證明PoW)。這樣的工作不是每個節點都要做的,而只有礦工節點才會去做。為什麼叫做「礦工」節點呢?因為每次這類節點算出謎題並爭取到組包記賬的權利時,比特幣系統會給這個節點獎勵一定數量的比特幣。這個過程非常像是一個礦工在很費力的挖礦,獎勵的比特幣就是這個礦工挖到的礦。這也是為什麼,有的文章說「挖到1個block,就可以得到XXX個比特幣」,其實它的實際意思是:礦工節點通過不停運算,爭取到組裝1個新block並發起全網記賬的權利後,可以得到XXX個比特幣的獎勵。講到這裡,你也該明白:其實只要控制了51%的礦工節點就可能發起51%攻擊。

註:可能你會好奇,獎勵的比特幣怎麼打入礦工的賬戶的呢?其實簡單來講,獎勵的比特幣也是一筆交易,但這筆特殊的交易沒有inputs,只有outputs。outputs里記錄的就是礦工節點上登記的公鑰地址~所以挖出的比特幣只有礦工節點所有者用自己的私鑰才可以解鎖,這樣就實現了對礦工的獎勵。

上面介紹的是最典型的幾類節點,在比特幣網路上還有礦池節點等其它一些節點,就不做過多介紹了。當然上面幾類節點的功能完全可以搭建在同一個節點上,這取決於節點搭建者具體想用節點來做什麼。

2)比特幣的總量

按照比特幣系統的設計原理,比特幣的發行總數是個定值——2100萬。而比特幣的發行,本質就是對「挖礦」的礦工給予的獎勵資金。因此,「挖礦」的獎勵金額是遞減的,每四年會減半一次,會逐漸趨近於0。

也是因此,比特幣是一種不能隨意增發的貨幣。

3)比特幣的貨幣緊縮

貨幣緊縮不僅體現在上面提到的不能隨意增發。想像一下這樣的情景,Alice的擁有5個比特幣,但有一天,她的電腦完蛋了,硬碟上的數據全部丟失,包括她的私鑰,而且她沒有備份她的私鑰。這意味著什麼呢?她的5個比特幣將永遠無法使用,因為用公鑰倒推不出私鑰,而且其它人也沒有她的私鑰。這5個比特幣將永遠「死」去。

隨著時間的推移,像Alice一樣的人會越來越多,「死」去的比特幣也會越來越多,所以這也將加劇比特幣的緊縮。

4)隨機生成的私鑰

前面講到,每個用戶的私鑰是由比特幣錢包隨機生成的。可能有人會有疑問,這樣隨機生成的私鑰安不安全,會不會我隨機生成私鑰跟別人的私鑰恰好重複了?這個你不用過於擔心,因為,比特幣私鑰是一串很長的文本,理論上比特幣私鑰的總數是:

這是個什麼概念?有人估計過地球上的沙子是7.5乘以10的18次方,然後你想像一下,每粒沙子又是一個地球,這時的沙子總數是56.25乘以10的36次方,仍然遠小於比特幣私鑰的總數。所以在這樣一個龐大的地址空間下,私鑰重複的概率微乎其微。

5)六個區塊的證明

還記得上面提到的,某些特殊的情況下區塊鏈可能分叉,這些情況可能是惡意的雙重支付攻擊;也有可能是碰巧在同一時點,地球上兩個礦工節點同時計算出了小於目標值的Hash值,並同時發起了組包記賬(這種情況發生的概率極低,但確實曾經發生過)。分叉時,比特幣系統會自動選擇最長的鏈條,拋棄短的鏈條。在這種機制下,越新生成的區塊約有可能被拋棄,越早生成的區塊越穩定、越安全。

所以一般在比特幣網路上,會有一條不成文的約定,就是只有你的交易達成並被裝入區塊後,後面又生成了5個新區塊後(加上包含你交易的區塊總共6個區塊),你的交易才是基本安全的。以每10分鐘生成一個區塊的時間來計算,也就是你在交易被確認後1個小時左右才能真正確認你的交易是可靠的。

三、總結比特幣系統是如何運行的

最後,我們來把比特幣系統的運行方式串一遍,也算是一個總結。

1、首先,每個比特幣的用戶會通過比特幣客戶端生成一個私鑰,並通過私鑰生成公鑰(公鑰與收款地址相關性極強,可以簡單理解為收款地址就是公鑰),這等於就是這個用戶的戶頭~別人向這個人轉賬必須輸入這個收款地址。

2、用戶Alice向Bob轉賬時,輸入了Bob的收款地址,也即是用Bob的公鑰將這筆比特幣鎖定了,未來只有Bob才能使用這筆比特幣。

而用戶Alice為什麼能使用這筆比特幣呢?因為,比特幣系統可以追溯到上一筆Charles給Alice轉賬的交易,在那筆交易里,用戶Charles用Alice的轉賬地址,將比特幣鎖定,因此只有Alice使用其私鑰解鎖,才能夠使用這筆錢。

所以比特幣的絕大部分交易都是由inputs(來自),outputs(目標)組成。inputs用來追溯上一筆交易,以便明確轉出者是否有權動用這筆錢,outputs用來進行一次新的加密,加密後只有收款者才能解密並動用這筆錢。

3、交易發生後,將廣播全網。很短的時間內,全網所有的節點會接到這筆交易。接到這筆交易後,每個節點會先把交易放入內存,然後對交易進行合法性檢驗,檢驗通過後,這筆交易進入有效交易池,等待被裝入區塊。

4、與此同時,網路上面所有的礦工節點,正在瘋狂的計算著謎題。謎題的解題方式就是:將有效交易池裡的近千筆交易(TX0,TX1,TX2...),上一個區塊的Hash值,Nonce參數組合成一個文本,然後計算這個文本的Hash值。通過Nonce的不斷變化,計算出的Hash值也會不斷變化。

直到當某一個節點成功計算出小於目標值的Hash值,這個節點就解答出了謎題,並有權將計算Hash值所使用的信息組裝成一個新區塊,記錄在自己的硬碟上,並發起一次全網記賬。

周圍的節點在收到廣播的消息後,也都記錄下這個新區塊。

5、由於礦工節點每次都會使用含有上一個區塊Hash值的文本來計算當前區塊的Hash值,因此,每一個區塊都有上一區塊的基因,這使得區塊們串成了一個牢不可破的鏈條。

如果篡改某一區塊中的某一交易,那麼其後所有的區塊數據都無法匹配了。也就形成了區塊鏈不可篡改的特點。

6、比特幣系統就這樣周而復始的更新著自己的區塊鏈條,不斷的進行全網記賬,不斷的運行下去。

結語:

我從2011年開始接觸比特幣,還記得2013年自己買了一塊兒板卡,註冊到礦池挖礦的情景(當然好景不長,幾個月板卡就燒掉了~)。後來逐漸專註於比特幣技術原理。很早就關注這個話題,很早就希望在這裡把自己的所學所想與大家一起分享,但工作繁忙一直沒有時間起筆,直到6月份抽出時間開始寫起這篇文章。本來以為很快就能寫完,結果斷斷續續寫了兩個月。一些概念之前覺得挺明白的,但真要寫出來又模糊了,於是又翻了幾遍《精通比特幣》,鞏固了一下自己的知識。所以寫這篇文章對我來說也是收穫滿滿。

這篇文章個人認為還是比較容易讀懂的,但是篇幅有些長,所以如果你沒有耐心一次看完,可以收藏起來慢慢研究。個人認為文章中已經把比特幣的一些重要的概念都講到了,而且也算講的比較深入。文章中的很多配圖來自於一個叫做《How Bitcoin Works Under the Hood》的視頻(有一些配圖是我結合這個視頻的截圖及網路圖片自己製作出的動畫,希望您能喜歡)。這個視頻我認為也是快速、全面了解比特幣的一個很好的讀物,如果您感興趣也可以看看。在文章中,我根據自己的理解將視頻的一些講解順序做了調整,並以自己的敘述方式講解出來,以方便大家更好的理解「比特幣系統是如何運行的」。最後,感謝大家閱讀了這麼長的一篇文章~

(完)

我的公眾號:金融極客(Finance_Geek)

更新比較慢,最近有點荒廢了-__-||| 不過我會振作起來的!

我的比特幣地址:1P9hxaoznbwiKJiaLEsfpPEnffyoW9vU37

其他一些推薦的通俗易懂類文章,感興趣的朋友可以閱讀:

GRAYLAMB:作為一個非金融從業者怎樣才能看懂電影《大空頭》?

GRAYLAMB:如何通俗易懂地解釋「協方差」與「相關係數」的概念?

GRAYLAMB:如何淺顯易懂地解說 Paxos 的演算法?

GRAYLAMB:債券屬性「久期」的本質是什麼?


推薦閱讀:

米家掃地機器人這一則營銷做的不錯
數據產品經理的自我修養
偶遇一個釣魚網站,於是就簡單玩了一下...
滲透測試想入門?看這個

TAG:比特币Bitcoin | 区块链Blockchain | 互联网 |