程式必備區塊鏈基礎知識

Kaitiren發表於2018-03-17

區塊鏈(BlockChain),是區塊(Block)和鏈(Chain)的直譯,其資料結構如圖1所示,即每個區塊儲存規定時間段內的資料記錄,並通過密碼學的方式,構建一條安全可信的鏈條,形成一個不可篡改、全員共有的分散式賬本。


比特幣的區塊分為區塊頭和區塊體兩部分。區塊頭的大小為80位元組,包括4位元組的版本號、32位元組(256位)的上一區塊雜湊值、32位元組的Merkle根節點、4位元組的時間戳、4位元組的難度值和4位元組的隨機數。區塊體包含10分鐘內選定的交易記錄,第一筆交易(coinbase交易)是用於獎勵礦工比特幣的特殊交易,由礦工自己新增進區塊。


640?wx_fmt=png&wxfrom=5&wx_lazy=1

圖1  區塊鏈的資料結構示意圖


基本概念


區塊鏈是很多現有技術交叉融合在一起的整合創新。因此,要了解區塊鏈,首先要了解區塊鏈到底整合了哪些技術。


P2P網路


如圖2所示,P2P(Peer-to-Peer)網路是一種端到端的網路。P2P網路分為結構化(例如基於Chord的P2P網路)和非結構化的P2P網路(例如Gnutella)。比特幣的區塊鏈採用的是非結構化P2P網路,整個網路沒有中心化的硬體或管理機構,任一節點既是服務端,也是客戶端。任何節點只要安裝相應的客戶端軟體,就能接入P2P網路(例如BT軟體),參與區塊鏈的記錄和驗證,不超過1/3節點的損壞、退出甚至被植入惡意程式碼,都不會影響整個系統的運作。


640?wx_fmt=png

圖2  傳統中心化系統和P2P網路的拓撲對比圖


加密演算法和數字簽名


加密技術分為對稱、非對稱和雜湊(Hash)加密。對稱加密是指用同樣的金鑰來進行加密和解密,非對稱加密是指用一個金鑰對來進行加密和解密,雜湊加密主要是通過對資料進行雜湊運算,用固定的雜湊結果值驗證資訊是否被篡改。


非對稱加密


在非對稱加密技術中,對外公開、分發出去的金鑰叫做公鑰,不能公開、自己留存的金鑰叫做私鑰。公鑰加密的,對應的私鑰才能解密。反之亦然。如圖3所示。


640?wx_fmt=png

圖3  非對稱加密RSA演算法的簡化示例圖


非對稱加密演算法有RSA、DSA和ECC等種類,區塊鏈使用的是基於橢圓曲線加密技術的數字簽名(ECDSA),具體實現是secp256k1。ECDSA相當於是DSA和非對稱加密ECC的結合。相比RSA演算法,ECDSA具有計算量小、儲存空間小、頻寬要求低等特點。


數字簽名


基於數字簽名的通訊機制工作原理,如圖4所示,傳送報文時,傳送方用一個雜湊函式從報文文字中生成檔案摘要,然後用自己的私鑰對摘要進行加密,加密後的摘要將作為報文的數字簽名和報文一起傳送給接收方。接收方首先用與傳送方一樣的雜湊函式從接收到的原始報文中計算出報文摘要,接著再用傳送方的公鑰來對報文附加的數字簽名進行解密,如果得到的明文相同,那麼接收方就能確認傳輸的檔案並未受到篡改,是安全可信的。


640?wx_fmt=png

圖4  數字簽名的流程示意圖


雜湊加密


