Laikelib淺談區塊鏈技術架構

FLy_鵬程萬里發表於2018-08-22

   一旦你掌握了這些技術原理,就會發現,其實它的限制挺多,有美好的地方,也有沒必要的地方,那些莫名奇妙的專案就坑不到你了。

     最近一直在研究區塊鏈,算是從以前聽說過,到現在大概瞭解一些。先說下自己學習過程中的感受,那就是“能不能把話說明白些?”大部分學習材料都存在結構混亂,或者對一個點單薄,無法深入淺出。至於那些還在拿著露天麥喊什麼是區塊鏈,錯過後悔一輩子的,都是騙子。

     我相信現在很多投資機構都在瞄區塊鏈,今年,即使AI也沒有區塊鏈這麼火爆。那麼對於一個區塊鏈專案,到底靠不靠譜,是在畫餅,還是真的可能搞成,所有人都應該擦亮眼睛。

 

     三個最底層的技術

     談區塊鏈最好先拋開各種幣的價值,價值亦或叫價格這種東西你懂的,貴和便宜根本不是人能控制的。但是基於區塊鏈技術去做專案,卻是實實在在可以可持續發展。所以,瞭解區塊鏈技術比炒幣來的實在。

     “區塊鏈”三個字並不能闡明這項技術的全部,如果要非要用可以完整表達的命名,我覺得應該叫“Peer-to-Peer Encrypted Non-Tampered Database”,即“點對點的加密化不可篡改資料庫”。

     它不一個資料庫(比如MySQL,MongoDB),也不是一類資料庫(比如SQL,NoSQL),它是一種資料庫架構,它在資料庫本身的技術上還上升了一層,考慮到資料的可靠性保證,以及資料庫服務如何不下線。因此,你不能把它跟普通的某個有名字資料庫拿來類對比,甚至你可以在某一個具體的區塊鏈實現時,使用其他的資料庫來幫助儲存和檢索資料。

 

     資料關係加密化

     在我們普通的資料庫中,無論是關係型還是非關係型,我們的不同記錄之間可能存在關係,也可能不存在關係,但在區塊鏈中,一條資料一定和另外一條資料存在聯絡,即使在現實的業務邏輯上沒有聯絡,但是它總是存在於鏈上,無法脫離鏈而存在,總有一條路徑從一個資料出發到達另外一個資料。

     “區塊”表達了區塊鏈裡面資料關係的最終呈現形式,一條記錄,無論它是什麼資訊,最終它(或它的檢索資訊)都要被放置在一個區塊中。而區塊與區塊之間,是一個“連結串列”的資料關係,會程式設計的人都知道什麼是連結串列,就是後一個資料中存在指向前一個資料的索引鍵。因此,區塊鏈上的任何兩個資料永遠可以通過這些索引鍵最終連在一起,資料無法逃離這個邏輯。

     但是“區塊鏈”這三個字無法闡述這樣的資料結構和普通資料庫結構之間的不同,因為上面描述的這種連結串列資料結構,用普通的資料庫也可以構建出來,只要你想要的話。

     Laikelib區塊鏈系統底層高階架構師許義霖認為,真正的價值在於區塊鏈運用了密碼學的原理。現有的加密技術,把這些索引關係進行了層層加密,以至於在儲存的資料中,這些索引鍵並沒有那麼明顯,而是需要通過各種計算才能得到。

 

     資料不可篡改

     區塊鏈上的資料是不可篡改的,大家都這樣說。但其實,資料是可以改的,只是說改了以後就你自己認,而且被修改資料所在區塊之後的所有區塊都會失效。區塊鏈網路有一個同步邏輯,整個區塊鏈網路總是保持所有節點使用最長的鏈,那麼你修改完之後,一聯網同步,修改的東西又會被覆蓋。這是不可篡改的一個方面。

     更有意思的是,區塊鏈通過加密校驗,保證了資料存取需要經過嚴格的驗證,而這些驗證幾乎又是不可偽造的,所以也很難篡改。加密並不代表不可篡改,但不可篡改是通過加密以及經濟學原理搭配實現的。這還有點玄學的味道,一個純技術實現的東西,還要靠理論來維持。但事實就是這樣。這就是傳說中的挖礦。

     挖礦過程其實是礦工爭取建立一個區塊的過程,一旦挖到礦,也就代表這個礦工有資格建立新區塊。

     怎麼算挖到礦呢?通過一系列複雜的加密演算法,從0開始到∞,找到一個滿足難度的hash值,得到這個值,就是挖到礦。這個演算法過程被稱為“共識機制”,也就是通過什麼形式來決定誰擁有記賬權,共識機制有很多種,區塊鏈採用哪種共識機制最佳,完全是由區塊鏈的實際目的結合經濟學道理來選擇。

     挖完礦沒完,拿LKT幣來說,接下來礦工要把被廣播到網路中的交易打包到這個區塊裡,一筆交易是不是合法的呢?發起這筆交易的人是不是偽造了一筆交易?要確保一筆交易的合法性,必須從已經存在的前面的區塊裡面去找到這筆交易的來源的真實性,而如何驗證交易真實性呢?

     在前面的區塊裡,儲存著交易來源的merkle root hash,只要找出這個交易所在的區塊,再做一次merkle校驗,就可以判定交易是否是合法的。得到merkle root hash是通過區塊內的所有交易不斷加密得到的,因此,只要交易是假的,就得不到這個merkle root hash。加密在這裡又幫助實現了資料的可靠性。

     區塊鏈裡面的加密比比皆是,這些加密規則和演算法,使得整個區塊鏈遵循一種規律,讓篡改資料的成本特別高,以至於參與的人對篡改資料都沒有興趣,甚至忌憚。這又是玄學的地方。

 

     點對點網路讓資料永不下線

     如果區塊鏈沒有p2p網路,僅僅是按照前面的描述,有加密體系,有鏈式特徵,然後執行在某一臺(組)伺服器上,按照我們現在中心化的模式執行,看上去也挺好玩的。但是發明者想玩的更大些,加密體系讓資料不可篡改,但是我直接拋顆原子彈把你機房炸掉,不是不可篡改,是直接玩兒完了。

     為了防止被原子彈炸掉機房,發明者設計了點對點的網路(客戶端和客戶端直接通訊,不經過某一臺特定的伺服器)到區塊鏈裡面。簡單說就是在這個點對點網路裡面,所有人的電腦裡保管著一模一樣的一個資料結構(其實就是一個完整的“區塊”“鏈”),它們相互通過網路連線,進行同步,當礦工建立了新的區塊,其他人就會把這個區塊同步到自己保管的資料結構中。因此,無論這個網路上哪一個節點被炸,其他節點都還活著,新加入的小夥伴就可以從這些節點裡同步資料到自己的電腦。想要讓區塊鏈資料消失,那把地球炸了吧。

     而這種加入點對點網路的設計,就叫“去中心化”,只要網路上還有一個節點活著,區塊鏈的資料就不會消失。

     更讓政客們害怕的是,這些儲存的資料,節點上的使用者可以隨便看,無所謂,完全公開。節點使用者既然把資料同步過來了,你就可以隨便用,就是你的資料了,想怎麼用就怎麼用。試想一下,哪天淘寶說我要把自己的資料區塊鏈化……目不忍視……

 

     核心技術概念

     1、區塊

     區塊是區塊鏈的主要資料儲存結構,一個區塊包含區塊頭和區塊體兩個部分。而區塊頭則是區塊的重頭戲。

     對於一個區塊而言,它就是一個特殊的資料結構。它的區塊頭包含了一些固定資訊:版本、塊高度、塊雜湊、上一個塊的塊雜湊、時間戳、難度和Nonce、merkle root。除了這些欄位,如果做一個自己的區塊鏈,還可以新增一些其他資訊到區塊頭中。

     區塊體是儲存具體內容的位置,在比特幣的區塊鏈中,區塊體儲存的是一段時間的交易資訊。在其他區塊鏈中,這裡可不一定儲存的是交易資訊,可能是其他資訊,總之區塊體是儲存該區塊鏈用來做什麼業務的具體業務資訊。

     在部分割槽塊鏈實現中,一個區塊還可以有區塊尾,用來儲存一些區塊建立結束之後的資訊,這些資訊可能是區塊頭和區塊體已經建立完以後,附加上去的,比如區塊的長度、容量等資訊。

     這就是一個區塊。而一個區塊頭中的previousHash欄位,儲存的是上一個區塊的hash值,因此,通過這個區塊就知道了上一個區塊是哪個,上一個區塊又能知道上上個區塊,直到可以追溯回整個鏈條的第一個區塊。這就是區塊鏈。

     後面一個區塊總是指向前一個區塊。一旦一個區塊生成,並且後面有區塊指向它,那它就不能被修改,因為一旦修改,所有的hash都需要重新計算。但是我們知道,hash演算法的特點是想要得到這個hash必須用原始內容進行一遍hash演算法,所以,如果給的內容和原始內容不同,是得不到這個hash的,所以,中間某個區塊鏈被修改而得到的hash,不可能被後面的區塊指向,區塊鏈就會斷掉。斷掉的區塊鏈加入到網路中,要麼不被認可,別的節點不會把你當作合法節點,要麼你要再同步一遍,從網路中重新複製最長的鏈到你的本機覆蓋原來的鏈。

     但是你可能會有兩個疑問:1.這個blockHash又不是內容的hash,怎麼確保區塊體內的資訊不被修改呢?要是我不改blockHash,只改內容,那不是可以瞞天過海?2.如果有兩個區塊同時指向了一個區塊,而這兩個區塊的區塊體不一樣,這該怎麼辦?

     第一個問題,我們需要通過後面的挖礦和merkle tree兩部分結合,知道這個原理。第二個問題,實際上,這種情況非常常見,挖礦成功的概率其實是100%,關鍵在於哪一位礦工先挖到礦,一般當礦工挖到礦之後,會向全網廣播,其他沒有挖到礦的礦工就會停止。但是由於網路延時等情況,可能在短時間內多個礦工一起挖到礦,他們都建立了新的區塊,並且廣播到了網路中。這種情況叫“分叉”。

     當分叉發生的時候,有兩種辦法。但都是順其自然,無法人工干預。後面挖新塊的礦工,會自己決定把哪一個分支最後的塊作為自己的前一個塊。如果在比較短的塊數內,一條鏈明顯長於另外一條鏈,那麼長的鏈會被保留,短的會被拋棄,挖短鏈的礦工算是白乾了一場。所有的網路節點在同步的時候,都會選擇當前最長的鏈進行同步,後面挖礦的礦工建立新塊的時候也是選擇最長的鏈。

     但是還有一種情況,就是短鏈的礦工不依不饒,或者短時間內兩條鏈無法分出勝負,甚至最後每條鏈都有了很多塊跟在後面。一幫人的轉賬總不能有兩個賬單吧,如果兩個賬單最後發現還不一樣就麻煩了。

     所以遇到這種情況,礦工們會決定分家。也就是一個區塊鏈變成了兩個鏈,其中一條鏈把前面的所有鏈複製出來,成為獨立的鏈,從此這兩條鏈再無瓜葛,雖然前面的區塊都是一摸一樣的,但是後面井水不犯河水,這種情況叫“硬分叉”。新產生的鏈繼承了前面的區塊,但是後面的區塊完全是挖這條鏈的礦工決定的。硬分叉的好處是,對於原來的使用者而言,突然之間,自己的一份資產變成了兩份。

     2、挖礦和共識機制

     簡單說挖礦過程就是一堆礦工在搶建立一個新區塊的權利的過程。

     在加密貨幣的世界裡,搶到這個權利,就會在這個區塊的最前面加上一筆轉賬給自己的交易,而這個交易的錢是憑空而來的,所以又叫“挖礦獎勵”,而且數額還不少,所以礦工才擠破腦袋搶這一個記賬權。但是在其他非幣區塊鏈應用裡,假如沒有這個獎勵,怎麼激勵礦工挖礦呢?這也是區塊鏈領域裡一個玄而又玄的話題,至今沒有答案。

     那麼挖礦挖礦,到底是怎麼一個技術上的演算法過程呢?

     在礦機程式裡,規定了如何得到一個hash,而這個規定,就被稱為共識機制,所有礦工按照這個共識機制去進行某個演算法,看誰先得到一個符合條件的結果,而這個結果又可以被輕而易舉的驗證是符合條件的(驗證是否符合共識機制)。不同的區塊鏈,共識機制不同,目前比較知名的是PoW和PoS,以及在這兩者基礎上衍生出來的其他共識機制。

     區塊鏈適合什麼不適合什麼?區塊鏈資料的特徵主要有兩點:

     1.公開透明,任何節點對資料有完全的權利去檢視;

     2.難以偽造或篡改。

     因此,區塊鏈非常適合兩類場景:1.證據;2.監督。

     如果區塊鏈上的資訊得到法律認可,那麼但凡拿出區塊鏈上的證據,侵權方將百口莫辯。而試想,如果將稅收完全遷移到區塊鏈,每個公民的每一筆稅收,最後都用到哪裡,一清二楚,這可能是令某些人害怕的點。但區塊鏈有兩大缺點:1.要挖礦,還有分叉風險,也就是說一個資料放到區塊鏈上,要等很久才能成為不可篡改的可信資料。2.分割槽塊,資料被割裂存放,這給查詢帶來巨大的麻煩,非常影響效率。所以,區塊鏈不適合那種即時性要求高的場景,無論是資訊交換的即時性(例如聊天)還是查詢的即時性(如搜尋引擎)。區塊鏈不是萬能的,某些服務明明中心化模式效率更高,成本更低,卻偏要為了風口搞區塊鏈化,那隻能看韭菜長沒長齊。還有一點令人擔心的是,由於區塊鏈上資訊的公開透明,而且不可刪除,是否會對個人隱私造成極大的損害,試想一下,當年給冠希哥修電腦的小哥通過區塊鏈網路炫耀自己發現的照片……那對當事人的傷害……連人死了都不會消散……區塊鏈應用隨著風口的來臨,區塊鏈應用此起彼伏。

     一個區塊鏈應用,它的架構是怎樣的呢?在區塊鏈本身之上,還需要有哪些其他的技術來支撐呢?

     區塊鏈應用中會把區塊鏈拆解之後,於應用其他層進行融合,最終實現應用的整體功能。之所以比特幣裡面的每一筆錢的來龍去脈都一清二楚,就是依賴於交易模型。我們現實中銀行裡面的一個賬號,只會告訴你一個賬號現在有多少錢,曾經花了多少錢,收入多少錢,還欠多少錢。但是不會告訴你“某一筆你花掉的錢,來自你某一筆收入”。但比特幣裡面必須告訴你這樣的邏輯,一條交易包含“輸入”和“輸出”兩個部分,比如你要轉10BTC,那麼你的賬號必須有一個或多個“輸入”加起來總和等於或超過10BTC,而輸出就是指你要把這10BTC轉給誰。但是有一種情況,當所有“輸入”加起來為10.5BTC時怎麼辦,就像你有100塊毛爺爺,去買70塊的東西一樣,需要“找零”。所以“輸出”有的時候會有一個是轉給自己的,就是“找零”。

     比特幣交易輸入與輸出示意圖而實際上,輸出在另外一個交易中,又是這個新交易的輸入。在區塊體裡面,這些交易記錄,以及它們的輸入輸出都被如實記錄。

     除此之外,還要進行merkle計算,將merkle root存到區塊頭中。

     身份認證體系既然是交易,那麼必然涉及到交易雙方的身份。比特幣交易的兩端是兩個賬號,至於到底是誰它不管,但它通過加密演算法,保證這一筆交易是哪一個賬號發起的,發起交易的人要對交易資訊進行簽名。你可能聽過非對稱加密、公鑰和私鑰。比特幣賬號最關鍵的就是這個私鑰,一旦私鑰丟失,你就無法證明自己是這個賬號的主人,也就無法從賬號中進行轉賬要做的簽名動作,你就不能再花這個賬號裡面的幣,也就丟失了幣。

     那麼簽名是怎樣的一個過程?怎麼證明這個交易是我發出的?怎麼證明這錢是轉給我的?

     金鑰、地址與錢包金鑰

     通常指的是保護比特幣資產的對應於所有權使用者的私鑰,個別時候也會模糊的統稱私鑰和公鑰為金鑰,這裡我們以狹義的私鑰解釋為準。地址 比特幣的收款地址,大部分情況下是指對公鑰的封裝(個別時候除了公鑰還有指令碼)。錢包 一種比特幣客戶端軟體,是私鑰的容器,通常通過有序檔案或者簡單的資料庫實現。比特幣錢包包含私鑰和公鑰資料,儘管公鑰資料理論是是不需要儲存的。一般來說,使用者的公鑰和比特幣地址可以劃等號,但實際上不是。比特幣地址是一串比公鑰短很多的字串,主要是為了方便輸入。而公鑰則用於各種非對稱加密。

     比特幣公鑰到比特幣地址公鑰和地址都是公開在比特幣網路中的,只有私鑰是使用者自己儲存,不能給任何人。當一個交易發起時,交易發起方用“自己的私鑰”和“接收方公鑰”對交易進行簽名,那麼網路中的其他人就可以用發起人的公鑰去驗證這個交易是不是他發起的,對於接收方而言,要提供自己的私鑰進行解密運算,來證明這個交易確實是傳送給自己的。而比特幣客戶端(錢包)就是幹這個加密解密和簽名的事。

     智慧合約比特幣本身已經有智慧合約的雛形,只是它所採用的程式語言指令碼能力比較弱,能實現的合約邏輯不復雜。以太坊則是在這個基礎上擴充套件鏈智慧合約部分,使智慧合約的程式設計能力大大增強。在上文提到的輸入和輸出,輸出其實就被作為另外一個新交易的輸入。比特幣的輸出不單單是告訴系統要轉給哪個地址多少錢,輸出實際上是一段比特幣指令碼。這段指令碼也經過複雜的非對稱加密,要執行這段,想要得到一個輸出裡面的錢,把這筆錢作為自己交易的輸入,必須用自己的私鑰先解密指令碼,然後執行指令碼,指令碼執行完,這筆錢就可以作為自己交易的輸入了。結合前面的知識,只有擁有對應的私鑰才能解密,所以,只有輸出記錄對應的比特幣地址對應的那個使用者才能解密指令碼,得到這些錢。在這個過程裡面,“指令碼”是一個關鍵,除了上面這種最簡單的轉賬邏輯,還可以通過一些條件判斷來實現稍微複雜一些的程式設計,比如只有當滿足某些條件的時候,解密後的指令碼才能執行。於是,基於這種設計,比特幣的指令碼系統可以用來實現多重簽名、保證合同等功能,也就是智慧合約的雛形。

相關文章