天天看點

談談自己對鉑鍊(Bottos)的看法和分析首次接觸和第一印象重新整理對“AI+區塊鍊”的認知鉑鍊代碼的簡單分析

首次接觸和第一印象

第一次接觸鉑鍊是在初鍊群中被鉑鍊群管拉進技術群時開始的。鉑鍊對我來說印象最深的還是他那長達70多頁的白皮書。作為一條主攻AI領域的專用公鍊,我在還沒開始看鉑鍊項目代碼時就設想鉑鍊對于AI部分的處理應該是在區塊鍊内部建構一個運作AI運算的基礎設施子產品,再由區塊鍊完成AI子產品産出資料的确權,AI的運算可能将一部分交由智能合約處理,做到運算和資料雙雙上鍊。AI計算天生是建構在大資料之上的,可以将大資料比作糧食,AI比作野獸,野獸隻有在充分進食後才能進化,是以如果AI運算的基礎設施和區塊鍊整合在一起那區塊鍊一定會大資料緊密結合,區塊鍊如果和大資料緊密結合那對于資料存儲這一塊兒的要求就非常高了,資料分片技術可能會成為一個瓶頸。AI+大資料+區塊鍊?再加上那70多頁的白皮書?基于以上猜想,我對鉑鍊充滿好奇。在進入鉑鍊技術群之後,我就從GitHub上下載下傳了鉑鍊的代碼,花了一個星期左右的時間看完了絕大部分代碼,也發現了一些小BUG和不足,目前的感受是鉑鍊的代碼其實寫得挺好的,看得出來是在一個經驗豐富的架構師的帶領下發起的項目,但在架構設計上和我之前對鉑鍊的設想有明顯的出入,我并未看到任何和AI相關的代碼,也未發現對于資料儲存這一塊兒有明顯亮眼的處理。

重新整理對“AI+區塊鍊”的認知