安全雜湊演算法(Secure Hash Algorithm,SHA)是由美國國家安全域性研發,由美國國家標準與技術研究院(NIST)釋出的一系列密碼雜湊函式,包括SHA-0、SHA-1、SHA-2和SHA-3等系列。比特幣的區塊鏈使用的是SHA-256雜湊加密演算法,於2001年釋出,屬於SHA-2分支。由於SHA256偽隨機性的特點,只要是相同的資料輸入,一定會得到相同的結果,如果輸入資料稍有變化,將得到一個千差萬別的結果,如圖5所示。SHA256還是一個單向不可逆的演算法,即根據一個輸入數算SHA256的結果很容易,但根據SHA256的結果反算輸入數幾乎是不可能。除此之外,比特幣還使用ripemd160演算法來生成比特幣錢包的地址。


640?wx_fmt=png

圖5  雜湊加密的示意圖


梅克爾樹


梅克爾(Merkle)樹是區塊鏈的基本組成部分。如果沒有梅克爾樹,區塊鏈也是可以運轉,但是要在區塊頭裡包含所有交易記錄,擴充套件性方面存在很大挑戰。如圖6所示,區塊鏈中的每個區塊,由區塊頭和區塊體構成,區塊頭中含有一個Merkle根節點的欄位,通過對區塊體中所有交易記錄,以二叉樹的形式迭代地兩兩拼接 、進行雜湊操作,可以得到一個最終的雜湊值,我們稱之為Merkle根雜湊。Merkle根雜湊相當於是對區塊中所有交易記錄進行了一個快照,區塊中交易記錄的任意改動都可以通過比較Merkle根雜湊而很容易地察覺。Merkle根雜湊主要用於簡單支付驗證(SPV),在驗證某個交易是否在區塊中時,也能極大地減少網路傳輸成本。


640?wx_fmt=png

圖6  Merkle樹示意圖


工作量證明機制


工作量證明機制,簡單地說,就是一種共識機制,用來確認你是否做過一定量工作的證明。比特幣的區塊鏈主要是依託計算數學難題來衡量工作量。每個區塊,當選定一定數量的交易記錄之後,填充版本號、時間戳、難度值,生成相應的Merkle根雜湊。很容易看到,這些數值在選定交易記錄以後,都是確定的,唯一能夠改變的就只有隨機數(Nonce)這個值。如圖7所示,系統根據難度值,要求計算整個區塊頭的兩次SHA256演算法,得到的雜湊結果要小於一個閾值。根據前面描述的SHA256演算法的偽隨機性,只有通過不斷地嘗試和列舉,才能找到相應的隨機數,證明自己的工作量。


640?wx_fmt=png

圖7  工作量證明機制示意圖


除了工作量證明機制(PoW)這類共識機制之外,還有股權證明機制(PoS)、授權股權證明機制(DPoS)、拜占庭容錯機制(BFT)、實用拜占庭容錯機制(PBFT)這些在不可信環境下的共識機制以及要求在可信環境下的共識機制,例如PaxOS和Raft。表1是做了簡單的對比。


640?wx_fmt=png

表1  共識機制的簡單對比表


執行機制


接入網路和驗證


節點通過安裝相應的軟體(例如比特幣核心),接入區塊鏈。節點啟動以後,主要是在P2P網路上發現鄰居節點、連結鄰居節點、傳遞P2P訊息和下載區塊鏈驗證。節點可以選擇下載全量的區塊鏈進行驗證,或者是隻下載區塊頭,通過Merkle樹節點來進行簡單支付驗證(SPV)。


錢包軟體可以分為移動錢包、桌面錢包、網際網路錢包和紙錢包,都支援儲存使用者的私鑰,錢包也可以根據私鑰是否是種子產生的,而分為決定性錢包和非決定性錢包,關鍵區別在於私鑰的備份和易恢復性。


區塊鏈的儲存和接受


比特幣的區塊鏈使用Berkeley DB(檔案資料庫)作為錢包資料庫,使用LevelDB(鍵值資料庫)儲存區塊的索引和UTXO(Unspent Transaction Output,未開銷的比特幣交易輸出)。節點在啟動的時候,將整個區塊鏈的索引從LevelDB載入入記憶體。當收到一個新區塊時,節點對新區塊中的所有交易進行檢測,驗證交易格式、交易大小、交易簽名、UTXO是否匹配、交易簽名、指令碼合規等方面。


