1.1 例說區塊鏈

1.1.1 從一本賬本說起

早些時候,農村一般都會有個賬房先生,村裏人出個工或者買賣些種子肥料等,都會依靠這個賬房先生來記賬,大部分情 況下其他人也沒有查賬的習慣,那個賬本基本就是這個賬房先生保管着,到了年底,村長會根據賬本餘額購置些瑣碎物件給村裏人發發,一直以來也都是相安無事, 誰也沒有懷疑賬本會有什麼問題。賬房先生因爲承擔着替大家記賬的任務,因此不用出去幹活出工,額外會有些補貼,僅此一點,倒也是讓一些人羨慕不已。下圖便 是當時賬本的記賬權圖示:

image.png

終於有一天,有個人無意中發現了賬房先生的那本賬。看了下賬面,發現數字不對,最關鍵的是支出、收入、餘額居然不能平衡。對不上,這可不行,立即報告給其 他人,結果大家都不幹了,這還得了。經過一番討論,大家決定,輪流來記賬,這個月張三,下個月李四,大家輪着來,防止賬本被一個人拿在手裏。於是,賬本的 記賬權發生瞭如下圖所示的變化:

image.png

通過上圖我們可以看到,村裏的賬本由大家輪流來保管記賬了,一切又相安無事了,直到某一天,李四想要挪用村裏的公款, 可是他又怕這個事情被後來記賬的人發現,怎麼辦呢?李四決定燒掉賬本的一部分內容,這樣別人就查不出來了,回頭只要告訴大家這是不小心碰到蠟燭,別人也沒 什麼辦法。

果然,出了這個事情以後,大家也無可奈何。可是緊接着,趙六也說不小心碰到蠟燭了;王五說不小心掉水裏;張三說被 狗啃了……終於大家決定坐下來重新討論這個問題。經過一番爭論,大家決定啓用一種新的記賬方法:每個人都擁有一本自己的賬本,任何一個人改動了賬本都必須 要告知所有其他人,其他人會在自己的賬本上同樣地記上一筆,如果有人發現新改動的賬目不對,可以拒絕接受,到了最後,以大多數人都一致的賬目表示爲準。

果然,使用了這個辦法後,很長一段時間內都沒有發生過賬本問題,即便是有人真的不小心損壞了一部分賬本的內容,只要找到其他的人去重新複製一份來就行了。

然而,這種做法還是有問題,時間長了,有人就偷懶了,不願意這麼麻煩地記賬,就希望別人記好賬後,自己拿過來覈對 一下,沒問題就直接抄一遍。這下記賬記得最勤的人就有意見了。最終大家開會決定,每天早上擲骰子,根據點數決定誰來記當天的賬,其他人只要覈對一下,沒問 題就複製過來。

我們可以看到,在這個時候,賬本的記賬權變成了這樣:

image.png

通過上圖,我們可以看到,經歷了幾次風雨之後,大家終於還是決定共同來記賬,這樣是比較安全的做法,也不怕賬本損壞丟失了。後來大家還決定,每天被擲到要記賬的人,能獲得一些獎勵,從當天的記賬總額中劃出一定獎勵的比例。

實際上,最後大家決定的做法,就是區塊鏈中記賬方法的雛形了,接下來我們就來了解一下區塊鏈的技術理念。

1.1.2 區塊鏈技術理念

區塊鏈在本質上就是一種記賬方法,當然了,並不是通過人來記賬的,而是通過一種軟件,我們暫且簡稱爲區塊鏈客戶 端。以上面的例子來說,張三、李四、王五、趙六等人,就相當於一個個的區塊鏈客戶端軟件,它們運行在不同的設備上,彼此之間獨立工作。通常我們把運行中的 客戶端軟件稱爲「節點」。這些節點運行後,彼此之間會認識一下。它們彼此之間是這樣認識的:張三認識李四也認識王五,趙六聯繫到了張三,讓張三把他認識的 人的聯繫方式發給自己,這樣趙六也認識了李四和王五,通過這樣的方式,大家就形成了一張網,有什麼事只要招呼一聲,立馬消息就會傳遍整個網絡節點。這種方 式跟新聞轉發差不多,不需要依靠某一個人,大家就能互通消息了,在區塊鏈軟件的結構中,這種互相通信的功能稱爲「網絡路由」。