在鉑鍊技術群裡發表了自己對鉑鍊架構設計的看法,也得到了鉑鍊開發者的回應,這才認識到自己對“AI+區塊鍊”的認知存在偏差。“AI+區塊鍊”其實并不是将AI和區塊鍊整合在一起,AI建構在大資料之上,而區塊鍊則是作為AI在資料确權和分享上的一種延申。根據 《Blockchain —建構新一代的人工智能生态系統(http://www.blockchainbrother.com/article/1024)》 這篇文章的描述,AI的發展歸咎于算力、算法和資料這三個核心因素。AI算法在上世紀就已被研究透徹,但當時AI并未發展起來的原因正是算力和資料的缺失。在21世紀的今天,CPU/GPU的算力依據摩爾定律(甚至超過摩爾定律)在增長,網際網路的發展加快了社會進步的節奏,以往線上下堆積的資料也逐漸搬到了線上,大資料和雲計算的出現更是讓AI在算力和資料上的不足得以彌補,是以近幾年AI領域出現了爆發式地增長:算法一直都有,現在算力和資料也跟上了,AI發展的三要素也都集齊了。雖然算力和資料跟上了,但也隻是在“量”上粗暴地增加了而已,在算力共享、資料交換和資料确權等“質”的轉變上,由于區塊鍊的出現也迎來了轉機。區塊鍊建構在密碼學基礎上的數字身份讓資料天然的具有“身份”屬性,其去中心化的特性也讓資料的流轉脫離了中心化的束縛而變得更加高效。資料具有身份驗證而且流通更快,這讓AI産生的資料更具價值,再配合上區塊鍊網絡龐大的協同計算能力,AI的運轉速度無疑将更上一個台階。是以我想,像鉑鍊這樣主打AI的區塊鍊,更多的還是為現有的AI體系提供資料上鍊和分享服務,而并不是建構一個獨立的AI生态系統,如果是這樣,那以後跨鍊通信應該會是這些主攻AI市場的區塊鍊所應該具備的功能。

鉑鍊代碼的簡單分析

> 高并發架構

鉑鍊代碼由Go語言編寫,代碼結構比較清晰,代碼品質和原創程度都比較高,沒有看到明顯抄襲的痕迹。鉑鍊主體采用高并發的Actor模型建構,由ProtoActor.Go實作。鉑鍊将API服務(Api)、鍊處理(Chain)、P2P網絡處理(Net)、區塊生産(Producer)、交易處理(Transaction)和可選的MongoDB服務(OptionDB)抽象為對應的Actor模型:

  • API服務:以RPC(遠端過程調用)的形式對外提供API服務,與鉑鍊的消息互動采用Protobuf編碼,天然支援由多種語言編寫的外部應用程式
  • 鍊處理:實作鉑鍊的區塊鍊資料庫功能,包括區塊查詢、交易查詢、區塊接收與廣播和鍊資訊查詢功能
  • P2P網絡處理:實作交易和區塊在P2P網絡中的傳播功能
  • 區塊生産:每500毫秒檢測一次自己是否是目前區塊的生産者,是的話就建構一個區塊并發送給“鍊處理”處理
  • 交易處理:從終端或P2P網絡接收交易放入交易池,并将交易發送給“P2P網絡處理”處理,支援擷取所有可加入區塊的交易和交易的移除操作
  • MongoDB服務:MongoDB服務作為一個可選服務,可在配置檔案中配置是否啟用,啟用MongoDB服務後可以将區塊寫入MongoDB中

每一個Actor對應一個線程,完全獨立地運作,與外部隔離。Actor之間的互動手段采用消息通信地方式,隻有通過發送消息才能改變一個Actor的内部狀态。鉑鍊使用Actor模型讓幾個可以獨立運作的子產品在高并發的環境下并發運作,在資料量大的環境中運作效率應該會有比較明顯的提升。

> RESTFUL化服務

幾乎每一個區塊鍊項目都提供了基于Http的Restful接口,提供Restful化的接口可以提供統一的接口調用規則,适合讓區塊鍊伺服器同時服務多種類型的終端,其中一些終端就包括區塊鍊浏覽器和線上錢包。鉑鍊的Restful服務提供查詢區塊、交易和賬戶的服務,也提供發送交易、擷取合約ABI(應用程式二進制接口)和合約代碼的服務,鉑鍊的指令行用戶端就使用Restful接口與區塊鍊通信。

> 資料庫持久化服務

除開像MongoDB這樣的分布式資料庫外,鉑鍊還使用了另外兩個嵌入式資料庫,分别是LevelDB和BuntDB。以太坊中也使用LevelDB為資料持久化提供服務,由于以太坊采用特殊的MPT字典樹結構儲存狀态,是以每個樹節點的值都可以鍵值對的形式儲存在LevelDB中。鉑鍊采用的區塊儲存結構非常簡單,就是普通的二進制序列,是以對于區塊和區塊頭的增删查改就交由像LevelDB這樣的以鍵值對形式組織的非結構化資料庫來做,非常友善。BuntDB是用Go語言編寫的記憶體資料庫,類似于Redis和Memcache,提供資料持久化和查詢功能,支援結構化查詢,鉑鍊使用它完成賬戶的存儲和結構化查詢操作。由于鉑鍊采用DPOS作為其共識算法,經常需要對投票賬戶進行排序,是以使用BuntDB這類的提供結構化查詢服務的資料庫是一個不錯的選擇,而且BuntDB是個記憶體資料庫,是以也不需要再額外使用緩存儲存頻繁查找的資料,直接用就行:

  • MongoDB資料庫: 以可選插件形式存在的Actor子產品,主要用于持久化儲存鍊上的區塊,還提供轉賬和建立賬戶兩個内置的合約功能,和LevelDB功能重疊,但作為一個本身就提供資料分片存儲功能的主從分布式資料庫,可能在以後區塊資料激增的情況下接替部分LevelDB的功能,為鉑鍊提供一個資料分片的解決方案。
  • LevelDB資料庫:以鍵值對的形式為區塊鍊提供區塊存儲和查找功能,以哈希作為鍵,以BPL(Bottos-Pack-Library,鉑鍊自研二進制編解碼庫)編碼作為值,但需要配合LruCache為其提供輔助的資料緩存服務
  • BuntDB資料庫:記憶體資料庫高效存取,不需要提供資料緩存服務,并且還支援結構化查詢和復原操作,特别适合需要頻繁存取和排序查找的賬戶資料的存儲

> P2P網絡節點發現機制

不同于基于POW共識設計的區塊鍊,基于DPOS共識設計的區塊鍊由于可能存在固定的代理人節點,是以在區塊鍊的對等網絡中,對節點發現機制的複雜度要求就沒那麼高。很多基于POW共識算法設計的區塊鍊在節點發現機制上采用DHT(分布式哈希表)系列算法,比如初鍊就采用Kadelima作為其節點發現機制的算法,按照距離讓節點在對等網絡中均勻排布,以最大化優化消息在網絡中的傳播效率,為了實作内網穿透,一般采用UDP協定建立連接配接,而鉑鍊則自研了一套基本能用的節點發現算法,節點之間采用TCP協定連接配接。在鉑鍊的節點發現算法中,存在三個層次的角色,分别是Neighbors、Candidates和Runners,在配置檔案中預配置的種子節點清單則首先放入Neighbors層次中。節點在三個層次之間通過Discover子產品驅動流轉,其中Runners層次中的節點通過KeepAlive子產品完成心跳檢測。具體的發現機制如下:

  • 角色介紹:

    a) Neighbors層次:處在該層次的節點都是鄰居,所有在Neighbors層次中的節點都沒有與其建立連接配接,都以IP和端口等節點資訊的形式存儲,處在該層次的節點通過Discover子產品與本節點建立連接配接後被提升至Candidates層次成為候選者節點

    b) Candidates層次:處在該層次的節點都是候選者,本節點與所有候選者節點都已經建立了TCP連接配接,在連接配接建立後會立即開啟三次握手流程,在雙方都已達到最後一次握手流程時會互相将對方提升至Runners層次成為連接配接者

    c) Runners層次:處在改層次的節點都是正式的連接配接者,所有的P2P通信都會通過他們進行轉發,也會通過他們完成接收,可廣播也可單點傳播。

  • 流程介紹:

    A) 從配置檔案中讀取所有種子節點的IP和端口等資訊,全部放入Neighbors層次中

    B) Discover子產品每5秒從Neighbors層次中取出10個節點資訊并嘗試建立TCP連接配接,連接配接成功後将節點從Neighbors層次中移除并放入Candidates層次中

    C) 每5秒中向所有處于Candidates層次中的節點開啟三次握手流程并将對應節點的握手計數器加1,如果超過10次握手都沒有成功那直接關閉和該節點的連接配接,然後将節點從Candidates層次中移除

    D) 在三次握手流程結束後将節點從Candidates層次中移除并放入Runners層次中并初始化該節點的心跳計數

    E) KeepAlive子產品每10秒向所有處于Runners層次中的節點發送一次Ping、Pong心跳檢測,在收到Pong消息後将對應節點的心跳計數加1

    F) 在終端啟動之後的前三個8秒中向所有處于Runners層次中的節點索要他們的Runners層次中的所有節點資訊,将這些節點資訊全部傳回本節點,然後放入本節點的Neighbors層次中

    G) 在終端啟動之後的第三個8秒之後的每8秒向最新加入Runners層次中的節點所要他的Runners層次中的所有節點資訊,将這些節點資訊全部傳回本節點,然後放入本節點的Neighbors層次中

    H) KeepAlive子產品每40秒檢測一次在Runners層次中的節點的心跳狀态,将所有心跳計數為0的節點從Runners層次中移除,關閉和他們的連接配接,然後放入Neighbors層次中