如果驗證成功,檢查上一區塊頭與鏈頭區塊雜湊值是否一致,如果是一致,則更新UTXO資料庫和回滾交易資料庫,如果不是,則將該區塊放在孤兒區塊池中 。當節點發現網路中存在另一條更長的區塊鏈時,就需要斷開現有的區塊並對區塊鏈進行重組。如果驗證不成功,會拋棄該區塊,繼續等待新區塊的到來(礦工會繼續計算新區塊的數學難題)。


區塊鏈的工作量證明計算機制


“礦工”角色的節點一直收集網路中廣播的交易記錄,並致力於計算新區塊的數學難題,即工作量證明。如果其他節點發來的新區塊驗證成功,節點除了更新UTXO資料庫和回滾交易資料庫,節點會立即開始下一個新區塊的計算。新區塊的構建優先選取交易記憶體池中優先順序高的交易記錄。優先順序的計算方式為:


如果自己的工作量證明計算成功,節點會第一時間將這個區塊廣播至整個網路中,其他節點收到該新區塊,如上所述,會進行相應的驗證和儲存。


整個區塊鏈的運轉機制如圖8所示。


640?wx_fmt=png

圖8  區塊鏈運轉機制示意圖


其他相關


指令碼語言


區塊鏈採用的指令碼語言並不是圖靈完備的語言,不支援迴圈,只能進行堆疊式操作。這種指令碼語言的好處是,不允許礦工提交一個死迴圈的指令碼,更注重的是安全方面的考量,但其擴充套件能力有限。從以太坊為首的區塊鏈程式設計平臺支援圖靈完備的程式語言,引領區塊鏈跨入2.0時代。由於支援迴圈等複雜操作,以太坊用Gas(燃料)機制來防止死迴圈的出現,確保系統的安全。


訊息佇列


比特幣區塊鏈採用Zero MQ(ZMQ)作為訊息分發和訊息佇列管理工具。與很多人熟悉的RabbitMQ相比,ZMQ不像傳統意義的訊息伺服器,更像一個底層的網路通訊庫,在多個執行緒、核心和主機盒之間彈性伸縮,在Socket API之上將網路通訊、程式通訊和執行緒通訊抽象為統一的API介面。


挖礦裝置和演算法演進


挖礦裝置從支援複雜指令(CISC)、適合序列計算的CPU礦機時代,經由基於眾核體系、適合並行簡單計算的GPU挖礦和低功耗卻價格昂貴的FPGA挖礦,逐漸向集約高速的ASIC礦機和規模效應的礦池演進。


基於工作量證明機制的演算法,容易導致礦工算力集中的問題。有人將這種“中心化”的責任歸咎於SHA256演算法。此時,基於SCRYPT演算法的萊特幣(Litecoin)進入了人們視線,其佔用記憶體多、計算時間長、平行計算困難的特點,限制了礦工的“軍備競賽”。萊特幣的成功催生了更多演算法的交叉融合,衍生出串聯演算法(夸克幣)、並聯演算法(HeavyCoin)和多用途演算法(在工作量證明的同時,尋找大素數的素數幣,PrimeCoin)。


開源專案和工具


區塊鏈的開源專案


BitCoin


BitCoin是最早、也是現網執行區塊鏈最成功的一個開源專案,核心技術框架採用C++開發,共識演算法採用PoW,每秒交易量(TPS)為不多於7筆,開源許可協議為MIT。


  • 官方程式語言:C++

  • 開源許可協議:MIT

  • 開源專案地址:https://github.com/bitcoin/bitcoin


Ethereum