在這個網絡中,每個節點都維護着自己的一個賬本,賬本中記錄着網絡中發生的一筆筆賬務。具體是什麼樣的賬務呢?這 得看具體是什麼樣的功能網絡。區塊鏈技術屬於一種技術方法,可以用來實現各種不同的業務功能,小到如上例中的日常記賬,大到各種複雜的商業合約,等等,記 錄的數據也就不同了。網絡中的節點是獨立記賬的,可是記賬的內容要保持彼此一致。所用的方法就是設定一個遊戲規則,通過這個規則選出一個記賬的節點,就如 上例中的擲骰子。在區塊鏈系統中,這個所謂的「擲骰子」稱爲「共識算法」,就是一種大家都遵守的篩選方案,我們可以先這麼簡單地理解。選出一個節點後,則 一段時間內的賬務數據都以這個節點記錄的爲準,這個節點記錄後會把數據廣播出去,告訴其他的節點,其他節點只需要通過網絡來接收新的數據,接收後各自根據 自己現有的賬本驗證一下能不能接得上,有沒有不匹配和不規範的,如果都符合要求,就存儲到自己的賬本中。

在有些系統中,會考慮到被骰子投中的節點的勞動付出,畢竟它要負責整理數據,驗證數據,打包數據,還要再廣而告 之,這個活還是挺辛苦的。於是會設計一種激勵機制,負責打包數據的那個節點可以獲得系統的獎勵,這個獎勵類似於論壇積分,站在軟件技術的角度,就是一個數 據。這個數據可以視爲獎金,有時候大家會很積極地去爭取那個獎金,於是就希望骰子能投中自己,有些區塊鏈系統在這個環節會設計出一種帶有競爭的機制,讓各 個節點去搶,誰能搶到這個機會誰就能獲得打包數據的權力並且同時獲得這筆獎勵,在這種情況下,我們會形象地將這個競爭的過程稱爲「挖礦」。

那麼,話又說回來了,我們將一個個運行客戶端稱爲節點,那到底怎麼標記不同的使用者呢?也是通過用戶名註冊嗎?實 則不然。在區塊鏈系統中,這個地方的設計很有意思,是通過一種密碼算法來實現的,具體來說是通過一種叫公開**算法的機制來實現的。我們知道,對於一種密 碼算法來說,無論算法過程是什麼樣的,都會有一個**。而公開**算法擁有一對(也就是兩個)**,跟虎符一樣,是彼此配合使用的,可以互相用來加解密。 其中一個叫私鑰,另外一個叫公鑰,公鑰可以公開給別人,私鑰要自己保管好。在區塊鏈系統中,公鑰就是用來用戶身份識別的,一般不會直接使用公鑰,因爲不容 易讓人記住。公鑰往往都比較長,實際處理的時候都會進行轉換,比如取得公鑰的最後20個字節或者經過一系列更復雜的轉換,最後得到一個稱爲「地址」的轉換 結果,這個「地址」就能代表一個用戶。