> DPOS共識算法

作為摻雜了“人治”因素的共識算法,DPOS共識算法也像POW共識算法那樣飽受争議,POW共識算法在挖礦算法設計不當的情況下,容易催生ASIC專用礦機進而在人性“逐利”的驅使下導緻算力逐漸集中為礦池,導緻去中心化程度明顯降低。針對目前POW共識算法的不足,DPOS共識算法并沒有給出一個優化方案,比如基于抗ASIC專用礦機挖礦算法的POW共識算法優化(比如初鍊就設計了一套抗ASIC專用礦機的挖礦算法),而是基于目前無法做到完全去中心化的事實,設計出一套從一開始就摒棄追求完全去中心化的初衷,以犧牲去中心化程度為代價來換取區塊鍊性能提升的基于“人治”的共識算法。DPOS共識算法涉及代理人節點的競選、投票和換屆,獲得投票數量排前幾位的競選者将在目前的代理人換屆周期内被提升為正式的區塊生産代理人節點,即記賬節點。每一個代理人節點都會在換屆周期内被配置設定一個出塊時間槽,輪到你出塊時就必須在目前時間槽内完成區塊的生成和廣播,不然就會被記錄為錯過一次出塊任務,這個記錄會廣播給全網,其他節點在收到這些記錄資訊後自然也能權衡在下次代理人換屆時是否還繼續給你投票。每一個節點都可以參與代理人競選,不過有沒有節點給你投票那就不是你能決定的了,人都有惰性和從衆心理,獲票數量始終在前的代理人節點會在頭部效應的影響下,地位越來越穩固,留給其他“小白節點”的機會就會越來越少,除非他們“資金”雄厚。DPOS共識算法會是在區塊鍊去中心化程度和運作效率的折中權衡下的一個中長期共識方案,但一定不會是公鍊的最終共識形态。DPOS共識算法适合那種需要由人或社群去維護運作在區塊鍊之上的産品的專用公鍊,這些産品品質維護的好壞程度很難用算法去衡量其背後的工作量,但使用這些産品的使用者卻能深切感受到,在這種環境下設計的區塊鍊适合選用DPOS作為其共識算法,因為既然隻能由人去确認區塊鍊的運作狀況,那“人治”就是不可避免的也是十分必要的一個環節,比如觸控科技的BCX區塊鍊遊戲引擎項目就是一個很好的例子。BCX區塊鍊采用DPOS共識算法,專為區塊鍊遊戲生态打造,如果人人都能參與區塊鍊遊戲的維護,都有權力為遊戲添加更多好玩的元素,那遊戲是否好玩就需要由玩家去鑒定,玩家會一直把票投給能讓遊戲真正變得好玩的維護者讓他們變成代理人,這些代理人一旦作惡讓遊戲變得不好玩或者不平衡,玩家自然不會再把票投給他們。扯了那麼多都沒有講鉑鍊DPOS共識算法的運作過程,鉑鍊團隊設計的DPOS共識算法和傳統的DPOS共識算法基本相同,沒有太大的出入,最多就調整了下代理人的選取規則。不過目前鉑鍊還處在測試階段,共識流程為測試網絡中的流程,在正式網絡釋出後應該會有完善和變更。測試網絡中的共識流程如下:

