In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-07 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly introduces "how to use custom tokens to vote in the construction of DApps in Ethernet Square". In daily operation, I believe many people have doubts about how to use custom tokens to vote in the construction of DApps in Etai Fang. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubts about how to use custom tokens to vote in the construction of DApps in Yi Tai Fang. Next, please follow the editor to study!
Votes and proposals
We will release Votes and vote. This requires two new structures:
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 X 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;}
The proposal would map voters to prevent people from voting twice on the proposal and other metadata that should be self-evident. Voting will be a yes or no vote, and will remember voters and their reasons for voting in some way, as well as the right to vote-the number of tokens they want to put into the vote. We have also added a series of Proposals so that we can store them somewhere and provide a counter to calculate how many proposals there are.
Let's now build their adjunct function, starting with the voting function:
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.votes [msg.sender] = = false, "User must not have already voted."); uint256 voteid = p.votes.originthpieces; 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;}
Pay attention to the function modifier: by adding this modifier to our contract, we can attach it to any future function and ensure that only the token holder can execute the function. This is a reusable security check!
The voting function has done some robustness tests, such as the right to vote is positive, voters have enough tokens to actually vote, and so on. Then we get the proposal from the store and make sure it is neither expired nor implemented. There is no point in voting on a proposal that has been completed. We also need to make sure that this person hasn't voted yet. We can allow changes in voting rights, but this will expose DAO to some loopholes, such as people withdrawing their votes at the last minute. Maybe a candidate for a future version?
Then we register a new vote in the proposal, change the current result to make it easier to find the score, and finally issue the Voted event. But what is token.increaseLockedAmount?
This logic increases the number of tokens locked by the user. This function can only be performed by the owner of the token contract (hopefully DAO at this time) and will prevent users from sending the number of tokens that exceed the locked amount registered for their account. After the proposal is implemented or implemented, the lock is lifted.
Let's write the function that now proposes to delete the entry.
Vote to delete and blacklist
As described in part 1 of this series, we plan three entry deletion features:
1. Delete entry: after confirming by voting, the target entry will be deleted. Voting time: 48 hours.
two。 Emergency delete entry [owner only]: can only be triggered by the owner. Once confirmed by a vote, the target entry will be deleted. Voting time: 24 hours.
3. Emergency deletion of images [owner only]: applies to image entries only. Can only be triggered by the owner. Once confirmed by a vote, the target entry will be deleted. Voting time: 4 hours.
Five deletions of a single address entry result in a blacklist.
Let's see what we can do now. First, delete the feature:
Modifier memberOnly () {require (whitelist [msg.sender]); require (! blacklist [msg.sender]); _;} function proposeDeletion (bytes32 _ hash, string _ description) memberOnly public {require (submissionExists (_ hash), "Submission must exist to be deletable"); uint256 proposalId = proposals.length++; Proposal storage p = proposals [proposalId]; p.description = _ description; p.executed = false; p.creationDate = now; p.submitter = msg.sender P.typeFlag = 1; p.target = _ hash; p.deadline = now + 2 days; emit ProposalAdded (proposalId, 1, _ hash, _ description, msg.sender); proposalCount = proposalId + 1;} function proposeDeletionUrgent (bytes32 _ hash, string _ description) onlyOwner public {require (submissionExists (_ hash), "Submission must exist to be deletable"); uint256 proposalId = proposals.length++; Proposal storage p = proposals [proposalId]; p.description = _ description; p.executed = false P.creationDate = now; p.submitter = msg.sender; p.typeFlag = 1; p.target = _ hash; p.deadline = now + 12 hours; emit ProposalAdded (proposalId, 1, _ hash, _ description, msg.sender); proposalCount = proposalId + 1;} function proposeDeletionUrgentImage (bytes32 _ hash, string _ description) onlyOwner public {require (submissions [_ hash]. Image = true, "Submission must be existing image"); uint256 proposalId = proposals.length++ Proposal storage p = proposals [proposalId]; p.description = _ description; p.executed = false; p.creationDate = now; p.submitter = msg.sender; p.typeFlag = 1; p.target = _ hash; p.deadline = now + 4 hours; emit ProposalAdded (proposalId, 1, _ hash, _ description, msg.sender); proposalCount = proposalId + 1;}
Once made, the proposal is added to the list of proposals and the entry for which the hash is targeted is recorded. Save the description and add some default values, and calculate the deadline based on the proposal type. The proposal added events and the total number of proposals increased.
Next, let's look at how to implement the proposal. In order to be enforceable, the proposal must have a sufficient number of votes and must exceed its deadline. The execution function will accept the ID of the proposal to be executed. There is no easy way for EVM to execute all outstanding proposals immediately. There may be too many people waiting for execution, and they will make major changes to the data in the DAO, which may exceed the gas limit of the Ethernet block, causing the transaction to fail. It is much easier to build a manual execution function that can be invoked by anyone with clear rules, so the community can focus on the proposals that need to be implemented.
Function executeProposal (uint256 _ id) public {Proposal storage p = proposals [_ id]; require (now > = p.deadline & &! p.executed); if (p.typeFlag = = 1 & & p.currentResult > 0) {assert (deleteSubmission (p.target));} uint256 len = p.votes.sessions; for (uint I = 0; I
< len; i++) { token.decreaseLockedAmount(p.votes[i].voter, p.votes[i].power); } p.executed = true; emit ProposalExecuted(_id);} 我们通过其ID获取提案,检查它是否符合未执行的要求和截止日期过期,然后如果提案的类型是删除提案且投票结果是肯定的,我们使用已经写入的删除功能,最后发出了我们添加的新事件(将其添加到合约的顶部)。assert调用与require语句具有相同的用途:断言通常在"断言"结果为真时使用。要求用于先决条件。在功能上它们是相同的,assert语句的差异在它们失败时无法接受消息参数。该功能通过为该一个提案中的所有投票解锁代币而结束。 我们可以使用相同的方法添加其他类型的提案,但首先,让我们更新deleteSubmission函数以禁止在其帐户上有五个或更多删除的用户:这意味着他们一直在提交社区投票反对的内容。让我们更新deleteSubmission函数: function deleteSubmission(bytes32 hash) internal returns (bool) { require(submissionExists(hash), "Submission must exist to be deletable."); Submission storage sub = submissions[hash]; sub.exists = false; deletions[submissions[hash].submitter] += 1; if (deletions[submissions[hash].submitter] >= 5) {blacklistAddress (submissions[ hash] .submitter);} emit SubmissionDeleted (sub.index, sub.content, sub.image, sub.submitter); nonDeletedSubmissions-= 1; return true;}
That's even better. Five are automatically deleted and blacklisted. However, it is unfair not to provide redemption opportunities for blacklisted addresses. We also need to define the blacklist function itself. Let's do these two things and set the unreasonable fee to, for example, 0.05 ether.
Function blacklistAddress (address _ offender) internal {require (blacklist [_ offender] = = false, "Can't blacklist a blacklisted user: /"); blacklist [_ offender] = = true; token.increaseLockedAmount (_ offender, token.getUnlockedAmount (_ offender)); emit Blacklisted (_ offender, true);} function unblacklistMe () payable public {unblacklistAddress (msg.sender);} function unblacklistAddress (address _ offender) payable public {require (msg.value > = 0.05ether, "Unblacklisting fee") Require (blacklist [_ offender] = = true, "Can't unblacklist a non-blacklisted user: /"); require (notVoting (_ offender), "Offender must not be involved in a vote."); withdrawableByOwner = withdrawableByOwner.add (msg.value); blacklist [_ offender] = false; token.decreaseLockedAmount (_ offender, token.balanceOf (_ offender)); emit Blacklisted (_ offender, false);} function notVoting (address _ voter) internal view returns (bool) {for (uint256 I = 0; I)
< proposalCount; i++) { if (proposals[i].executed == false && proposals[i].voters[_voter] == true) { return false; } } return true;} 请注意,列入黑名单的帐户的令牌会被锁定,直到他们发送不合格的费用为止。 其他类型的投票 使用我们上面写的函数的灵感,尝试编写其他提议。对于剧透,请查看项目的GitHub仓库并从那里复制最终代码。为简洁起见,让我们继续讨论DAO中剩下的其他功能。 章节的结束 一旦达到故事的时间或章节限制,就应该结束故事了。任何人都可以在允许提取股息的日期之后调用结束函数。首先,我们需要一个新的StoryDAO属性和一个事件: bool public active = true;event StoryEnded(); 然后,让我们构建函数: function endStory() storyActive external { withdrawToOwner(); active = false; emit StoryEnded();} 简单:它将收集的费用发送给所有者并发出事件后停用故事。但实际上,这并没有真正改变整个DAO中的任何内容:其他功能对它的结束没有反应。那么让我们构建另一个修饰符: modifier storyActive() { require(active == true); _;} 然后,我们将此修饰符添加到除withdrawToOwner之外的所有函数中,如下所示: function whitelistAddress(address _add) storyActive public payable { 如果DAO中遗留了任何代币,让我们将它们取回并接管这些代币的所有权,以便以后能够在另一个故事中使用它们: function withdrawLeftoverTokens() external onlyOwner { require(active == false); token.transfer(msg.sender, token.balanceOf(address(this))); token.transferOwnership(msg.sender);}function unlockMyTokens() external { require(active == false); require(token.getLockedAmount(msg.sender) >0); token.decreaseLockedAmount (msg.sender, token.getLockedAmount (msg.sender));}
The unlockMyTokens function is used to unlock all locked tokens in case some locked tokens are locked by a specific user. It should not happen, and this feature should be removed through a large number of tests.
Dividend distribution and withdrawals
Now that the story is over, the fees collected need to be allocated to all token holders. We can re-use our whitelist to mark all those who cancel the fee:
Function withdrawDividend () memberOnly external {require (active = = false); uint256 owed = address (this) .balance.div (whitelistedNumber); msg.sender.transfer (owed); whitelist [msg.sender] = false; whitelistedNumber--;}
If these dividends are not withdrawn within a certain period of time, the owner may seize the remaining dividends:
Function withdrawEverythingPostDeadline () external onlyOwner {require (active = = false); require (now > deadline + 14 days); owner.transfer (address (this) .balance);}
Leave a homework assignment and consider how easy or difficult it is to reuse the same deployed smart contract, clear its data, and keep the token in the bottom pool and restart another chapter without having to redeploy. Try to do this yourself and keep a close eye on buybacks so that you can update this series of tutorials in the future! Additional incentives should also be considered: perhaps the number of tokens in the account will affect their dividend from the end of the story? Your imagination is the limit!
Deployment issu
Given that our contract is now very large, deploying and / or testing it may exceed the gas limit in the Ethernet Fong block. This is the reason that restricts the deployment of large applications on the Ethernet Fong network. To deploy it anyway, try using the code optimizer during compilation by changing the truffle.js file to include the solc settings for optimization, as follows:
/ /... module.exports = {solc: {optimizer: {enabled: true, runs: 200}}, networks: {development: {/ /.
This will run the optimizer 200 times in the code to find areas that can be scaled down removed or abstracted before deployment which will significantly reduce deployment costs.
At this point, the study on "how to use custom tokens to vote in the construction of DApps in Ethernet Square" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.