如何添加参与者从DAO购买代币的功能以及在Story中添加提交内容。编写DAO的最终形式:投票,黑名单,股息分配和退出。我们将提供一些额外的辅助函数以便进行监测。开发详细教程如下:
投票和提案
发布Votes并投票。这需要两个新的结构:
struct Proposal {
string description;
bool executed;
int256 currentResult;
uint8 typeFlag; // 1 = delete
bytes32 target; // ID of the proposal target. I.e. flag 1, target XXXXXX (hash) means proposal to delete submissions[hash]
uint256 creationDate;
uint256 deadline;
mapping (address => bool) voters;
Vote[] votes;
address submitter;
}
Proposal[] public proposals;
uint256 proposalCount = 0;
event ProposalAdded(uint256 id, uint8 typeFlag, bytes32 hash, string description, address submitter);
event ProposalExecuted(uint256 id);
event Voted(address voter, bool vote, uint256 power, string justification);
struct Vote {
bool inSupport;
address voter;
string justification;
uint256 power;
}
提案将对选民进行映射,以防止人们对提案进行两次投票,以及其他一些应该不言自明的元数据。投票将是一个是或否投票,并将记住选民以及他们以某种方式投票的理由,以及投票权——他们希望投入该投票的代币数量。我们还添加了一系列Proposals,以便我们可以将它们存储在某个地方,并提供一个计数器来计算有多少提案。
现在构建他们的附属函数,从投票函数开始:
modifier tokenHoldersOnly() {
require(token.balanceOf(msg.sender) >= 10**token.decimals());
_;
}
function vote(uint256 _proposalId, bool _vote, string _description, uint256 _votePower) tokenHoldersOnly public returns (int256) {
require(_votePower > 0, "At least some power must be given to the vote.");
require(uint256(_votePower) now, "Proposal must not have expired.");
require(p.voters[msg.sender] == false, "User must not have already voted.");
uint256 voteid = p.votes.length++;
Vote storage pvote = p.votes[voteid];
pvote.inSupport = _vote;
pvote.justification = _description;
pvote.voter = msg.sender;
pvote.power = _votePower;
p.voters[msg.sender] = true;
p.currentResult = (_vote) ? p.currentResult + int256(_votePower) : p.currentResult - int256(_votePower);
token.increaseLockedAmount(msg.sender, _votePower);
emit Voted(msg.sender, _vote, _votePower, _description);
return p.currentResult;
}
注意函数修饰符:通过将该修饰符添加到我们的合约中,我们可以将它附加到任何将来的函数,并确保只有令牌持有者才能执行该函数。这是一个可重复使用的安全检查!
投票功能做了一些健壮性检查,例如投票权是积极的,选民有足够的代币实际投票等。然后我们从存储中获取提案并确保它既没有过期也没有已经执行。对已经完成的提案进行投票是没有意义的。我们还需要确保这个人还没有投票。我们可以允许改变投票权,但这会让DAO面临一些漏洞,例如人们在最后一刻撤回投票等等。也许是未来版本的候选人?
然后我们在提案中注册一个新的投票,更改当前结果以便于查找分数,最后发出Voted事件。但是什么是token.increaseLockedAmount?
这一点逻辑增加了用户的锁定代币数量。该功能只能由代币合约的所有者执行(此时希望是DAO)并且将阻止用户发送超过其帐户注册的锁定金额的令牌数量。提案落实或执行后,此锁定被解除。