diff --git a/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md b/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md deleted file mode 100644 index d7ce53237..000000000 --- a/resources/content/articles/en/2021-02-03_07-00-00_challenge-en.md +++ /dev/null @@ -1,180 +0,0 @@ ---- -parent: 2021-02-03_07-00-00_getting-started -title: Challenge -description: Translate a Solidity smart contract to Glow -order: 8 -last_updated: "2021-02-25T09:00:00+01:00" - ---- -# Challenge: Translate a Solidity smart contract to Glow - -In order to learn something new, we normally try to learn it refers to something we already know. -That's why in this article, we are going to learn the Glow smart contract language -by studying an example in Solidity and then translating it to Glow - - -## The Ballot example - -Ballot.sol is the first program that loads when looking going to the Remix IDE - - pragma solidity >=0.7.0 <0.8.0; - contract Ballot { - -Declare a struct called Voter that is a complex type -consisting of the weight of a vote, a Boolean voted, -the address of the Voter, and an index called vote. - - struct Voter { - uint weight;// Weight is accumulated by delegation - bool voted; // if true, that person already voted - address delegate;// person delegated to - uint vote; // index of the voted proposal - } - -You have an address type called chairperson. - - address chairperson; - -You have a mapping where you map and address with a voter - - mapping(address => Voter) voters; - -You also create an array of proposals where each proposal is a complex type struct. - - Proposal[] proposals; - - struct Proposal { - // If you can limit the length to a certain number of bytes, - // always use one of bytes1 to bytes32 because they are much cheaper - bytes32 name; // short name (up to 32 bytes) - uint voteCount;// number of accumulated votes - } - -In the constructor Ballot, you initialize the chairperson as the message sender with weight 1. -You also create a list of proposals. - - constructor(bytes32[] memory proposalNames) { - chairperson = msg.sender; - voters[chairperson].weight = 1; - - for (uint i = 0; i < proposalNames.length; i++) { - // 'Proposal({...})' creates a temporary - // Proposal object and 'proposals.push(...)' - // appends it to the end of 'proposals'. - proposals.push(Proposal({ - name: proposalNames[i], - voteCount: 0 - })); - } - } - -Give the `Voter` the right to vote on this ballot. -It can only be called by the `Chairperson`. -Validate that the voters have not voted yet and assign voters a weight. - - function giveRightToVote(address voter) public { - require( - msg.sender == chairperson, - "Only chairperson can give right to vote." - ); - require( - !voters[voter].voted, - "The voter already voted." - ); - require(voters[voter].weight == 0, - "the voter already had voting rights"); - voters[voter].weight = 1; - } - -Then the delegate() function delegates your vote to the Voter $(to) after a couple of validations -such as the message sender is not the to address has not voted. - - function delegate(address to) public { - Voter storage sender = voters[msg.sender]; - require(!sender.voted, "You already voted."); - require(to != msg.sender, "Self-delegation is disallowed."); - - while (voters[to].delegate != address(0)) { - to = voters[to].delegate; - - // We found a loop in the Delegation, not allowed. - require(to != msg.sender, "Found loop in delegation."); - } - sender.voted = true; - sender.delegate = to; - Voter storage delegate_ = voters[to]; - if (delegate_.voted) { - // If the delegate already voted, - // directly add to the number of votes - proposals[delegate_.vote].voteCount += sender.weight; - } else { - // If the delegate did not vote yet, - // add to her weight. - delegate_.weight += sender.weight; - } - } - -Give your vote (including votes delegated to you) to proposal - - function vote(uint proposal) public { - Voter storage sender = voters[msg.sender]; - require(sender.weight != 0, "Has no right to vote"); - require(!sender.voted, "Already voted."); - sender.voted = true; - sender.vote = proposal; - - // If 'proposal' is out of the range of the array, - // this will throw automatically and revert all - // changes. - proposals[proposal].voteCount += sender.weight; - } - -Find which is the proposal with the most votes. - - function winningProposal() public view - returns (uint winningProposal_) - { - uint winningVoteCount = 0; - for (uint p = 0; p < proposals.length; p++) { - if (proposals[p].voteCount > winningVoteCount) { - winningVoteCount = proposals[p].voteCount; - winningProposal_ = p; - } - } - } - -Get the name of the winning proposal - - function winnerName() public view - returns (bytes32 winnerName_) - { - winnerName_ = proposals[winningProposal()].name; - } - } - - -## Visualization - -By reading the previous contract, we can identify the following actors and flow: -The `Chairman` creates a contract with a defined number of options. -Then gives names to each option. -And grants voting rights to voters. -A voter (Bob in this diagram) can delegate his vote to another voter. -Voters vote for one of the options by its number. -Then everyone can ask who is winning by the one that has more votes. - -![img](https://ucarecdn.com/5dd5c388-7578-45a9-aea9-644d5ccf332c/ballot.png) - - -## How does the contract look in Glow? - -Now it is your turn. How does the previous smart contract look in Glow? - -Here are a few ideas on how you could get started with such a program: - -- One known proposal, one known voter -- Multiple known proposals, One known voter -- Multiple known proposals, Three known voters -- Multiple known proposals, Three known voters, with delegation -- Multiple known proposals, unknown voters, with delegation -- Multiple known proposals, unknown voters, with delegation, with giving voting rights