로메오의 블로그

[DApp] Solidity Front-end Election에서 후보자 읽어오기 본문

Backend/Python & Blockchain

[DApp] Solidity Front-end Election에서 후보자 읽어오기

romeoh 2019. 7. 7. 03:44
반응형

CANDIDATE 등록, 확인하기

 

Solidate로 작성한 Back-end 코드는 위 포스트를 그대로 사용합니다.

 

다만 constructor에 후보자를 미리 3명 정도 등록하는 코드를 추가하겠습니다.

 

/contracts/Election.sol

pragma solidity ^0.5.0;

contract Election {
    
    // 후보자 모델
    struct Candidate {
        uint id;
        string name;
        uint voteCount;
    }

    // 후보자 기호 변수
    uint public candidatesCount;

    // 후보자 매핑
    mapping(uint => Candidate) public candidates;

    // 후보자 등록하기
    function addCandidate (string memory _name) public {
        candidatesCount++;
        candidates[candidatesCount] = Candidate(candidatesCount, _name, 0);
    }

    // constructor
    constructor() public {
        // 후보자를 미리 3명 등록합니다.
        addCandidate('romeoh');
        addCandidate('doraemong');
        addCandidate('pororo');
    }
}

 

Front-end 코드 구현하기

샘플 화면으로 제공되는 src 폴더에서 필요치 않은 폴더나 파일은 제거했습니다.

삭제한 폴더 & 파일
/src/css
/src/images
/src/fonts
/src/pet.json
/box-img-lg.png
/box-img-sm.png

/src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>투표 결과</title>
</head>

<body>
    <h1>투표 결과</h1>

    <!-- 로딩바 -->
    <div id="loader">
        <p>로딩중...</p>
    </div>

    <!-- 투표결과 표시 -->
    <div id="content" style="display: none;">
        <table style="width: 100%">
            <colgroup>
                <col width="60">
                <col width="*">
                <col width="100">
            </colgroup>
            <thead>
                <tr>
                    <th scope="col">기호</th>
                    <th scope="col">이름</th>
                    <th scope="col">득표수</th>
                </tr>
            </thead>
            <tbody id="candidatesResults">
            </tbody>
        </table>
        <hr>

        <!-- 계정 정보 표시 -->
        <p id="accountAddress"></p>
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="js/web3.min.js"></script>
    <script src="js/truffle-contract.js"></script>
    <script src="js/app.js"></script>
</body>
</html>

/src/js/app.js

var App = {
    web3Provider: null,
    contracts: {}
}

$(window).load(function () {

    // web3Provider 생성하기
    if (typeof web3 !== 'undefined') {
        // MetaMask가 설치되어 있어서 web3 인스턴스가 이미 생성되어 있음
        App.web3Provider = web3.currentProvider;
        web3 = new Web3(web3.currentProvider);
    } else {
        // MetaMask가 설치되지 않았을 경우 기본 인스턴스를 지정함
        App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
        web3 = new Web3(App.web3Provider);
    }

    // Election.json을 가지고 온다.
    $.getJSON("Election.json", function (election) {
        // Truffle 계약을 초기화 함
        App.contracts.Election = TruffleContract(election);
        // 인스턴스에 접속함
        App.contracts.Election.setProvider(App.web3Provider);

        render();
    });

    // 화면구현
    function render() {

        // 계정 정보 읽어오기
        web3.eth.getCoinbase(function (err, account) {
            if (err === null) {
                App.account = account;
                $("#accountAddress").html("나의 계정: " + account);
            }
        });

        // 계약 정보를 읽어온다.
        App.contracts.Election.deployed().then(function (instance) {
            electionInstance = instance;
            return electionInstance.candidatesCount();
        }).then(function (candidatesCount) {
            for (var i = 1; i <= candidatesCount; i++) {
                electionInstance.candidates(i).then(function (candidate) {
                    var id = candidate[0];
                    var name = candidate[1];
                    var voteCount = candidate[2];

                    // 투표결과 html 파싱
                    var candidateTemplate = "<tr><th>" + id + "</th><td>" + name + "</td><td>" + voteCount + "</td></tr>"
                    $("#candidatesResults").append(candidateTemplate);
                });
            }

            // 후보자 화면 표시
            $("#loader").hide();
            $("#content").show();
        }).catch(function (error) {
            console.warn(error);
        });
    }
});

빌드하기

$ truffle migrate --reset

truffle로 migrate 하면 /build/constracts/Election.json 파일이 생성됩니다.

이 폴더에 json 파일이 생성되는것은 /bs-config.json에서 baseDir을 static으로 설정되어 있기 때문입니다.

npm으로 lite server 구동하기

터미널을 새로 열어서 npm을 구동합니다.

$ npm run dev

dev 스크립트는 package.json 파일에서 확인 할 수 있습니다.

 

크롬에서 확인

아직 아무것도 표시되지 않습니다.

 

MetaMask를 열어서 서버를 선택합니다.

사용자 정의 RPC를 선택합니다.

먼저 Ganache에서 RPC Server의 주소와 포트를 확인하세요.

Network Name과 New RPC URL을 위와 같이 입력하고 저장 버튼을 누릅니다.

 

저장을 누르는 즉시 Candidate 서버가 선택되면서 화면이 표시됩니다.

 

그런데 나의 계정정보가 Ganache의 계정이 아니고 MetaMask 기본 계정으로 들어가 있습니다.

변경해 보겠습니다.

 

Ganache의 index 2번 주소를 사용하기 위해 우측 연쇄 아이콘을 누릅니다.

Private key를 드래그 해서 복사합니다.

MetaMask에서 계정 가져오기를 누릅니다.

형식은 개인키

복사한 개인키를 붙여넣기하고 가져오기를 누릅니다.

 

계정이 변경되었습니다.

 

화면을 새로고침하면 변경된 계정이 적용됩니다.

Ganache의 index 2번 주소와 같습니다.

 

반응형
Comments