Skip to content

Commit

Permalink
Merge pull request #12 from wooqii/wooqii-Voting-translate
Browse files Browse the repository at this point in the history
Solidity by Example Voting sector translation (#11)
  • Loading branch information
dongsam committed Mar 26, 2018
2 parents 31d8900 + daa29da commit f6e64a2
Showing 1 changed file with 73 additions and 85 deletions.
158 changes: 73 additions & 85 deletions solidity-by-example.rst
Original file line number Diff line number Diff line change
@@ -1,78 +1,69 @@
###################
Solidity by Example
예제λ₯Ό ν†΅ν•œ 솔리디티
###################

.. index:: voting, ballot
.. 색인:: voting, ballot
.. _voting:

******
Voting
νˆ¬ν‘œ μŠ€λ§ˆνŠΈκ³„μ•½
******

The following contract is quite complex, but showcases
a lot of Solidity's features. It implements a voting
contract. Of course, the main problems of electronic
voting is how to assign voting rights to the correct
persons and how to prevent manipulation. We will not
solve all problems here, but at least we will show
how delegated voting can be done so that vote counting
is **automatic and completely transparent** at the
same time.

The idea is to create one contract per ballot,
providing a short name for each option.
Then the creator of the contract who serves as
chairperson will give the right to vote to each
address individually.

The persons behind the addresses can then choose
to either vote themselves or to delegate their
vote to a person they trust.

At the end of the voting time, ``winningProposal()``
will return the proposal with the largest number
of votes.
λ‹€μŒ 계약은 ν™•μ‹€νžˆ λ³΅μž‘ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λ‹€μŒ μ˜ˆμ‹œλ“€μ€ μ†”λ¦¬λ””ν‹°μ˜
λ‹€μ–‘ν•œ νŠΉμ§•μ„ ν¬ν•¨ν•©λ‹ˆλ‹€. 이 μ˜ˆμ‹œλŠ” νˆ¬ν‘œκ³„μ•½μ„ κ΅¬ν˜„ν•©λ‹ˆλ‹€.
λ¬Όλ‘ , μ „μž νˆ¬ν‘œκ°€ λ‹Ήλ©΄ν•œ 핡심 λ¬Έμ œλŠ” μ˜¬λ°”λ₯Έ μ‚¬λžŒμ—κ²Œ νˆ¬ν‘œκΆŒμ„
λΆ€μ—¬ν•˜λŠ” 방법과 μ‘°μž‘μ„ λ°©μ§€ν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€. μš°λ¦¬λŠ” 이 μ˜ˆμ‹œμ—μ„œ
λͺ¨λ“  문제λ₯Ό ν•΄κ²°ν•˜μ§€λŠ” μ•Šμ§€λ§Œ, μ΅œμ†Œν•œ μœ„μž„νˆ¬ν‘œκ°€ μ–΄λ–»κ²Œ
λ™μ‹œμ— **μžλ™μ μ΄λ©° μ™„μ „ 투λͺ…ν•˜κ²Œ** μ΄λ£¨μ–΄μ§€λŠ”μ§€ 보여쀄 κ²ƒμž…λ‹ˆλ‹€.


이 μ•„μ΄λ””μ–΄λŠ” λ°œμ˜μ•ˆ λ‹Ή ν•˜λ‚˜μ˜ 계약을 μž‘μ„±ν•˜μ—¬ 각 μ˜΅μ…˜λ§ˆλ‹€
짧은 이름을 λΆ™μž…λ‹ˆλ‹€. μŠ€λ§ˆνŠΈκ³„μ•½μ—μ„œ 의μž₯ 역할을 μˆ˜ν–‰ν•˜λŠ” 계약 μž‘μ„±μžλŠ” 각 μ£Όμ†Œμ— κ°œλ³„μ μΈ νˆ¬ν‘œκΆŒν•œμ„ λΆ€μ—¬ν•  κ²ƒμž…λ‹ˆλ‹€.
그러면 의μž₯으둜 λ΄‰μ‚¬ν•˜λŠ” 계약 μž‘μ„±μžλŠ” 각 μ£Όμ†Œμ— κ°œλ³„μ μœΌλ‘œ νˆ¬ν‘œκΆŒμ„ λΆ€μ—¬ν•©λ‹ˆλ‹€.

μ£Όμ†Œκ°€ μžˆλŠ” μ‚¬λžŒλ“€μ€ μžμ‹ μ„ νˆ¬ν‘œν•˜κ±°λ‚˜ κΈ΄λ’°ν•  수 μžˆλŠ” μ‚¬λžŒμ—κ²Œ νˆ¬ν‘œλ₯Ό μœ„μž„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

νˆ¬ν‘œμ‹œκ°„μ΄ λλ‚˜λ©΄, ``winningProposal()`` 이 κ°€μž₯ 큰 숫자의 κ²°κ³Όλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

::

pragma solidity ^0.4.16;

/// @title Voting with delegation.
/// @title λŒ€ν‘œλ‹¨κ³Ό νˆ¬ν‘œ.
contract Ballot {
// This declares a new complex type which will
// be used for variables later.
// It will represent a single voter.
// 이것은 λ‚˜μ€‘μ— λ³€μˆ˜μ— μ‚¬μš©λ  μƒˆλ‘œμš΄
// 볡합 μœ ν˜•μ„ μ„ μ–Έν•©λ‹ˆλ‹€.
// 그것은 단일 유ꢌ자λ₯Ό λŒ€ν‘œν•  κ²ƒμž…λ‹ˆλ‹€.
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
uint weight; // weight λŠ” λŒ€ν‘œλ‹¨μ— μ˜ν•΄ λˆ„μ λ©λ‹ˆλ‹€.
bool voted; // λ§Œμ•½ 이 값이 true라면, κ·Έ μ‚¬λžŒμ€ 이미 νˆ¬ν‘œν•œ 것 μž…λ‹ˆλ‹€.
address delegate; // νˆ¬ν‘œμ— μœ„μž„λœ μ‚¬λžŒ
uint vote; // νˆ¬ν‘œλœ μ œμ•ˆμ˜ 인덱슀 데이터 κ°’
}

// This is a type for a single proposal.
// 이것은 단일 μ œμ•ˆμ— λŒ€ν•œ μœ ν˜•μž…λ‹ˆλ‹€.
struct Proposal {
bytes32 name; // short name (up to 32 bytes)
uint voteCount; // number of accumulated votes
bytes32 name; // κ°„λ‹¨ν•œ λͺ…μΉ­ (μ΅œλŒ€ 32λ°”μ΄νŠΈ)
uint voteCount; // λˆ„μ  νˆ¬ν‘œ 수
}

address public chairperson;

// This declares a state variable that
// stores a `Voter` struct for each possible address.
// 이것은 각각의 κ°€λŠ₯ν•œ μ£Όμ†Œμ— λŒ€ν•΄
// `Voter` ꡬ쑰체λ₯Ό μ €μž₯ν•˜λŠ” μƒνƒœλ³€μˆ˜λ₯Ό μ„ μ–Έν•©λ‹ˆλ‹€.
mapping(address => Voter) public voters;

// A dynamically-sized array of `Proposal` structs.
// λ™μ μœΌλ‘œ 크기가 μ§€μ •λœ `Proposal` ꡬ쑰체의 λ°°μ—΄μž…λ‹ˆλ‹€.
Proposal[] public proposals;

/// Create a new ballot to choose one of `proposalNames`.
/// `proposalNames` 쀑 ν•˜λ‚˜λ₯Ό μ„ νƒν•˜κΈ° μœ„ν•œ μƒˆλ‘œμš΄ νˆ¬ν‘œκΆŒμ„ μƒμ„±μ‹­μ‹œμ˜€.
function Ballot(bytes32[] proposalNames) public {
chairperson = msg.sender;
voters[chairperson].weight = 1;

// For each of the provided proposal names,
// create a new proposal object and add it
// to the end of the array.
// 각각의 제곡된 μ œμ•ˆμ„œ 이름에 λŒ€ν•΄,
// μƒˆλ‘œμš΄ μ œμ•ˆμ„œ 개체λ₯Ό λ§Œλ“€μ–΄ λ°°μ—΄ 끝에 μΆ”κ°€ν•©λ‹ˆλ‹€.
for (uint i = 0; i < proposalNames.length; i++) {
// `Proposal({...})` creates a temporary
// Proposal object and `proposals.push(...)`
Expand All @@ -84,16 +75,16 @@ of votes.
}
}

// Give `voter` the right to vote on this ballot.
// May only be called by `chairperson`.
// `voter` μ—κ²Œ 이 νˆ¬ν‘œκΆŒμ— λŒ€ν•œ κΆŒν•œμ„ λΆ€μ—¬ν•˜μ‹­μ‹œμ˜€.
// 였직 `chairperson` μœΌλ‘œλΆ€ν„° ν˜ΈμΆœλ°›μ„ 수 μžˆμŠ΅λ‹ˆλ‹€.
function giveRightToVote(address voter) public {
// If the argument of `require` evaluates to `false`,
// it terminates and reverts all changes to
// the state and to Ether balances. It is often
// a good idea to use this if functions are
// called incorrectly. But watch out, this
// will currently also consume all provided gas
// (this is planned to change in the future).
// `require`의 μΈμˆ˜κ°€ `false`둜 ν‰κ°€λ˜λ©΄,
// 그것은 μ’…λ£Œλ˜κ³  λͺ¨λ“  λ³€κ²½λ‚΄μš©μ„ state와
// Ether Balance둜 λ˜λŒλ¦½λ‹ˆλ‹€.
// ν•¨μˆ˜κ°€ 잘λͺ» 호좜되면 이것을 μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.
// κ·ΈλŸ¬λ‚˜ μ‘°μ‹¬ν•˜μ‹­μ‹œμ˜€,
// 이것은 ν˜„μž¬ 제곡된 λͺ¨λ“  κ°€μŠ€λ₯Ό μ†ŒλΉ„ν•  κ²ƒμž…λ‹ˆλ‹€.
// (이것은 μ•žμœΌλ‘œ λ°”λ€Œκ²Œ 될 μ˜ˆμ •μž…λ‹ˆλ‹€)
require(
(msg.sender == chairperson) &&
!voters[voter].voted &&
Expand All @@ -102,62 +93,59 @@ of votes.
voters[voter].weight = 1;
}

/// Delegate your vote to the voter `to`.
/// `to` 둜 μœ κΆŒμžμ—κ²Œ νˆ¬ν‘œλ₯Ό μœ„μž„ν•˜μ‹­μ‹œμ˜€.
function delegate(address to) public {
// assigns reference
// μ°Έμ‘°λ₯Ό μ§€μ •ν•˜μ‹­μ‹œμ˜€.
Voter storage sender = voters[msg.sender];
require(!sender.voted);

// Self-delegation is not allowed.
// 자체 μœ„μž„μ€ ν—ˆμš©λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
require(to != msg.sender);

// Forward the delegation as long as
// `to` also delegated.
// In general, such loops are very dangerous,
// because if they run too long, they might
// need more gas than is available in a block.
// In this case, the delegation will not be executed,
// but in other situations, such loops might
// cause a contract to get "stuck" completely.
// `to`κ°€ μœ„μž„ν•˜λŠ” λ™μ•ˆ delegation을 μ „λ‹¬ν•˜μ‹­μ‹œμ˜€.
// 일반적으둜 이런 λ£¨ν”„λŠ” 맀우 μœ„ν—˜ν•˜κΈ° λ•Œλ¬Έμ—,
// λ„ˆλ¬΄ 였래 μ‹€ν–‰λ˜λ©΄ λΈ”λ‘μ—μ„œ μ‚¬μš©κ°€λŠ₯ν•œ κ°€μŠ€λ³΄λ‹€
// 더 λ§Žμ€ κ°€μŠ€κ°€ ν•„μš”ν•˜κ²Œ 될지도 λͺ¨λ¦…λ‹ˆλ‹€.
// 이 경우 μœ„μž„(delegation)은 μ‹€ν–‰λ˜μ§€ μ•Šμ§€λ§Œ,
// λ‹€λ₯Έ μƒν™©μ—μ„œλŠ” μ΄λŸ¬ν•œ λ£¨ν”„λ‘œ 인해
// 슀마트 κ³„μ•½μ„œκ°€ μ™„μ „νžˆ "κ³ μ°©"될 수 μžˆμŠ΅λ‹ˆλ‹€.
while (voters[to].delegate != address(0)) {
to = voters[to].delegate;

// We found a loop in the delegation, not allowed.
// μš°λ¦¬λŠ” delegation에 루프가 μžˆμŒμ„ 확인 ν–ˆκ³  ν—ˆμš©ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.
require(to != msg.sender);
}

// Since `sender` is a reference, this
// modifies `voters[msg.sender].voted`
// `sender` λŠ” μ°Έμ‘°μ΄λ―€λ‘œ,
// `voters[msg.sender].voted` λ₯Ό μˆ˜μ •ν•©λ‹ˆλ‹€.
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.
// λŒ€ν‘œκ°€ 아직 νˆ¬ν‘œν•˜μ§€ μ•Šμ•˜λ‹€λ©΄,
// weight에 μΆ”κ°€ν•˜μ‹­μ‹œμ˜€.
delegate_.weight += sender.weight;
}
}

/// Give your vote (including votes delegated to you)
/// to proposal `proposals[proposal].name`.
/// (λ‹Ήμ‹ μ—κ²Œ μœ„μž„λœ νˆ¬ν‘œκΆŒμ„ ν¬ν•¨ν•˜μ—¬)
/// `proposals[proposal].name` μ œμ•ˆμ„œμ— νˆ¬ν‘œ ν•˜μ‹­μ‹œμ˜€.
function vote(uint proposal) public {
Voter storage sender = voters[msg.sender];
require(!sender.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.
// λ§Œμ•½ `proposal` 이 λ°°μ—΄μ˜ λ²”μœ„λ₯Ό λ²—μ–΄λ‚˜λ©΄
// μžλ™μœΌλ‘œ throw ν•˜κ³  λͺ¨λ“  변경사항을 되돌릴 κ²ƒμž…λ‹ˆλ‹€.
proposals[proposal].voteCount += sender.weight;
}

/// @dev Computes the winning proposal taking all
/// previous votes into account.
/// @dev λͺ¨λ“  이전 λ“ν‘œλ₯Ό κ³ λ €ν•˜μ—¬ μŠΉλ¦¬ν•œ μ œμ•ˆμ„œλ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
function winningProposal() public view
returns (uint winningProposal_)
{
Expand All @@ -170,9 +158,9 @@ of votes.
}
}

// Calls winningProposal() function to get the index
// of the winner contained in the proposals array and then
// returns the name of the winner
// winningProposal() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬
// μ œμ•ˆ 배열에 ν¬ν•¨λœ 승자의 indexλ₯Ό κ°€μ Έμ˜¨ λ‹€μŒ
// 승자의 이름을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
function winnerName() public view
returns (bytes32 winnerName_)
{
Expand All @@ -181,13 +169,13 @@ of votes.
}


Possible Improvements
κ°œμ„ κ°€λŠ₯ ν•œ μ‚¬μ•ˆλ“€
=====================

Currently, many transactions are needed to assign the rights
to vote to all participants. Can you think of a better way?
ν˜„μž¬ λͺ¨λ“  μ°Έκ°€μžμ—κ²Œ νˆ¬ν‘œκΆŒμ„ λΆ€μ—¬ν•˜κΈ° μœ„ν•΄ λ§Žμ€ κ±°λž˜κ°€ ν•„μš” ν•©λ‹ˆλ‹€.
더 λ‚˜μ€ 방법을 생각해 λ³Ό 수 μžˆμŠ΅λ‹ˆκΉŒ?

.. index:: auction;blind, auction;open, blind auction, open auction
.. 색인:: auction;blind, auction;open, blind auction, open auction
*************
Blind Auction
Expand Down

0 comments on commit f6e64a2

Please sign in to comment.