區塊鏈開源專案Asch原始碼初探
阿新 • • 發佈:2019-01-10
Asch這個名字是 App Side Chain 的縮寫。 是一種基於區塊鏈跨鏈技術的應用開發平臺,目前全部核心程式碼已經在GitHub上開源。
區塊鏈是比特幣的底層技術,但是名氣低於比特幣,但是個人認為潛力遠遠大於比特幣。是最值得技術人員關注的技術之一。
我一般研究一門新技術,傾向於研究更新更早期的程式碼。 因為非常成熟有名的程式碼往往已經過度設計,對於閱讀程式碼入門不一定是好的選擇。 而一些出於專案早期的程式碼,而且更容易閱讀理解其核心原理。Asch目前來說是一個非常好的區塊鏈學習入門的開源專案。
『整體架構』
目前整個阿希鏈主要由以下原始碼庫組成
- asch阿希鏈的核心服務端原始碼,主要由 Node.js 開發。
目前原始碼閱讀主要基於asch@1.3.0 version
『目錄結構』
- proto/index.proto
- genesisBlock-mainnet.json
- config-mainnet.json
- public/
- src/core
- src/base
『proto/index.proto』
Asch 的區塊核心資料結構通過protobuf和進行序列化和反序列化。 所以proto/index.proto這個資料結構就是核心區塊的資料結構。 依我的理解,index.proto 這個名字應該叫 block.proto 更合適。
『目錄 public/』
網頁錢包的程式碼根目錄,由asch-frontend打包生成的網頁錢包程式碼。
『原始碼目錄結構 src/』
src/init.js 負責初始化,用 async 來處理各種先後順利,避免回撥地獄,剛開始看的時候會比較繞, 但是看懂了就很清晰了。
在程式碼中很多模組都有共同的模組變數,最典型的是var moduels, library,
- modules 對應的是 src/core/ 下面的模組。
- library.base 對應的是 src/base/ 下面的模組。
『受託人的輪流鍛造(Forging)機制』
Asch 不像比特幣那種挖礦機制,而是受託人的輪流鍛造機制,主要有以下流程。
- onBlockchainReady(core/delegates.js) 當區塊鏈資料庫載入完成,開始鍛造初始化。
- loadMyDelegates: 從配置檔案中獲取secret(依次讀取若干個),用 secret 生成金鑰對(公鑰和私鑰)。
- accounts.getAccount: 用公鑰從區塊鏈資料庫中獲取賬號,並檢查該賬號是否是受託人,是受託人才繼續進行。
- loop: 開始進入輪詢,每次輪詢間隔100ms 。
- slots.getSlotNumber (utils/slots.js) 先獲取 epochTime ,epochTime 記錄從 2016-5-27T20:00:00 後到某一個特定時間經過了多少秒。然後 getSlotNumber = epochTime / interval, interval = 10 。也就是每過10s出現一個新的slot 。
- blocks.getLastBlock: 顧名思義,獲取當前最新的區塊
- getBlockSlotData->generateDelegateList (core/delegates.js) 先獲取當前受託人列表,按票數排序,獲取票數最高的 101 個受託人的公鑰。並且對這些受託人列表進行『隨機』排序。這裡的隨機應該是每個節點一樣的隨機,不是完全隨機。
- getBlockSlotData: 獲取當前slot的檢查受託人列表,如果在配置中該受託人的金鑰對的,則進入到『區塊的產生流程』。
『區塊的產生流程』
- loop(core/delegates.js): 對於註冊了受託人的節點,會有一個定時觸發器,呼叫 blocks.js 裡面的 generateBlock 。
- generateBlock(core/blocks.js): 首先從 transactions 裡面獲取未確認的交易列表。
- generateBlock: 從未確認的交易列表中過濾出驗證通過的交易列表。
- base.block.create: 建立包含這些交易列表的新區塊,驗證區塊是否合法。
- hasEnoughVotes: 檢查該受託人是否有足夠的票數,如果票數不夠,則不可生成區塊。(這個步驟應該提前吧?)
- processBlock: 通過 block.id 查詢本地資料庫,如果已經還未存在,則繼續進行下面行為。
- applyBlock: 生效剛才驗證通過的交易列表,就是對交易涉及的賬號進行一些轉賬等操作,這部分邏輯在 src/base/transaction.js apply 函式中實現。交易有多種型別,後面再詳述。
- base.block.dbSave: 儲存 block
- base.transaction.dbSave: 儲存交易列表
- accounts.mergeAccountAndGet: 對新區塊的建立者進行資料更新,建立者其實就是這個註冊了受託人的節點。
- setLastBlock: 將這個新的區塊設定成當前最新的區塊。
- bus.message(‘newBlock’) 廣播這個新的區塊。
『ToDo』
- Asch鏈的交易流程
- Asch鏈的HTTP介面實現原理
- DApp原理和開發流程
- …