KryptoCamp — Day24 — DAO 的合約程式碼研究 — 2
今天接續昨天的內容,主要研究 DAO 合約的內容以及實現方式,大部分我能找到的範例都是以 ERC-20 為判斷基準,要切換成 ERC-721 可能還有些需要研究的地方。
開始之前先了解一下昨天看到的 Moralis 這個開發工具在開發中扮演什麼角色,他可以做些什麼。
什麼是 Moralis ?
官方文件當中把自己描述成區塊鏈的 Firebase ,它提供了後端的託管,是一個專門用於開發鏈上項目的後端託管服務。
可以簡單理解為當你的前端需要後端儲存鏈上資料的時候,Moralis 可以很好的做到這個部分,讓你在開發中不再需要維護且擔心後端的服務。
關於 DAO 的合約
接下來讓我們回到 DAO 的合約裡面查看:
這是一份用 ERC-20 token 來投票的合約,他做的事情很簡單且並沒有根據持有 token 的量來給予不同數量的票數,看起來大部分的檢查是在前端做的。他主要的 function 有幾個,我們一個一個看。
createPost
這個 function 如其名,就是拿來新增一個投票 post 的,他寫在鏈上的 contentId 是用傳入的 _contentUri hash 成的 bytecode ,而不是數字,postId 也是一樣,接下來他針對 contentRegistry 與 postRegistry 將他們對應的資料寫到上方的 mapping 裡將關於 post 的資料都寫上鏈,最後發出兩個 event 給前端監聽,我預計 call 這個 function 應該是需要花不少 gas fee 的。
validateReputationChange
這個 function 主要是檢查準備投票的 address 是不是有投票的權限,他會檢查 reputationRegistry 這個 mapping 裡面某個地址對於特定的 category 有多少投票數,並且最後回傳一個布林值。表示這個地址是不是可以參與特定的投票。
voteUp
接收一個 _postId 用於判斷要投的是哪一篇 post,並且接收_reputationAdded 這參數,從程式碼上判斷應該要投的票數,最後做的事情就是切換三個 mapping 資料裡面的狀態。
voteDown
與 voteUp 類似,是一個投反對票的 function。
這個合約本身應該是有缺陷的,第一是 gas fee 應該偏高,因為他有很多資料要寫,第二是 votes 的計算方式有點奇怪,不管是投贊成還是反對應該 votes 都要增加,且程式碼寫的不太容易讀,我認為是一個比較不好的示範。且看起來並沒有從合約去限制誰可以參與這次投票,反而是從前端去抓錢包的某個 token 是否有餘額來判斷,這應該是無法直接使用的程式碼。
接著我找到了另一份關於 NFT DAO 的文章,這個就比較符合我們這次專案所需要的。
在這篇文章他提供了 openzeppelin 在實作治理投票的標準界面
可以在說明當中看到 openzeppelin 4.5 以上的版本已經有支援 ERC-721 的投票。
讓我們來看看這段由 openzeppelin 的 contract wizard 所產生的模板合約
首先 constructor 的部分有大量的 contract 需要初始化,分別帶入他們所需要的參數。
在文件當中提到使用 Governor 必須實作一些 function,這邊也都有實作到。
這段程式碼做了什麼事情:
- votingDelay 回傳投票正式開始的延遲時間,實際的值寫在 GevernorSetting 的建構子當中。
- quorum 回傳要發起一個投票的人數,或者說是票數,也寫在 GevernorSetting 的建構子。
- votingPeriod 回傳投票的進行期間,GevernorSetting 建構子的一部分
- getVotes 回傳經過計算的票數,邏輯需自定義。
- state 回傳某個投票的狀態,遵循 Compound’s Governor Alpha & Bravo 所定義的狀態
- propose 利用這個 function 創建一個投票。
- _execute 用以執行投票的結果,細節尚不清楚。
- _cancel 將投票取消。
- executor 把回傳合約地址。
- supportsInterface 看起來是做了某種判斷,ERC165,允許驗證我們合約中使用的接口。