引子
區塊鏈作為「新基建」的重要組成部分,越來越受技術愛好者關注。區塊鏈極客信奉“code is law”,相信通過程式碼可以構築一個可信的世界。
而作為一門綜合學科技術,區塊鏈建立在數學、密碼學、計算機原理、分散式網路和博弈論等眾多基礎學科之上,底層程式碼動輒數十萬行,如果沒有摸清門道,要完全掌握這些程式碼是極具挑戰的。
本文希望給讀者一個走讀區塊鏈原始碼的方法,讓讀者面對區塊鏈底層專案時可以從容地說出“show me the code”。
基礎知識儲備
區塊鏈是一門綜合學科,涉及多個專業領域,涵括多方面的基礎知識,在深度研究區塊鏈之前需要做一定廣度的知識儲備。注意,這裡說的是廣度,並非深度,也就是說你只需要大概知道這些基礎知識的基本原理與作用即可。
- 密碼學相關:理解雜湊、對稱加密、非對稱加密以及數字簽名的基本原理和作用;
- 計算機作業系統相關:理解多程式、多執行緒、互斥、並行等相關概念和作用;
- 資料結構相關:理解佇列、堆疊、樹等基本資料結構和使用場景;
- 計算機網路相關:理解TCP/IP、心跳包、訊息流等基本概念;
- 資料庫相關:理解資料庫基本概念,瞭解KV資料庫的基本原理;
- 計算機原理相關:理解程式編譯、解析、執行和位元組碼、虛擬機器等概念;
- 分散式系統相關:理解點對點網路、分散式一致性、CAP等相關概念和基本原理;
- 程式開發相關:掌握相關的程式語言、構建工具等,理解專案構建基本流程。
多維走讀
在儲備了相關的基礎知識之後,你就可以開啟一份真正的區塊鏈底層程式碼了,一般通過git clone可以快速下載到專案程式碼。
但是,面對數十萬行的程式碼,該從何看起呢?
庖丁為文惠君解牛,手之所觸,肩之所倚,足之所履,膝之所踦,砉然向然,奏刀?然,莫不中音:合於《桑林》之舞,乃中《經首》之會。出自《莊子·養生主》
一個優秀的區塊鏈底層專案,必然有一份優秀的工程程式碼,這份程式碼有其合理的組織結構與紋理邏輯。走讀程式碼應效仿庖丁解牛,先摸清區塊鏈的基本結構和邏輯,再開始走讀,可以達到事半功倍的效果。
本文推薦要從四個不同視角進行走讀,站在自己的需求角度出發去看程式碼,而不要被巨量的程式碼所左右。這四個角度為功能視角、系統視角、使用者視角和開發視角,分別從邏輯層面、執行層面、使用層面和開發層面釐清程式碼架構和關鍵演算法。
功能視角
在深入一份區塊鏈底層程式碼之前,首先要通過其官網、技術文件、github wiki等渠道獲取專案設計文件,瞭解其基本功能設計。
一般每個專案都會提供核心功能列表、總體架構圖、功能模組圖等介紹文件,通過這些介紹可以掌握專案基本功能。即使你真的找不到也不打緊,大部分割槽塊鏈底層專案在功能設計層面的差異較小,核心功能模組也大致相同。
以FISCO BCOS為例,基礎層程式碼如下:
核心層核心程式碼如下:
介面層核心程式碼如下:
從功能視角出發,先定位核心功能模組的程式碼位置,再仔細深入各個功能程式碼,從單個功能模組內,也可繼續遞迴採用功能視角拆分法,廣度遍歷直至瞭解全貌。
系統視角
系統視角從整個區塊鏈網路執行角度,關注區塊鏈節點全生命週期所參與的系統行為。
關注點包括從敲下啟動節點的命令開始,節點經歷了哪些初始化環節,之後又是如何與其他節點建立點對點網路,以及完成分散式協作的。
由於不同區塊鏈在部署架構上略有差異,系統執行方式也有所不同,但萬變不離其宗,系統視角來看,每個區塊鏈系統都要經歷節點初始化、建立點對點網路、完成分散式互動的過程。
從系統視角看區塊鏈,首先要關注初始化工作。以FISCO BCOS為例,區塊鏈節點啟動從main函式入口進入,通過libinitializer模組初始化並啟動各模組,啟動順序如下:
通過啟動順序可以知道FISCO BCOS的一個重要特性——支援多群組賬本,每個群組是一個獨立的Ledger模組,每個Ledger具有獨立的儲存、同步、共識處理功能。
完成初始化工作同時,系統將會啟動若干執行緒(或者程式、協程,原理類似),這些執行緒包括網路監聽、共識、訊息同步等,可以結合程式碼分析與系統命令檢視執行節點配合確定有哪些關鍵執行緒,搞清楚關鍵執行緒的工作機制就可以基本掌握區塊鏈系統執行機制。
以FISCO BCOS為例,節點啟動之後的關鍵執行緒以及他們之間的關係如下:
初始化完成之後,網路模組的Host執行緒將根據配置列表,主動與其他節點建立連線,並且持續監聽來自其他節點的連線;Sync執行緒開始相互傳送區塊高度,發現高度低於其他節點則開啟下載邏輯;RPC與Channel執行緒等待客戶端傳送請求,將收到的交易塞入txpool;Sealer執行緒從txpool獲取交易,Consensus執行緒則開始處理共識訊息包。
如此,整個區塊鏈系統有條不紊地運轉,完成客戶端請求與分散式協作。
使用者視角
使用者視角關注操作介面和交易生命週期,關注訪問區塊鏈的介面和協議設計、編解碼方式、核心資料結構、錯誤碼規範等,還會關注如何傳送一筆交易到鏈上,交易在鏈上又經歷了哪些處理流程,直到達成全網共識。
一般區塊鏈底層專案都會給出互動協議的說明文件,通常實現包括JsonRPC、gRPC、Restful等不同型別的互動協議。
不同專案的互動介面會有所不同,但大都會包含傳送交易、部署合約、呼叫合約、檢視區塊、檢視交易以及回執、檢視區塊鏈狀態等介面。不同專案的資料編碼也會有所不同,有些採用Json,有些採用protobuf等。
當從技術文件中瞭解清楚互動協議、介面、編解碼和錯誤碼等設計細節之後,接下來最重要的是通過傳送交易、部署合約、呼叫合約這些關鍵介面,對程式碼進行抽絲剝繭,貫穿交易整個生命週期,從而搞清楚區塊鏈底層最核心的邏輯。
以FISCO BCOS為例,通過多個模組相互協作,完成交易整個生命週期的處理:
開發視角
開發視角關注的是整個程式碼工程,包括第三方依賴,原始碼模組之間的相互關係,單元測試框架和測試用例,編譯和構建方式,持續整合和benchmark,以及如何參與社群原始碼貢獻等等。
不同語言都有相應推薦的編譯構建方式以及單測框架,通常在區塊鏈專案原始碼目錄可以快速定位到第三方依賴庫,比如以cmake構建的C++專案有CmakeLists.txt檔案,go專案有go.mod檔案,rust專案有cargo.toml檔案等。
以FISCO BCOS為例,從CmakeLists.txt可以看到依賴庫包括:
專案核心原始碼包括fisco-bcos程式入口程式碼,以及libxxx的各模組程式碼,根據模組的名字可以快速識別其對應功能,這裡也體現了一個專案原始碼質量的高低,高質量的程式碼應該是“程式碼即註釋”。
單元測試程式碼在test目錄,採用boost的單元測試框架,子目錄unittests中單測程式碼與原始碼目錄一一對應,非常容易找到原始碼對應的單元測試程式碼。
構建和持續整合工具程式碼在tools目錄,子目錄ci中維護了多個不同場景的持續整合用例,在github提交的每一個pr(pull request)都會觸發這些持續整合用例,當且僅當每個用例成功通過方可允許合入pr。
關於FISCO BCOS的程式碼規範和貢獻方式,在CODING_STYLE.md和CONTRIBUTING.md檔案中有詳細描述,鼓勵社群使用者積極參與貢獻。
總結
區塊鏈涉及領域和知識較多,需要深入原始碼細節,才能真正完全掌握區塊鏈核心技術。所謂“重劍無鋒,大巧不工”,掌握原始碼走讀的基本方法論,才能在巨量程式碼前,面不改色心不跳。
本文提出從功能、系統、使用者和開發四個不同視角進行區塊鏈底層程式碼走讀的方法,一般來說,依次選擇不同視角進行走讀是比較推薦的方式,也可以根據個人喜好和能力模型選擇視角順序。
最後,本文所舉示例皆為FISCO BCOS,但這套走讀方法可以適用於任何其他區塊鏈底層專案,希望本文對你有所幫助。
FISCO BCOS的程式碼完全開源且免費下載地址↓↓↓
https://github.com/FISCO-BCOS...