以太坊(Ethereum)是一個支援圖靈完備指令碼執行的區塊鏈開發平臺,基於智慧合約,降低使用者搭建DApp應用的門檻。目前以太坊正式執行的版本是1.0,採用的是POW共識演算法,公網TPS是25筆,未來將採用類POS的Casper演算法,區塊鏈的確認速度將得到大幅提升。在規劃的2.0版本中,TPS有望可以達到2000TPS。


  • 官方程式語言:Go

  • 開源許可協議:GPLv3

  • 開源專案地址:https://github.com/ethereum


Hyperledger Fabric


Hyperledger Fabric是IBM開源的區塊鏈專案,開發環境可以適配多種環境(virtualbox虛擬機器、自建網路和IBM的BlueMix),支援Docker,共識演算法外掛化,注重角色的許可權控制和企業級的安全機制。主要開發語言是Go語言,支援JavaScript、Java和Python等語言,交易頻率TPS最高能夠達到100K。其子專案Iroha助力區塊鏈移動應用程式的開發,值得關注和進一步跟蹤。


  • 官方程式語言:Go

  • 開源許可協議:Apache 2.0

  • 開源專案地址:https://github.com/hyperledger/fabric


OpenChain


OpenChain 是區塊鏈技術公司Coinprism的開源工具,目標是大型企業和金融機構,基於一種獨特的分散式賬本技術,幫助使用者部署自己定製的區塊鏈,減少使用者的交易成本和結算時間。


  • 官方程式語言:C#

  • 開源許可協議:Apache 2.0

  • 開源專案地址:https://github.com/openchain


BitShares


位元股(BitShares)提供的BitUSD等錨定資產,是虛擬幣歷史上的一個最重要變革之一,消除了虛擬貨幣估值波動大的問題。位元股創新地提出了DPoS共識演算法,核心技術框架採用C++語言開發,既適用於公有鏈,也適合於聯盟鏈。在位元股2.0中,交易頻率TPS最高能夠達到100K。


  • 官方程式語言:C++

  • 開源許可協議:MIT

  • 開源專案地址:http://github.com/bitshares


Ripple


瑞波(Ripple)是世界上第一個開放的支付網路,也是目前最成功的區塊鏈技術公司。其核心產品Ripple協議本質上是一個實時結算系統,通過引入新的共識機制RPCA,只要特殊節點投票,就能在很短時間內完成交易的驗證和確認。


  • 官方程式語言:C++

  • 開源許可協議:ISC

  • 開源專案地址:https://github.com/ripple/rippled


Tendermint


美國公司Tendermint推出的Tendermint是第一個實施分片技術的公共區塊鏈。Tendermint主核心負責管理所有區塊鏈分割槽,支援比特幣分割槽和以太坊分割槽,具有很大的靈活性,共識引擎通過Tendermint套接字協議(TMSP)與應用程式進行連線,不依賴於某一特定的程式語言,所以開發人員可以使用任意一種程式語言來編寫智慧合約。


  • 官方程式語言:Go

  • 開源許可協議:Apache2.0

  • 開源專案地址:https://github.com/tendermint/tendermint


Corda


Corda是R3CEV於2016年12月初開源的區塊鏈平臺,採用一種類區塊鏈的分散式賬本,基於產業標準工具,通過創新智慧合約和資料處理,為金融服務設計一種新型分散式的分類帳平臺。


  • 官方程式語言:Go

  • 開源許可協議:Apache2.0

  • 開源專案地址: https://www.corda.net/


具體對比圖如表2所示。


640?wx_fmt=png

表2  開源專案的對比表


以太坊的整合開發環境(IDE)


Remix是以太坊官方IDE,它允許開發者在以太坊區塊鏈建立和部署合約及去中心化應用。它包含一個Solidity原始碼排錯器,Solidity是以太坊開發的智慧合約語言,可以將智慧合約程式碼編譯成以太坊虛擬機器(EVM)可識別的位元組碼。此外,如要和以太坊節點互動,主要用到的Web3.js API;與節點進行底層互動,需要用到JSON RPC API。以太坊主流專案的對比如表3所示。


640?wx_fmt=png

表3  以太坊主流專案的對比表


相關文章