a) 節點在區塊鍊初始化時建立Bottos内置合約賬戶并注入大量資金,如果Bottos合約賬戶已存在則跳過此步驟

b) 通過向區塊鍊發送合約交易調用内置合約代碼,與共識相關的内置合約功能包括建立賬戶、交易轉賬、劃撥權益、注冊代理人競選和代理人投票

c) 節點先發送“建立賬戶”的交易建立密鑰賬戶、餘額賬戶和權益賬戶,然後發送“交易轉賬”交易從Bottos内置賬戶中索取需要的轉賬金額填充餘額賬戶,再發送“劃撥權益”交易将資金從餘額賬戶劃撥至權益賬戶,最後發送“注冊代理人競選”交易建立代理人投票賬戶

d) 以上所有交易都會進行全網廣播并執行對應的合約功能,這樣全網所有節點都能看到任意一個節點建立的代理人投票賬戶,他們可以選擇給指定的代理人投票賬戶投票,通過發送“代理人投票”交易将權益賬戶中的餘額用來更新指定注冊競選代理人的投票狀态

e) 每29個區塊完成一次代理人換屆,所有節點在收到區塊編号是29的倍數的區塊時開啟代理人換屆流程,從所有代理人投票賬戶中選取28個票數最高的賬戶和1個剩餘完成時間最小的賬戶,将這29個賬戶随機打亂後就成為本屆的出塊代理人賬戶名單

f) 根據節點的系統時間獲得目前的出塊槽位(Slot),再根據出塊槽位從29個代理人賬戶中選取對應槽位下的代理人賬戶,如果該賬戶在節點的本地賬戶名單中,那麼在代理人參與率和出塊排程時間都達标的情況下,本節點會被指定為目前時間段内的出塊人,在立即将交易打包進區塊并全網廣播後完成本輪出塊任務

g) 在目前的測試網絡中,節點在出塊後并沒有配置設定相應的記賬獎勵,鍊上所有的資金都來自于初始化的Bottos内置合約賬戶中,該賬戶具有非常龐大的資金儲備,足夠在測試網絡中使用,在正式網絡中将完善整個獎勵過程