爲什麼在區塊鏈系統中要用這麼一個奇怪的用戶身份表示方法呢?似乎看起來除了有些創意外,也沒特別的用處。這裏我 們就得再介紹下這個公開**算法的特別能力。之前提到說這種算法有兩個**,那麼這兩個**是怎麼配合工作的呢?我們來簡單說明一下:用公鑰加密的數據必 須用對應的私鑰來解密,而用私鑰加密(通常稱爲「簽名」)的數據必須用對應的公鑰來解密。這個特點可是能發揮很大用處的,就如上述的例子中,如果張三要發 送給李四一張支票,那怎麼傳送呢?就這麼發過去,會被那個記賬的人拿到,風險可就大了。於是張三想了一個辦法,他在支票上用李四的公鑰加了個密,然後再籤 上自己的名字(使用自己的私鑰簽名),這個時候其他人就算拿到支票也沒用,因爲只有李四纔有自己的私鑰,也只有李四才能解開這張支票來使用。這種功能設計 在區塊鏈系統中稱爲「腳本系統」。

現在我們知道了,區塊鏈的技術理念,其實就是大家共同來參與記賬,通過一種規則不斷地選出賬務打包者,其他節點接收驗證,並且每個用戶都有一對**表示自己,通過腳本系統的功能實現在公共網絡中定向發送有價值的數據。

1.1.3 一般工作流程

通過上面的例子,相信讀者朋友對區塊鏈已經有了基本認識。區塊鏈系統有很多種,第一個應用區塊鏈技術的軟件就是比 特幣,事實上區塊鏈的概念就是比特幣帶出來的。到現在爲止,已經出現了相當多的基於區塊鏈技術的衍生系統,比如閃電網絡、公證通、以太坊、超級賬本項目 等。每一類系統都有自己的特點,例如汽車設計,有的設計成跑車,有的設計成運輸車,有的設計成商務車,但是有一點,無論是什麼類型的車,它的工作方式或者 說工作流程都是類似的,在本質上它們都是同一類技術結構的產物。在這一小節,我們從一般性的角度闡述一下區塊鏈系統的工作流程,爲了便於說明,我們會選取 一些場景例子。

我們先來看一個轉賬交易的流程。轉賬交易本質上就是發送一筆數據,這個數據可以表示爲資產,也可以表示爲訂單或者其他各種形式的數據,我們看一下下面的圖示。

從圖中我們可以看到,整個數據的發送過程其實還是很簡單的,數據發送出去後,會被打包進區塊,然後廣播出去給所有 的節點確認,確認沒有問題後就寫入到各自的本地區塊鏈賬本中,當網絡中的大多數節點都確認寫入後,這個轉賬過程就算是完成了。有朋友可能會問,在這種分佈 式的網絡中,怎麼能知道是被大多數節點確認寫入了呢?這裏並沒有什麼服務器登記呀?這個問題我們先留着,在下面講到區塊鏈分類的時候會有詳細的解釋,大家 可以先思考一下。

image.png

這個工作流程圖是有代表性的,其他各種系統都是在這個基礎上進行衍生和擴展。比如有些會增加身份認證功能,以確保只有 符合身份驗證的用戶才能發送數據;有些則擴展交易數據的表達能力,不但能用來表示一般的交易轉賬,還能表示更復雜的商業邏輯。各種應用很多,但是萬變不離 其宗。

實際上,說一千道一萬,整個區塊鏈網絡,就是大家共同來維護一份公共賬本。注意了,這個公共賬本是一個邏輯上的概念,每個節點各自都是獨立維護自己賬本數據的,而所謂的公共賬本,是說各自的賬本要保持一致,保持一致的部分就是公共賬本,我們看下圖示:

image.png

如圖所示,有些節點在廣播新的數據,有些節點在接收數據,大家共同維護一個賬本,確保達成一致。區塊鏈技術其實就是圍繞如何保持數據的一致、如何讓這個公共賬本的數據不被篡改來展開的。爲了解決這些問題,區塊鏈技術擁有一套技術棧,我們通過以下章節來闡述。

來源:我是碼農,轉載請保留出處和鏈接!

本文鏈接:http://www.54manong.com/?id=121

'); (window.slotbydup = window.slotbydup || []).push({ id: "u3646208", container: s }); })(); '); (window.slotbydup = window.slotbydup || []).push({ id: "u3646147", container: s }); })();