這篇文章的目標是為設計一種“非合作二次方投票”,或“抗勾結二次方投票”的機製做準備。
作者:Eric Zhang
建築師@DoraFactory @DoraHacks
關於這篇文章的背景,請參考《二次方投票和二次方資助》。在這篇文章發布後的一個月,BSC基金會在DoraHacks開發者平台HackerLink上運行了BSC生態第一輪二次方資助,並在其後的15天中收到了全球超過60個開發者團隊提交的項目。
在《二次方投票和二次方資助》中,我介紹了Vitalik的博客《Quadratic Payments》所提到的三個問題:身份偽造攻擊(Identity Bribery)、勾結(Collusion)、理性忽視問題(Rational Ignorance)。這三個問題其實不限於二次方投票,而是鏈上治理機制所遇到的通用問題。因此,這些問題的解決方案不僅可以使得二次方投票更規模化和更安全,還可以惠及更多鏈上治理的機制。
這篇文章的目標是為設計一種“非合作二次方投票”,或“抗勾結二次方投票”的機製做準備。在這種場景下,投票者無法相互之間合作,因此就沒有了勾結的可能性。這種機制一個基礎框架是,Vitalik Buterin在Ethresear上發表的文章《Minimal anti-collusion infrastructure》[1] (MACI)。因此,我們先解釋MACI的機制,從而為進一步探討如何使用MACI改進二次方投票,消除勾結(Collusion)的可能性。
MACI:最小的反共謀基礎設施
MACI是“最小化抗勾結框架”。背景材料參考Vitalik Buterin 的博客https://ethresear.ch/t/minimal-anti-collusion-infrastructure/5413 ,以及《On Collusion》 https://vitalik.ca/general/2019/04/03/collusion.html
很多的鏈上治理應用需要“抗勾結”這個特性,但同時又需要區塊鏈對交易執行以及抗審查、保護隱私的保證。投票是有這種需求的一個重要場景,因為很明顯在投票中,抗勾結是必須的,同時對執行結果的正確性的要求是很高的,需要保護計票過程,最後,還需要防止對投票者的審查。
設置
假設有一個智能合約(R),包含一個公鑰的列表(K_1 … K_n), 以及一些必要的函數,可以把這些公鑰註冊到智能合約中。另外,只有符合以下兩個條件驗證身份的參與者的公鑰可以進入到R中:
賬戶屬於一個“合法”的參與者(一個獨立的人,某個社區的成員,比如擁有某個國家的國籍、在一個論壇上有足夠高的聲譽、持有不少於某個數量的Token…)
賬戶持有人個人控制密鑰(例如,如果需要的話,可以打印出來以證明)
每一個用戶需要stake一筆錢: 如果任何人洩漏了自己的私鑰,那麼得到私鑰的人可以直接取走這筆錢,從而這個賬戶就會從列表中被移除。這個機制抑制了任何人把私鑰交給別人。
另外,假設有一個操作員((operator)),他有一個私鑰(k_omega), 和一個對應的公鑰(K_omega).
最後,假設有一個機制(M), 它是一個函數(action^n rightarrow Outputs), 其中,函數的輸入是(n)個參與者的行為,輸出是這個函數定義的某種輸出結果。例如,一個簡單的投票機制是一個函數,根據輸入的值,輸出出現次數最多的那個值。
執行
在起始時間(T_{start}),(operator)開始一個其實狀態(S_{start} = {i: (key=K_i, action = phi)}, i in 1…n).
在起始時間(T_{start})和結束時間(T_{end})之間,任何註冊的參與者可以向R發送消息,消息用參與者自己的私鑰(k)加密。有兩種消息:
約定行為: 例如投票。參與者需要發送加密過的消息(enc(msg = (i, sign(msg = action, key = k_i)), pubkey = K_omega)), 其中(k_i)是這個參與者當前的私鑰,(i)是參與者在(R)中的id
更新密鑰: 參與者需要發送加密過的消息(enc(msg = (i, sign(msg = NewK_i, key = k_i)), pubkey = K_omega)), 其中(NewK_i)是參與者要變更的公鑰, (k_i)是這個參與者當前的私鑰
這時,操作員的工作是按照消息上鍊的先後順序處理每一個消息。具體的處理過程:
使用操作員私鑰解密消息。如果解密失敗,或者解密對應的信息無法解碼成為以上的兩類信息,則直接跳過這條信息
使用(state[i].key)驗證消息的簽名
如果解碼後的消息是約定的行為((action)),那麼設置(state[i] = action), 如果解碼後的消息是一個新的公鑰,那麼設置(state[i].key = NewK_i)
在(T_{end})之後,操作員必須公佈輸出狀態(M(state[1].action, … , 狀態[n].action)), 同時給出一個ZK-SNARK,證明這個輸出是正確的結果。
為什麼這個機制是抗勾結的
假設一個參與者想要證明他做過什麼,例如做過(action) (A),他可以引用一個鏈上的交易(enc(msg = (i, sign(msg = A, key = k_i)), pubkey = K_omega)),並且提供一個零知識證明,驗證這筆交易的確是包含(A)的加密信息。但是,他無法證明他沒有發出別的交易,例如他可能發出過一筆更早的交易,把公鑰換成了一個新的(NewK_i),因此前面的證明也就變得沒有意義了,因為如果他更換過密鑰的話,他可能已經做了別的動作。
參與者還可能把私鑰給其他人,但是這樣做的話那個人拿到私鑰後就可以立即試圖修改密鑰。這樣的話1) 有50%的成功率,2) 會導致拿到密鑰的人直接拿走之前stake的存款。
MACI未解決的問題
接收方在可信硬件環境中,或者接收方在可信多籤的情況下,賣出私鑰
原有的私鑰在一個可信的硬件環境中的攻擊,這個環境可以防止私鑰變更為任何攻擊者們不事先知道的私鑰
第一種情況,可以通過特別設計的複雜簽名機制,而這種設計對可信硬件和多簽不友好。不過這種設計需要確保驗證函數對ZKP友好。
第二種情況可以通過“面對面零知識證明”解決,例如,參與者可以把私鑰拆解為(x + y = k_i),公佈(X = x*G) 和(Y = y*G), 並且給驗證者展示兩個信封,分別包含(x)和(y); 驗證者打開一個,檢查公佈的(Y)是正確的,然後檢查(X + Y = K_i)。
非合作二次方投票
這種機制可以用來改進包括投票在內的多種鏈上治理機制。在二次方資助中,當資金池規模非常大的時候,或者當二次方資助被用於更大的場景時(例如大選、國會審批預算等場景),勾結就會成為一個必須被解決的問題。因此,設計一個抗勾結二次方投票(Anti-collusion quadratic funding)機制,可以規模化二次方資助。
[1]Vitalik Buterin,最小的反共謀基礎設施,
https://ethresear.ch/t/minimal-anti-collusion-infrastructure/5413
展開全文打開碳鏈價值APP 查看更多精彩資訊