比特幣的支付流程及原理
在比特幣的世界里,用戶都有一個表示自己身份(或者也叫地址)的標(biāo)識。這個標(biāo)識是該用戶的公鑰信息(用base58做了一層編碼)。有公鑰就自然有私鑰,只不過私鑰是不公開的,只有你自己知道(這個很重要喲)。
假設(shè)A要給B轉(zhuǎn)賬5 BTC(比特幣簡寫),這條信息會在整個比特幣網(wǎng)絡(luò)里廣播,收到廣播的每個節(jié)點(diǎn)(包括A和B本身)都更新自己本地的賬本(A減少5 BTC,B增加5 BTC)。這樣交易就完成了。似乎很簡單。不過很容易就會想到一個問題:如何證明這條廣播消息的合法性?
關(guān)鍵是要證明這條廣播是由A發(fā)出的,而不是其他人。這里就用到了數(shù)字簽名的原理了:
A會對該條廣播用自己的私鑰做個簽名,網(wǎng)絡(luò)中的其他節(jié)點(diǎn)用A的公鑰驗證這個簽名(數(shù)字簽名的原理這里就不多說了,不明白的自行谷歌),驗證通過后,才會更新本地的賬本。
其他人因為沒有私鑰,所以無法偽造這樣的廣播。知道私鑰的重要性了,如果你的私鑰被破解,分分鐘傾家蕩產(chǎn)啊!
比特幣所用的數(shù)字簽名是基于非對稱的橢圓曲線算法,有興趣的可以研究下。

圖片來自網(wǎng)絡(luò)
簽名的數(shù)據(jù)源
簽名的原理雖然這里不多說,但是用于簽名的數(shù)據(jù)源還是要搞明白。
數(shù)據(jù)源是A的前一筆交易和B的公鑰組成的,后者很容易獲取,就是B的地址。那么A的前一筆交易怎么理解呢?

圖片來自網(wǎng)絡(luò)
比特幣的網(wǎng)絡(luò)并不會記錄每個人的余額,比如A有100個比特幣,B有30個比特幣。網(wǎng)絡(luò)里記錄的是每個人的交易信息,簡單來講,進(jìn)賬是+, 出賬是-。每次交易時把交易遍歷一遍就可以知道你有多少錢。
這種機(jī)制的核心就是保證了每一筆交易都不是獨(dú)立的,都要援引以前的交易,所以比特幣的交易信息在網(wǎng)絡(luò)中就以某種鏈條的方式傳遞。
這里有一條規(guī)則,每一筆交易都要把所有的進(jìn)賬用完,然后把余額發(fā)送給自己。舉個例子,A初始有100 BTC(可以認(rèn)為是系統(tǒng)初始分配的),然后A要從B那里購買一個商品,需要付給B 20 BTC,A首先會把之前所有的進(jìn)賬用完(100 BTC),然后發(fā)現(xiàn)實際付款的金額(20 BTC)和援引的進(jìn)賬不同,就把差額(80 BTC)發(fā)送給自己。
雙重支付(double spending)
不記錄余額是為了防止偽造賬簿,篡改余額。有人可能要問了,交易不會被偽造嗎。當(dāng)然有可能。

圖片來自網(wǎng)絡(luò)
如上圖,惡意用戶A援引一條他的進(jìn)賬信息(Frank 以前某個時間轉(zhuǎn)給他5個比特幣,說明他余額是足夠的),向B買一個貨物,他廣播5 BTC付款給了B。同時A又援引同一個進(jìn)賬信息,廣播給自己5 BTC。B收到A的轉(zhuǎn)賬信息后,發(fā)貨。
但是由于網(wǎng)絡(luò)傳播時間的差異,網(wǎng)絡(luò)中的某些節(jié)點(diǎn)有可能先收到第二筆廣播,然后這條進(jìn)賬信息就會被標(biāo)記為已使用,而另外一些節(jié)點(diǎn)先收到第一筆廣播,大家都認(rèn)為自己先收到的那個是合法的,那就無法確認(rèn)這5 BTC到底是A的,還是B的。最慘的是B,損失了貨物又損失了金錢。
這就是所謂的比特幣雙重支付陷阱。
在傳統(tǒng)的貨幣體系中,這個問題是非常好解決的,因為有個中心機(jī)構(gòu)(銀行)幫你來驗證每筆交易,但是比特幣的核心就是去中心化,沒有這個所謂的中心機(jī)構(gòu)。
如何解決這個問題呢? hashcash終于要登場了!
hashcash的原理可以參考另一篇文章,這里不再贅述。
關(guān)于hashcash
區(qū)塊鏈和hashcash
區(qū)塊鏈的概念:
交易進(jìn)行時間排序,然后根據(jù)排序結(jié)果分組,每個組就是一個區(qū)塊,把這些區(qū)塊鏈接起來就是區(qū)塊鏈。

