블록체인 학습
0 XP

Chapter 9 마무리 테스트: 투표 등록부

이번 차시에서 배운 mapping 과 struct, 그리고 바로 앞 실습에서 형태를 익힌 이벤트를 모두 활용해 간단한 투표 등록부를 완성하세요. mapping(uint256 => struct) 로 후보를 관리하고, mapping(address => bool) 로 중복 투표를 막는, 실전에 가까운 종합 과제입니다.

투표 시스템에는 서로 다른 두 mapping 이 필요합니다. 하나는 후보 정보를 묶어 담는 mapping(uint256 => Candidate)(후보 ID → struct), 다른 하나는 누가 이미 투표했는지를 기록하는 mapping(address => bool) 입니다. 뒤쪽 mapping 이 중복 투표 방지라는 접근 제어 역할을 합니다.

핵심 문법 복습

  • 후보 등록: candidates[id] = Candidate(name, 0);
  • 득표 증가: candidates[candidateId].voteCount += 1;
  • 중복 방지: require(!hasVoted[msg.sender], "...");
  • 이벤트 발생: emit Voted(msg.sender, candidateId);

요구 조건:

  1. VotingRegistry 컨트랙트를 선언하세요.
  2. name(string)과 voteCount(uint256) 필드를 가진 Candidate struct 를 선언하세요.
  3. 후보 ID(uint256) → Candidate 를 연결하는 public mapping candidates 를 선언하세요.
  4. 주소 → 투표 여부(bool)를 연결하는 public mapping hasVoted 를 선언하세요.
  5. Voted(address voter, uint256 candidateId) 이벤트를 선언하세요.
  6. addCandidate(uint256 id, string memory name) 함수: 해당 ID 에 후보를 등록합니다(voteCount 는 0).
  7. vote(uint256 candidateId) 함수: 아직 투표하지 않은 사람만 투표할 수 있게 하고, 후보의 voteCount 를 1 늘린 뒤 hasVoted 를 true 로 설정하고 Voted 이벤트를 발생시키세요.
  8. getVotes(uint256 candidateId) 함수: 해당 후보의 득표 수를 반환하세요. (view, returns (uint256))

중복 투표를 막으려면 require(!hasVoted[msg.sender], "already voted"); 로 먼저 확인하세요.

상태를 바꾸는 함수(vote)에서는 "확인 → 상태 변경 → 이벤트 발생" 순서를 지키면 흐름이 명확해집니다. mapping 은 순회가 불가능하므로 후보 목록을 따로 돌 필요 없이 ID 로 직접 접근하세요.

Code Editor
에디터를 불러오는 중...
실행 결과

Run 버튼을 눌러 코드를 실행하세요.