MACI 是Minimal Anti-Collusion Infrastructure的缩写, Vitalik在2019年5月于ethreaser.ch所提出,为了让用应用程式在区块链上可以有抵抗共谋的一个机制(主要是想达到正确地执行你的想法跟抗审查(censorship resistance))。而最实际的应用就是投票,若在区块链上投票能做到他人无法查验你的票,这样行贿者就无法知道你是否有乖乖投票,如此一来就能减低行贿的诱因。
基本流程大致为
- 欲投票者需要注册期间内,以公钥(EdDSA)向合约注册身份
- 注册期结束
- 投票开始,投票者将自己的票加密送到合约
- 投票结束,协调者(coordinator)从合约上抓下所有的票, 计算结果,并产生zk证明到合约,更新票数(注1)
MACI中最关键的机制在于,投票结束前,投票者都可以向合约发出更换公钥的指令,然后再使用新的公私钥去投票。当协调者计票时,会去合约上找注册者的公钥,若发现此身份有更换过公钥,则旧公钥所投的票就会被认定为无效票。程序大约为
- Alice注册身份为公钥A
- 行贿者利诱或威胁Alice 投赞成票,而Alice 也照行贿者的意思投给了赞成票
- 在投票结束前,Alice随时可以向合约更改身份为公钥B
- 更改完公钥后,Alice可再用私钥B签章投反对票
- 当协调者计票时,会发现用公钥A已经被改为公钥B,所以私钥A所签的赞成票,将记为无效票
再深入一点细节. . .
- 使用者注册先产生一组EdDSA的私钥对(注2),再是透过合约的signUp()注册公钥,而合约中有一merkle tree记载着帐号相关的资讯
- 接着使用者产生一组临时的(ECDSA)私钥对prvE/pubE(每次投票就产生一组)
- 利用这组临时的私钥prvE跟协调者的公钥pubC产生加密的钥匙EncKey,使用密钥EncKey加密投票指令(command)(注3)
- 再将临时的公钥pubE与加密过的指令,透过合约的publishMessage()上链
- 协调者透过ECDH交换秘密的方式可以得到EncKey,当投票结束时协调者再使用这把密钥把讯息(注3)解密,接着更新票数。
而更换公钥的指令也是透过publishMessage()上链,因为上链的指令都是加密过的,也只有协调者能解密,因此行贿者无法得知受贿者是否有更换过身份。
在MACI中,所有讯息都是上链的,因此不怕协调者不打包特定资料。不过所有资料协调者都可以解密,行贿者可以直接与协调者串通,去得知受贿者们是否有乖乖投票,如何防范不在MACI原本的提案内,有兴趣的人可以去MACI Github上了解实作细节。
注1:对!MACI系统中协调者必须是诚实的
注2:在snarks的应用中通常使用EdDSA做签章,而非以太的ECDSA,因为EdDSA在zk circuit的实作上复杂度比较低。
注3:在MACI中投票,更换公钥等动作都称作指令(command),而加密后的指令称作讯息(message)
原创文章,作者:惊蛰财经,如若转载,请注明出处:http://www.xmlm.net/bi/31765.html