圖片來自網(wǎng)絡(luò)
什么是區(qū)塊的信息
同一個區(qū)塊的交易是同一時間發(fā)生的,交易的數(shù)量可以任意。區(qū)塊內(nèi)的這些交易唯一的標(biāo)識了該區(qū)塊。這個的標(biāo)識其實就是每筆交易的hash結(jié)果的組合。而每筆交易的hash又是由各自交易的信息(比如交易時間,交易的買賣雙方地址等)。
除了hash結(jié)果的組合,區(qū)塊中還有其他信息,比如時間戳,隨機(jī)數(shù)等。這個隨機(jī)數(shù)對后面"猜答案"非常的重要,這里先賣個關(guān)子。
總之結(jié)果就是每個區(qū)塊都有一個唯一的對外信息。記住這個就行了。

圖片來自網(wǎng)絡(luò)
如何加入?yún)^(qū)塊鏈
只要一個區(qū)塊能加入現(xiàn)有的區(qū)塊鏈中,它就是一個合法的區(qū)塊。所以如何加入?yún)^(qū)塊鏈?zhǔn)顷P(guān)鍵。
比特幣網(wǎng)絡(luò)中的任何節(jié)點(diǎn)(比如你自己)都可以生成區(qū)塊,并且都可以申請加入現(xiàn)有的區(qū)塊鏈。
那么比特幣網(wǎng)絡(luò)如何決定區(qū)塊鏈的下一個區(qū)塊是哪一個呢?可能同一時間會有多個不同的節(jié)點(diǎn)生成新的區(qū)塊,所以節(jié)點(diǎn)不能依靠接收到區(qū)塊的順序來決定。
比特幣通hashcash來解決這個問題。
前面提到,每個區(qū)塊除了基本的交易信息外,還有個隨機(jī)數(shù),這些信息就是hashcash中所謂的戳記。而這個隨機(jī)數(shù)就戳記的第7域。也就是不斷嘗試要滿足前綴N個比特位都是0這樣的條件。(這個N會根據(jù)計算機(jī)的不斷發(fā)展而增加已提升難度,達(dá)到計算的平衡)

圖片來自網(wǎng)絡(luò)
只有當(dāng)達(dá)到了條件才會被接受作為區(qū)塊鏈的一環(huán)。這也被稱為工作證明(proof of work)。生成區(qū)塊的節(jié)點(diǎn),需要證明本節(jié)點(diǎn)投入了足夠多的運(yùn)算資源去求解一個數(shù)學(xué)難題。
區(qū)塊鏈如何防止雙重支付
一個交易是否合法關(guān)鍵是能否加入一個有效的區(qū)塊鏈。假設(shè)A付款給B,B等交易被確認(rèn)加入一個鏈中,然后發(fā)貨。
A偽造了一筆交易,把錢有退回給自己。如果要被整個網(wǎng)絡(luò)認(rèn)可這筆交易,A必須自己生成一個比原來的鏈長的區(qū)塊鏈并把這筆交易加入鏈中。但事實上,這幾乎是無法做到的。一臺計算機(jī)甚至要花幾年的時間去"猜"一個區(qū)塊,而整個網(wǎng)絡(luò)中的計算機(jī)的力量只要幾分鐘就可以解出來。個人要想偽造一筆交易達(dá)到雙重支付s要跟整個比特幣網(wǎng)絡(luò)競爭。你的計算速度再快,也不可能快過整個網(wǎng)絡(luò)。

圖片來自網(wǎng)絡(luò)
礦工
前面提到攻擊者需要和整個比特幣網(wǎng)絡(luò)的計算能力競爭,這個計算能力的貢獻(xiàn)大部分就是來自一些個人或者組織(現(xiàn)在大部分是組織了,個人很少),他們通過貢獻(xiàn)自己的計算資源來求解區(qū)塊。這些組織我們稱之為礦工。曠工的存在讓比特幣的整個系統(tǒng)更加安全。礦工的作用是驗證交易和維護(hù)區(qū)塊鏈。而他們工作的獎勵就是比特幣。
區(qū)塊鏈越長越安全
這個很好理解,一個交易處于鏈中越靠后的位置,就越難被篡改。因為比特幣網(wǎng)絡(luò)只接受最長的一條區(qū)塊鏈作為有效的區(qū)塊鏈,這樣,對于攻擊者來說,引入一個虛假區(qū)塊不僅需要解一個數(shù)學(xué)問題,而且需要和其它正常的節(jié)點(diǎn)競爭,生成所有的后續(xù)節(jié)點(diǎn)才能使其它節(jié)點(diǎn)接受自己的區(qū)塊鏈作為有效鏈,這變得幾乎不可能。