> 智能合約和WASM虛拟機

同以太坊類似,鉑鍊也具有普通賬戶和合約賬戶兩種賬戶類型。在鉑鍊中,普通賬戶和合約賬戶都使用同樣一個資料結構,在普通賬戶的基礎上為其部署智能合約代碼和ABI資料(可選),那普通賬戶就算是一個合約賬戶了。鉑鍊的智能合約子產品主要為内置的合約賬戶服務,該内置合約賬戶名為“Bottos”,包含多種基礎的合約方法,像建立賬戶、交易轉賬、部署智能合約代碼和部署ABI資料等方法都實作在該合約裡,“Bottos”内置合約也是唯一一個在鉑鍊中使用ABI來為合約方法的調用參數進行解碼的智能合約,因為在WASM虛拟機中并未看到有對合約參數進行解碼的操作,這可能是因為目前鉑鍊還處在測試階段的原因,也可能是WASM虛拟機在運作合約方法時不需要從外部提供調用參數。在鉑鍊裡所有的交易都是在調用智能合約裡的方法,像最基本的交易轉賬等功能也都是由内置合約方法實作。節點在執行一個交易時會先判斷交易觸發的合約方法是否為内置合約方法,如果是則解碼交易中附帶的調用參數,然後調用該内置合約方法,比如交易轉賬,如果不是那麼就交給WASM虛拟機處理,WASM虛拟機會從交易指定的合約賬戶中查詢部署的智能合約代碼,在解析完合約代碼後就會開始運作交易中指定的合約方法,如果方法執行完畢後還發現有子交易未處理,那麼就繼續遞歸地執行下去,但遞歸深度不能超過10。鉑鍊會使用WASM位元組碼作為合約代碼應該是參考了EOS的設計,WASM全名為WebAssemly,是一個能被浏覽器解析執行的位元組碼資料,目的是為了解決JavaScript在浏覽器中運作過慢的問題。WASM最亮眼的特點就是支援将多種語言編寫的程式代碼編譯為WASM位元組碼,這其中就包括C/C++、C#、Java、JS等語言。相比于以太坊單一的Solidity智能合約語言,WASM能讓區塊鍊支援多種語言編寫智能合約代碼,這無疑會極大地豐富區塊鍊的應用生态,也是下一代區塊鍊的基本要求。扯了那麼多還是羅列下鉑鍊處理智能合約的基本流程:

a) 從交易中取出合約賬戶、合約方法和合約參數三個資料,判斷合約賬号和合約方法是否屬于内置合約

b) 如果是,則依據合約方法内置的ABI結構解析合約參數,将解析出來的參數傳遞給對應的内建函數并調用執行,交易執行完畢

c) 如果不是,則依據合約賬戶從資料庫中取出部署在該賬戶下的合約代碼,建立WASM虛拟機并解析合約代碼,找到合約代碼中的入口函數“Start”和合約方法位址,将方法的位址傳入入口函數執行,如果在執行後存在子交易要處理,則回到第一步繼續遞歸處理直到再無子交易或遞歸深度超過10為止,否則交易執行完畢

> 總結

鉑鍊的标簽就是“DPOS+WASM”,這不禁讓人聯想到EOS,可能鉑鍊就是在對标EOS,隻不過更加關注AI領域,但再造一個EOS真的有意義嗎?目前鉑鍊公開的代碼還在測試網絡中運作,期待後續跟進的Beta版主網代碼,可能會有相當大程度的改進,到時候我們再一一解析吧。希望這篇文章能讓你更進一步地了解鉑鍊(Bottos)的設計和追求的目标,目前鉑鍊的代碼已可在GitHub上下載下傳,上去搜“Bottos”就能找到,如果你對鉑鍊感興趣,不妨閱讀下他們的代碼,相信你一定會有所收獲的。相比于以太坊和EOS,鉑鍊的代碼應該更基礎也更容易閱讀,對于急切需要了解區塊鍊設計全貌的朋友來說是個不錯的切入點。再者,加入鉑鍊社群也是一個了解區塊鍊社群生态的不錯的選擇,社群裡會時不時地釋出一些有償的任務或無償的教育訓練計劃,讓社員在社群的激勵下逐漸了解一款區塊鍊産品。

繼續閱讀