在Fabric實現類似Uniswap的去中心化交易所

1.合約簡介

Uniswap是以太坊上最火爆的去中心化交易所DApp,其操作簡單,原理也很容易理解,安全而且費用低,所以被廣泛使用。
由於Fabric是基於KeyValue世界狀態的特點,沒有原生Token,沒有Gas手續費,所以所有自定義的Token都是在狀態中存儲的,而我們可以參考ERC20合約標準,創建同樣接口的合約,具體可以參考Fabric官方示例:https://github.com/hyperledger/fabric-samples/tree/master/token-erc-20

因爲Fabric採用Docker作爲合約虛擬機,所以不需要像Uniswap一樣通過工廠合約創建交易對合約來實現,而是由一個合約實現所有交易對。我們假設在這個Uniswap合約中,需要支付互換的手續費,所以我們先定義了PTN作爲手續費的Token,然後定義了ABC和PETH的通證作爲互換要用到的ERC20通證,接下來進行互換。

2 創建交易對

創建交易對或提供Token給流動性池的叫做市商。做市商A要創建一個合約中不存在的交易對時(比如ABC和PETH互換),發起如下Invoke合約的創建交易對方法的交易請求:
參數0:Payment PTN作爲手續費
參數1:Payment 1000 ABC給合約
參數2:Payment 10 PETH給合約
合約執行後會在狀態數據庫中記錄下ABC:PETH的餘額1000和100,乘積爲10000

3 Token互換交易

現在用戶B持有ABC,想換PETH,那麼他發起如下Invoke合約的互換方法的交易請求:
參數0:Payment PTN作爲手續費
參數1:Payment 100.3 ABC給合約(其中0.3爲手續費)
參數2:交易對ABC、PETH。
合約執行後,記錄ABC餘額爲1100,而爲了保持池子中的乘積不變,所以PETH餘額=10000/1100=9.09,所以合約會付給用戶B 0.91 PETH 。另外手續費池記錄下0.3分配給A。

4 增加流動性池量

現在做市商C也想參與ABC和PETH的互換,於是他需要按現在的比值 1100:9.09往池子注入。於是C發起Invoke合約的增加交易對流動池方法的交易請求:
參數0:Payment PTN作爲手續費
參數1:Payment 2200 ABC給合約
參數2:Payment 18.18 PETH給合約
合約會檢查本交易中ABC和PETH的比值,如果和合約餘額的比值不一致,那麼Token退回。如果一致,那麼記錄狀態數據庫:ABC餘額3300,PETH餘額27.27,乘積:89991

5 反向交易

現在用戶D持有PETH,想買入ABC,那麼他發起如下Invoke合約的互換方法的交易請求:
參數0:Payment PTN作爲手續費
參數1:Payment 1.003 PETH給合約(其中0.003爲手續費)
參數2:交易對參數PETH,ABC。
合約之後,PETH變成28.27,乘積保持89991不變的話,所以ABC=89991/28.27=3183.27,也就是說合約會轉給用戶D 3300-3183.27=116.73 ABC 【最新狀態餘額:ABC 3183.27, PETH 28.27】
那麼我們假設做市商C並沒有增加流動性池,那麼會怎麼樣?PETH變成10.09,ABC餘額=10000/10.09=991.08,所以ABC會付出1100-991.08=108.92 ABC
我們可以看到因爲池子變大了,所以匯率的波動性變小了,於是用戶D獲得了更多的ABC,如果池子是無限大,也就是說匯率是1100:9.09的話,用戶D應該是買到121.01個ABC。

6 手續費分配

如果只有做市商A,那麼手續費就給A了,現在有AC兩個做市商,A出了1000ABC,C出了2200ABC,所以如果收到ABC手續費的時候,按這個比例進行分配。A出了10PETH,C出了18.18PETH,所以在收到用戶D的0.003 PETH手續費時,A和C應該按他們出的PETH比例分手續費。

7 路由

如果有現在有以下交易對:
ABC<->PETH PTN <-> PETH
那麼用戶在發起ABC換PTN時,合約能夠發現其中的路由:ABC-》PETH-》PTN
因爲經過了兩次交換,所以用戶要付0.6%的手續費,每個0.3%分給其中參與了的做市商。

8 贖回流動性池

如果做市商A想贖回自己質押到流動性池中的Token,那麼他可以發起Invoke合約的贖回方法的贖回交易:
參數0:Payment PTN作爲手續費
參數1:交易對參數ABC、PETH、贖回ABC的量、贖回PETH的量。
注意這裏贖回的量的比例必須是當前流動性池的比例,如果比例不對,贖回失敗。另外贖回數量必須<=當時該用戶增加流動性時的質押數量。按照當前最新匯率ABC 3183.27: PETH 28.27=112.60,所以ABC的量最大爲1000,ETH量爲8.88
合約執行時,檢查是否滿足前面說的條件,如果滿足,則合約付出對應數量Token給A,並更新合約狀態餘額
ABC餘額 2183.27,PETH餘額19.39

9 提取手續費收益

如果做市商A積攢了不少手續費了,那麼他可以申請提取手續費。A發起Invoke合約的手續費提取方法的交易請求:
參數0:Payment PTN作爲手續費
參數1:交易對ABC、PETH、提取ABC的量、提取PETH的量。
合約檢查合約狀態中A地址的手續費餘額,如果餘額>=申請數量,則可以提取,生成從合約付出給A對應數量Token的Payment,並更新狀態數據。

10 各種查詢

用戶要進行交易需要對當前狀態進行查詢,查詢的內容包括:

10.1 交易對列表查詢

返回所有的交易對列表的Token名和流動性池中的餘額

10.2 某交易對的當前狀態查詢

傳入交易對TokenID,返回各Token餘額(也就可以計算匯率),做市商列表及他們提供的流動性數量,手續費分配列表

10.3 某交易對的交易歷史查詢

傳入交易對TokenID,返回該交易對的所有成交記錄,可以基於此繪製K線圖

10.4 路由查詢

傳入交易對TokenID,返回要完成該交易需要經過的路由以及路由中的每個交易對的當前餘額

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