Skip to content

Commit 2360d8a

Browse files
committed
translation of quadratic-vote
1 parent 08962a8 commit 2360d8a

File tree

3 files changed

+213
-153
lines changed

3 files changed

+213
-153
lines changed

basic/26-quadratic-vote&gitcoin/README-CN.md

Lines changed: 92 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,22 @@
1717

1818
如果我们希望同时考虑人们对不同问题的关注程度,又避免完全“用钱买影响力”的困局,应该怎么办呢? 这个时候就可以使用 "二次方投票" 和 "二次方资助"
1919

20+
### Quadratic-Vote-Wiki
21+
22+
平方投票允许投票者为额外投票“付费”,以更强烈地表达对特定议题的支持,从而导致投票结果与支付结果的最高意愿一致,而不仅仅是用户偏好的结果。无论个人偏好的强度如何。投票的支付可以通过人工或真实货币(例如,在投票成员之间平均分配代币或使用真实货币)。平方投票是基数投票类别中累积投票的变体。它与累积投票的不同之处在于将“成本”和“投票”关系从线性变为平方。
23+
24+
基于市场原则,平方投票每个投票者都会事先获得了一些投票点数。他们可以使用这些点数来投票,藉以影响投票结果。如果投票者强烈支持或反对特定决定,可以花费点数,来取得额外的选票。平方投票,借此显示选民的支持、反对程度。选票价格规则决定了额外投票的成本,每多取得一次额外投票的成本会变得越来越昂贵。通过增加选民点数成本,来凸显个人对特定决定的支持。如果使用金钱,而非点数,这些花费最终会透过公共支出返回至选民身上。格伦·韦尔和 Steven Lalley 进行了相关研究,主张平方投票法的决策效率会随着选民数量的增加而增加。平方投票函数的简化公式是:
25+
26+
```math
27+
选民的投票成本 = (投票数)^2
28+
```
29+
30+
智能合约中的公式稍有不同:
31+
32+
```math
33+
选民的投票成本 = 2^0 + 2^1 + 2^2 + ... + 2^(n-1)
34+
```
35+
2036
## 代码解读
2137

2238
1. voteTool 二次方投票
@@ -26,15 +42,13 @@
2642

2743
两个的提案都是先通过 hash 获取到 id
2844

29-
```
45+
```solidity
3046
function hash(bytes memory _b) public pure returns (bytes32){
3147
return keccak256(_b);
3248
}
3349
```
3450

35-
在实际添加或者投票的时候用的上面获取到的 id, 内部用的数字,是为了 event 可以保持该 id
36-
37-
实际好像 bytes32 也可以,但是 bytes/string 不行,event 中会被 hash
51+
由于 `bytes``string` 等动态类型作为 event 的 indexed 参数,将会被 hash,所以直接把 hash 数值作为投票的 id 值。
3852

3953
### 共性二
4054

@@ -46,92 +60,107 @@ function hash(bytes memory _b) public pure returns (bytes32){
4660
### voteTool
4761

4862
二次方投票, 票数越多,需要金额越多
49-
例: 第一票 1eth,第二票 2eth, 第三票 4eth,第四票 8eth,
50-
票数 n 金额 = 2\*\*(n-1)
63+
64+
例: 第一票 1eth,第二票 2eth, 第三票 4eth,第四票 8eth...
65+
66+
那么第 n 票的成本则是:
67+
68+
```math
69+
cost to the voter = 2^(n-1)
70+
```
5171

5272
暂未兼容 eth/token 一起投
5373

54-
- addProposal(uint256 \_proposal) public onlyOwner (添加提案)
55-
- expireProposal(uint256 \_proposal) public onlyOwner (过期后无法再投票)
56-
- vote(uint256 \_proposal, uint256 \_n) public payable(投票)
57-
- withdraw() public onlyOwner(内部只是提 eth, 代币需要修改)
74+
- `addProposal(uint256 _proposal) public onlyOwner` (添加提案)
75+
- `expireProposal(uint256 _proposal) public onlyOwner` (过期后无法再投票)
76+
- `vote(uint256 _proposal, uint256 _n) public payable` (投票)
77+
- `withdraw() public onlyOwner` (内部只是提 eth, 代币需要修改)
5878

5979
### financingTool
6080

81+
![quadratic_funding.png](https://vitalik.ca/images/qv-files/quadratic_funding.png)
82+
6183
每个用户针对某个提案投票都是总金额的开平方
62-
公式解读由 **Harry** 提供
6384

64-
```
65-
/**
66-
绿色:
67-
项目A:1*1 = 1
68-
项目B:
69-
用户1:4:边长2
70-
用户2:16:边长4,总计 6
71-
用户1:12,总计:6-2+(4+12)开根号=8
72-
项目C:2*2=4
73-
项目D:3*3=9
74-
75-
底边总长度:1+8+2+3=14
76-
77-
总方块面积:14*14 = 196
78-
79-
配捐 = 196-(1+32+4+9) = 150
80-
81-
最终:
82-
A:1 + 1/14 * 150 = 11.714285714
83-
B: 32 + 8/14 * 150 = 117.714285714
84-
C: 4 + 2/14 * 150 = 25.428571429
85-
D: 9 + 3/14 * 150 = 41.142857143
86-
*/
87-
88-
struct Proposal {
89-
uint256 name;//提案id
90-
uint256 amount;//获得的金额
91-
uint256 voteCount;//获得的份额
92-
address owner;
93-
address[] userAddrArr;//捐助用户地址
94-
uint8 isEnd;//0,1
95-
}
96-
97-
struct UserVote {//每个用户每个提案会有一个实例
98-
uint256 count;//份额
99-
uint256 amount;//金额
100-
}
85+
1. 每个绿色的方块代表一次捐助的金额,大正方形的面积 C 可以理解为总资助池金额,而黄色部分面积 S 可以理解为一个由外部支持的补助资金池。我们把所有绿色方块排列在大正方形的对角线上。这时,每一个贡献者投入的金额是 `c_i`,那么大正方形的面积是 `C=(sum(sqrt(c_i)))^2`,补助金额 `S=C−sum(c_i)`
86+
2. 在任何时候,只要有多于一个贡献者,那么 `C > sum(c_i)`
87+
3. 如果 S 和补助资金池不完全一致,可以根据黄色的面积按比例分配
88+
4. 多次小额的捐助可以导致很大的黄色面积,从而让项目赢得更多的资金配比
89+
90+
```solidity
91+
/**
92+
公式解读由 Harry 提供:
93+
绿色:
94+
项目A:1*1 = 1
95+
项目B:
96+
用户1:4:边长2
97+
用户2:16:边长4,总计 6
98+
用户1:12,总计:6-2+(4+12)开根号=8
99+
项目C:2*2=4
100+
项目D:3*3=9
101+
102+
底边总长度:1+8+2+3=14
103+
104+
总方块面积:14*14 = 196
105+
106+
配捐 = 196-(1+32+4+9) = 150
107+
108+
最终:
109+
A:1 + 1/14 * 150 = 11.714285714
110+
B: 32 + 8/14 * 150 = 117.714285714
111+
C: 4 + 2/14 * 150 = 25.428571429
112+
D: 9 + 3/14 * 150 = 41.142857143
113+
*/
114+
115+
struct Proposal {
116+
uint256 name;//提案id
117+
uint256 amount;//获得的金额
118+
uint256 voteCount;//获得的份额
119+
address owner;
120+
address[] userAddrArr;//捐助用户地址
121+
uint8 isEnd;//0,1
122+
}
123+
124+
struct UserVote {//每个用户每个提案会有一个实例
125+
uint256 count;//份额
126+
uint256 amount;//金额
127+
}
101128
102129
```
103130

