帶你讀源碼:四大視角多維走讀區塊鏈源碼

引子

區塊鏈作爲「新基建」的重要組成部分,越來越受技術愛好者關注。區塊鏈極客信奉“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 高級架構師。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章