深入解析ViteX內建合約設計

買賣虛擬貨幣
這是第三篇給大家介紹關於ViteX的技術文章,本篇文章主要從ViteX整體設計、效能最佳化及系統可靠性三個方面介紹了vDex內建合約的設計背景、思路及方案。希望大家能更深入的理解ViteX執行機制。ViteX作為去中心化交易所,透過內建合約vDex實現撮合引擎及ViteX經濟模型的相關功能,在實現高效能的同時兼顧實現的簡潔,簡單的系統更健壯。在之前的一篇文章《ViteX內建合約設計與實現簡介》中我們已經就內建合約的關鍵設計細節進行了介紹,本篇文章從幾個比較有代表性的問題入手介紹一下相關的設計背景、思路及方案。1.vDex為什麼要分兩個合約來實現ViteX交易所要實現訂單撮合和平臺經濟模型的兩個核心功能,如果放在一個合約裡面實現,不便於問題的聚焦,會造成問題的開發人員及外部介面使用人員的困惑,很自然的想到把他們拆分。另外,撮合引擎從概念上是基礎功能,從設計之初並不對外直接暴露介面,和經濟模型解耦後,便於後續的撮合引擎升級。具體拆分的兩個合約是dexFund和dexTrade,dexTrade實現訂單薄儲存及訂單撮合的功能,dexFund完成資產、挖礦及分紅等ViteX經濟模型相關功能。2.為什麼會有兩種訂單id《ViteX內建合約設計與實現簡介》介紹過訂單id的詳細設計,該訂單id是為了最大化效能訴求而設計的,實現鏈上訂單有序儲存和高效的撮合,在這裡記為baseOrderId。後續我們還新增了使用者鏈下單tx的hash作為key的訂單id,這裡記為hashOrderId,和baseOrderId依賴於合約拼接生成不同,hashOrderId在使用者下單的一刻就能生成,客戶端可以直接把這個id暫存下來而不必等待vDex的輸出,便於進行訂單後續狀態的追蹤和操作,從這個角度看hashOrderId是客戶端友好的訂單id。兩種訂單id分別都有自己適用的場景,實現了效能和使用者體驗的兼顧。
3.撤單為什麼有兩個入口

因為訂單薄的儲存是在dexTrade合約,撤單直接和訂單薄互動,所以最初的撤單入口也是放在dexTrade。但是下單功能因為會涉及到資金凍結所以是以dexFund合約為入口的,這就導致了下單和撤單有不同的入口。在合約實際執行的過程中會出現訂單下單後因為鏈上共識延遲沒有寫入dexTrade訂單薄就進行撤單的情況,此時撤單操作會因為不能從訂單薄查到訂單而導致執行失敗。為此,我們在dexFund合約新增了撤單入口,對同一個訂單來說因為是同一個使用者發出的交易,透過使用者鏈的交易順序性保證撤單操作肯定會在下單後上鏈執行,有效的撤單肯定可以正確執行。對比兩個撤單入口能夠發現,dexTrade合約的撤單入口因為避免dexFund合約的轉發所以更加直接和輕量級,而dexFund合約因為經過了dexFund合約會需要額外的開銷,但是該入口提供了代理撤單的先驗操作,所以如果是代理撤單就必須走dexFund合約來撤單, 具體來說dexTrade撤單入口適合實時性要求不高的普通使用者,而dexFund撤單入口適合對實時性要求較高的自動化呼叫。

4.訂單撮合效能問題

要提升撮合效能就必須要能快速的匹配待撮合訂單,常用的做法是將頭部訂單或者全部訂單都放入記憶體來實現高效的訪問。但是對於鏈上合約來說,因為受限於鏈底層提供的介面能力訪問儲存,不能做到訂單薄常駐記憶體。這時候可以考慮方式是充分利用底層儲存的特點,保證訂單薄有序儲存,這樣撮合過程只需要依次簡單迭代訪問就可以了。由此我們得到了《ViteX內建合約設計與實現簡介》所介紹的訂單id的設計方案,透過把價格作為訂單id的一部分,而訂單id是底層key有序levelDB的儲存key,這樣訂單薄在底層儲存就是價格有序,透過簡單的key順序遍歷即可完成撮合過程。這樣的實現足夠簡單也非常高效。

5.減少儲存佔用的一些辦法

鏈上儲存的成本是很高的,為了儘量減少儲存資料,我們採取了以下三種手段。第一,透過Protobuf來實現物件的序列化,從源頭減少資料量。第二, 不重複儲存不變的資料,避免冗餘,這裡主要體現在挖礦和分紅相關的指標處理部分,如果指標長期不變,則只儲存最早的一個指標,只有變更的時候才儲存新值。第三,實時清理和定時清理相結合。對於挖礦、分紅中累計的多版本指標資料,對於已經計算完結果的指標實時刪掉資料。定時清理則是針對訂單資料,為了避免訂單薄無限膨脹,會為所有訂單設定超時失效時間戳,定時透過批次介面清理這些失效訂單,實現鏈上訂單的滾動清理。

6.vDex如何提高可靠性

作為內建合約,vDex每行程式碼的實現都是協議,要保證協議的執行正確性,除了透過測試發現問題外,從設計之初就考慮如何提高模組的可靠性。vDex在最初設計的時候,一條重要的原則就是要兼顧簡潔和高效能,過於複雜的設計會成倍提高程式碼量,同時出錯概率也會相應增加。以簡潔為原則,我們的相關資料結構都儘量精簡欄位,不相關的資訊不做儲存,或者放到鏈下儲存,鏈上只處理通常不會改變的核心資料結構,盡力避免資訊冗餘,透過鏈下配套服務來實現傳統交易所的多維度的豐富查詢和展示。程式碼實現層面,控制單個函式的程式碼行數,適時進行拆分和精心命名,控制複雜度的同時也極大減少了重複程式碼的出現,結構更合理之後,每個實現細節也就更清晰,便於理解而不容易出錯。最後,透過《ViteX內建合約設計與實現簡介》提到的對賬機制,我們也能夠從另外一個角度驗證程式碼執行的正確性,同時保證使用者資產的安全。

透過以上幾個問題,我們從整體設計、效能最佳化及系統可靠性三個方面介紹了vDex內建合約的設計背景、思路及方案,這些設計細節體現了ViteX為了達成簡單、高效、透明的目標所做的實踐,希望以上介紹可以幫助大家理清ViteX的去中心化執行機制。

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;