104131
场景:每个人可以对多个提案进行捐助,在一定时间内结束,结束后给一定时间用于增加配捐时间,确认完整结束后,可以由提案 owner 去领取捐助额。
105132

106-
- addProposal(uint256 \_proposal) public onlyOwner(添加提案内部的 p.owner=msg.sender 有误看需求修改)
107-
- vote(uint256 \_proposal, uint256 \_inAmount) public payable(捐助)
108-
- addExtraAmount(address \_maker, uint256 \_inAmount) public payable(配捐\_maker 标记谁配捐的)
109-
- withdrawProposal(uint256 \_proposal) public checkEnd(结束后提取捐助额)
110-
- function getResult(uint256 \_proposal) public view returns (uint256, uint256) (查询提案目前的捐助额/份额)
111-
- 其他就是相关查询方法 test 开头的只是测试方法
133+
- `addProposal(uint256 _proposal) public onlyOwner` (添加提案, 内部的 p.owner=msg.sender 有误, 看需求修改)
134+
- `vote(uint256 _proposal, uint256 _inAmount) public payable` (捐助)
135+
- `addExtraAmount(address _maker, uint256 _inAmount) public payable` (配捐, _maker 标记谁配捐的)
136+
- `withdrawProposal(uint256 _proposal) public checkEnd` (结束后提取捐助额)
137+
- `function getResult(uint256 _proposal) public view returns (uint256, uint256)` (查询提案目前的捐助额/份额)
138+
- 其他就是相关查询方法, test 开头的只是测试方法
112139

113140
## 测试步骤
114141

115142
- 安装依赖
116143

117-
```
118-
yarn
119-
```
144+
```sh
145+
yarn
146+
```
120147

121148
- 编译合约
122149

123-
```
124-
npx hardhat compile
125-
```
150+
```sh
151+
npx hardhat compile
152+
```
126153

127154
- 执行测试脚本
128155

129-
```
130-
npx hardhat test
131-
```
156+
```sh
157+
npx hardhat test
158+
```
132159

133160
## 参考资料
134161

162+
- [Quadratic Payments: A Primer](https://vitalik.ca/general/2019/12/07/quadratic.html)
135163
- [二次方投票和二次方资助](https://www.matataki.io/p/6113)
136164
- [视频](https://www.bilibili.com/video/BV1Y5411w77b/)
137165
- [gitcoin](https://gitcoin.co/blog/gitcoin-grants-quadratic-funding-for-the-world/)
166+
- [Quadratic voting-WIKI](https://en.wikipedia.org/wiki/Quadratic_voting)

0 commit comments

Comments
 (0)