728x90
트러플을 활용해서 투표 기능이 있는 간단한 dApp 코드를 간단하게 작성하고 jest로 테스트 해보겠다.
목차
- sol코드
- jest코드
mkdir truffle
cd truffle
truffle init
터미널 새로열고
npx ganache-cli
trffle-config.js
development 부분 주석해제
truffle/contracts/Voting.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
contract Voting {
string[] public candidateList; //배열 정의
mapping(string=>uint8) public votesReceived; // 키값에 string을 넣으면 uint8으로 value값이 나오는 배열 voteReceived 정의
constructor(string[] memory candidatenames){ // 후보 이름 담긴 배열을 넣어주면
candidateList = candidatenames; //candidateList라는 배열에 저장된다.
}
}
Voting이라는 contracts 를 정의해준다.
아래에선,
사용할 함수를 정의해주겠다.
1. 투표를 할 함수
변수명에 사용자 이름을 넣어주면 votesReived라는 배열에 투표 받은 수만큼 count가 올라감
function voteForcandidate(string memory candidate) public{
// 조건 require()
require(vaildCandidate(candidate), "Error !");
votesReceived[candidate] += 1;
}
2. 총 투표를 받은 수를 출력하는 함수
인자 값으로 후보 이름을 넣어주면 된다.
function totalVotesFor(string memory candidate) public view returns(uint8){
require(vaildCandidate(candidate), "Error !"); //검증되지 않은 후보자면 error를 띄운다.
return votesReceived[candidate]; // 받은 표수 return
}
3. 후보자가 유효한지 검증해주는 함수
function vaildCandidate(string memory candidate) private view returns(bool){
// 1.후보자 리스트 candidateList
// 2. 내가 입력한 후보자군과 candidateList 안에 후보자가 일치하는 게 있니?
// String 비교가 안됩니다.
// keccak256 16진수 -> 32바이트
// password
// keccak256(abi.encodePacked((candidateList[i])));)
for(uint i=0; i< candidateList.length; i++){
if(keccak256(abi.encodePacked(candidateList[i])) == keccak256(abi.encodePacked(candidate))){
return true;
}
}
return false;
}
keccak256 그냥 sha-256이랑 비슷하다고 생각하자!
전체 코드
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
contract Voting {
string[] public candidateList;
mapping(string=>uint8) public votesReceived;
constructor(string[] memory candidatenames){
candidateList = candidatenames;
}
function voteForcandidate(string memory candidate) public{
// 조건 require()
require(vaildCandidate(candidate), "Error !");
votesReceived[candidate] += 1;
}
function totalVotesFor(string memory candidate) public view returns(uint8){
require(vaildCandidate(candidate), "Error !");
return votesReceived[candidate];
}
function vaildCandidate(string memory candidate) private view returns(bool){
// 1.후보자 리스트 candidateList
// 2. 내가 입력한 후보자군과 candidateList 안에 후보자가 일치하는 게 있니?
// String 비교가 안됩니다.
// keccak256 16진수 -> 32바이트
// password
// keccak256(abi.encodePacked((candidateList[i])));)
for(uint i=0; i< candidateList.length; i++){
if(keccak256(abi.encodePacked(candidateList[i])) == keccak256(abi.encodePacked(candidate))){
return true;
}
}
return false;
}
}
테스트 코드를 작성해보겠다.
truffle/test/Voting.test.js
const Voting = artifacts.require('Voting'); // 파일이름
describe.only('Voting', () => {
let deployed, data;
it('deployed', async () => {
deployed = await Voting.deployed();
console.log(deployed); // 배포 내역 확인
});
it('candidateList', async () => {
const arr = [
deployed.candidateList.call(0),
deployed.candidateList.call(1),
deployed.candidateList.call(2),
deployed.candidateList.call(3),
];
data = await Promise.all(arr); // Promise객체 안에 한 번에 때려넣고 한 번에 돌림.
console.log(data);
});
it('voteForCandidate', async () => {
await deployed.voteForcandidate(data[0]); // 0번에게 투표
await deployed.voteForcandidate(data[2]); // 2번에게 투표
await deployed.voteForcandidate(data[1]); // 1번에게 투표
await deployed.voteForcandidate(data[3]); // 3번에게 투표
for (const candidate of data) {
let count = await deployed.totalVotesFor.call(candidate);
console.log(`${candidate} : ${count}`);
}
});
});
그 전에 migration 파일을 작성해주어야한다.
truffle/migrations/3_deploy.Voting.js
const Voting = artifacts.require('Voting');
module.exports = function (deployer) {
deployer.deploy(Voting, ['사과', '딸기', '포도', '배']);
};
cadidateList를 넣어주어야한다.
truffle test
truffle test같은 경우 자동으로 compile이 진행되기 때문에
migration을 안해줘도 된다.
테스트 결과
사과, 딸기, 포도, 배가 각자 1표씩 받았다!
주의 사항: forEach문은 비동기를 기다려주지 않으니, async함수를 forEach문 안에 넣으면 안된다.
for in이나 for of를 사용 할 것.
728x90
'블록체인 > 스마트 컨트랙트' 카테고리의 다른 글
[스마트 컨트랙트, open-zeppelin] 토큰 <-> 이더리움 스왑 구현해보기 (0) | 2022.07.22 |
---|---|
[스마트 컨트랙트] 물건 사고, 환불하는 dApp 간단히 구현 (0) | 2022.07.20 |
[truffle, 스마트 컨트랙트] 토큰 생성해보기 (0) | 2022.07.15 |
[ truffle, 스마트 컨트랙트 ] 솔리디티 event 사용해서 dApp 간단하게 구현해보기 (0) | 2022.07.14 |
[truffle, 스마트 컨트랙트] d App 간단하게 만들어보기 (0) | 2022.07.13 |