KryptoCamp — Day25 — DAO 合約程式碼研究

Galen-Ting
廢物到工程師的一大步
4 min readMar 12, 2022

今天來仔細研究關於 openzeppelin 文件當中寫到的治理合約應該如何實作,以下附上今天的文件。

在 openzeppelin 提供 Governor 之前,有兩個很用於治理投票的合約分別是 Governor BravoGovernor Alpha,這兩個合約都是用於解決 DAO 與 defi 的治理相關問題,基本上可以認為 Governor Bravo 是 Governor Alpha 的升級版,團隊接下來也只打算維護 Governor Bravo 的合約,Alpha 的合約至今日已經兩年多沒有更新了,以下簡單附上兩者的區別:

https://medium.com/tally-blog/understanding-governor-bravo-69b06f1875da

而 openzeppelin 跟 Governor Bravo 比起來比較方便的地方是可以很簡單的引入,即使有與 Governor Bravo 不一樣的需求,也可以利用模塊化的部分依序引入自己需要的部分即可,而不用 fork 回來做修改,不過做的事情基本上是差不多的。

另外即使是已經有使用 Governor Bravo 的項目,在 openzeppelin 也提供了相同的接口,就算要切換使用也不會有太大的問題。

為了與 Governor Bravo 兼容,很多 module 都有兩個版本,如果沒有從 Governor Bravo 更換的需求,則通常採用名稱比較短的那個即可。

如果想要在 token 合約上開啟治理功能,那麽 ERC-20 需要引入 ERC20Votes ,如果是 ERC-721 的話則需要引入 ERC721Votes

如果你的合約只引入了核心的 Governor,那麼至少還有四件事情是你需要定義的:

  • 如何確定投票權
  • 要開啟一個投票需要多少票
  • 人們在投票時有哪些選擇以及這些選票如何計數
  • 應該使用什麼類型的令牌進行投票

你可以選擇自己定義或是直接使用 openzeppelin 提供的 module 。

如果要開啟一個投票的提案,就需要執行 propose function ,這裡面要帶入四個參數,看 _execute 的程式碼可以知道每個參數都是一組一組的,也就是說每個 targets會分別對到每一個 valuescalldatas ,並且依序執行。利用這種方式可以先將我們預期要投票的提案先打包成 calldatas並投票,提案成的話就可以執行已經打包好的交易。

真正執行投票的時候則是呼叫 castVote function 來進行。等到投票都進行完成,則依據是否有使用時間鎖,若是有則要先呼叫 queue function 進入列隊,並且等到等待足夠的時間後就可以執行 execute 執行投票的提案。

或是沒有使用時間鎖的話,則可以在投票結果出來後直接執行 execute function ,執行時的邏輯可以看這裡。在其中看到的 call function 是一個低階的 function 呼叫方法,一般而言不太推薦用這個呼叫方式,但是當你是調用 fallback function 時這是比較推薦使用方式。

關於 fallback function 可以參考這個影片。

--

--

Galen-Ting
廢物到工程師的一大步

學程式不無聊,無聊就不學程式,皮皮的學習好過死死的學習。