Reputation: 63
I'm making an Ethereum-based voting app app app dapp. It is using truffle and uses virtual accounts through meta-mask. I don't know what to do if I want to put the record in the database when I vote. I want to use mysql for the database.
OS: ubuntu 18.07
truffle : 5.0
nvm : 0.33.1
nodejs:12.14.1
npm : 6.13.4
contracts/ election.sol :
*pragma solidity ^0.5.0; contract Election {
// 후보자 모델
struct Candidate {
uint id;
string name;
uint votefirst; //1순위투표수
uint voteSeond; //2순위투표수
uint votethird; //3순위투표수
uint voteCount; //전체 유권자들이 투표한 총 투표수
}
// 후보자 기호 변수
uint public candidatesCount; //후보자수
uint public voteCount; //총 투표수
string public votename;
uint public voterCount; //투표자수
uint public test = 0;
// 후보자 반환하기
mapping(uint => Candidate) public candidates;
// 투표에 참여한 ID 기록
mapping(address => bool) public voters;
// 후보자 등록하기
function addCandidate (string memory _name) public {
candidatesCount++;
candidates[candidatesCount] = Candidate(candidatesCount, _name, 0 , 0, 0, 0);
}
// constructor
constructor() public {
addCandidate('A');
addCandidate('B');
addCandidate('C');
//voterCount++;
}
// 투표하기
function vote(uint _candidateId) public {
// 중복투표를 하면 오류를 발생 시킨다.
//require(!voters[msg.sender]);
// 목록에 없는 후보자에게 투표하면 오류를 발생시킨다.
require(_candidateId > 0 && _candidateId <= candidatesCount);
// 투표에 참여한 ID를 기록해서 두번 투표하지 못하도록 한다.
voters[msg.sender] = true;
// 득표수를 +1 한다.
candidates[_candidateId].votefirst = candidates[_candidateId].votefirst+1;
candidates[_candidateId].votefirst = candidates[_candidateId].votefirst+test;
candidates[_candidateId].voteCount = candidates[_candidateId].voteCount+3;
}
function vote1(uint _candidateId) public {
// 중복투표를 하면 오류를 발생 시킨다.
//require(!voters[msg.sender]);
// 목록에 없는 후보자에게 투표하면 오류를 발생시킨다.
require(_candidateId > 0 && _candidateId <= candidatesCount);
// 투표에 참여한 ID를 기록해서 두번 투표하지 못하도록 한다.
voters[msg.sender] = true;
// 득표수를 +1 한다.
candidates[_candidateId].voteSeond = candidates[_candidateId].voteSeond +1 ;
candidates[_candidateId].voteCount = candidates[_candidateId].voteCount+3;
//votelist[voterCount].vote_s=candidates[_candidateId].voteSeond;
}
function vote2(uint _candidateId) public {
// 중복투표를 하면 오류를 발생 시킨다.
//require(!voters[msg.sender]);
// 목록에 없는 후보자에게 투표하면 오류를 발생시킨다.
require(_candidateId > 0 && _candidateId <= candidatesCount);
// 투표에 참여한 ID를 기록해서 두번 투표하지 못하도록 한다.
voters[msg.sender] = true;
// 득표수를 +1 한다.
candidates[_candidateId].votethird = candidates[_candidateId].votethird +1 ;
candidates[_candidateId].voteCount = candidates[_candidateId].voteCount+3;
//votelist[voterCount].vote_t=candidates[_candidateId].votethird;
}
}*
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();
});
var voter =0;
var vote_winner;
var account_mine;
var vote_num;
// 화면구현
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 voteCount1 = candidate[2];
var voteCount2 = candidate[3];
var voteCount3 = candidate[4];
var voteCountall = candidate[5];
var name1 = candidate[6] + account_mine;
var voteAccount = account_mine;
var voteSum= (parseInt(voteCount1) + (parseInt(voteCount2)*2) + (parseInt(voteCount3)*3));
voter = voteCountall;
// 투표결과 html 파싱
var candidateTemplate = '<tr><th>' + id + '</th><td>' + name + '</td><td>' + voteCount1 + '</td><td>' + voteCount2 + '</td><td>' + voteCount3 + '</td></tr>'
$('#candidatesResults').append(candidateTemplate);
if( (voter / 3) / 2 < voteCount1)
{
vote_winner = name;
var candidateTemplate1 = '<tr><th>' + id + '</th><td>' + name + '</td></tr>'
$('#candidatesResults1').append(candidateTemplate1);
}
var candidateOption_first = '<option value="' + id + '">' + name + '</option>'
$('#candidateSelect1').append(candidateOption_first);
var candidateOption_second = '<option value="' + id + '">' + name + '</option>'
$('#candidateSelect2').append(candidateOption_second);
var candidateOption_third = '<option value="' + id + '">' + name + '</option>'
$('#candidateSelect3').append(candidateOption_third);
});
}
// 후보자 화면 표시
$('#loader').hide();
$('#content').show();
}).catch(function (error) {
console.warn(error);
});
}
$('#btnVote').on('click', function() {
var candidateId_first = $('#candidateSelect1').val()
var candidateId_second = $('#candidateSelect2').val()
var candidateId_third = $('#candidateSelect3').val()
vote_1 = candidateId_first;
vote_2 = candidateId_second;
vote_3 = candidateId_third;
if ((!candidateId_first) || ( !candidateId_second ) || ( !candidateId_third) ) {
return alert('모든 후보자의 순위를 선택해주세요.')
}
if ((candidateId_first == candidateId_second) || (candidateId_second == candidateId_third) || (candidateId_third == candidateId_first)){
return alert('순위별 후보자가 중복되었습니다.')
}
App.contracts.Election.deployed()
.then(function(instance) {
return instance.vote(candidateId_first, {from: App.account}),
instance.vote1(candidateId_second, {from: App.account}),
instance.vote2(candidateId_third, {from: App.account})
})
.then(function(result) {
if (result.receipt) {
vote_num++;
var j= parseInt(voter);
voter =j+3;
alert('성공적으로 투표했습니다.')
location.reload();
}
})
.catch(function(error) {
alert(error.message)
alert('투표하실 수 없습니다.')
})
});
});
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 class="table" style="width: 50%">
<colgroup>
<col width="200">
<col width="*">
<col width="100">
</colgroup>
<thead>
<tr>
<th scope="col">기호</th>
<th scope="col">이름</th>
<th scope="col">1순위 득표수</th>
<th scope="col">2순위 득표수</th>
<th scope="col">3순위 득표수</th>
</tr>
</thead>
<tbody id="candidatesResults">
</tbody>
</table>
<table>
<thead>
<tr>
<!-- <th >득표수</th> -->
</tr>
</thead>
<tbody id="voteCount">
</tbody>
</table>
<h2>투표 참여</h2>
<table class="table" style="width: 100%">
<colgroup>
<col width="60">
<col width="*">
<col width="100">
</colgroup>
<thead>
<tr>
<th scope="col">순위</th>
<th scope="col">이름</th>
</tr>
</thead>
<thead>
<tr>
<th scope="col">1</th>
<th scope="col">
<select id="candidateSelect1">
<option value="">후보자를 선택하세요.</option>
</select>
</th>
</tr>
</thead>
<thead>
<tr>
<th scope="col">2</th>
<th scope="col">
<select id="candidateSelect2">
<option value="">후보자를 선택하세요.</option>
</select>
</th>
</tr>
</thead>
<thead>
<tr>
<th scope="col">3</th>
<th scope="col">
<select id="candidateSelect3">
<option value="">후보자를 선택하세요.</option>
</select>
</tr>
</thead>
</table>
<button id="btnVote">투표하기</button>
<table>
<thead>
<colgroup>
<col width="200">
<col width="*">
<col width="100">
</colgroup>
<tr>
<th scope="col">투표자 기록</th>
<th scope="col"> 이름</th>
</tr>
</thead>
<tbody id="candidatesResults1">
<p id="accountAddress"></p>
</tbody>
</table>
</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>
please let me know how to solve this problem..
Upvotes: 4
Views: 1114
Reputation: 83788
By the definition, dApps do not connect databases, but they connect to a blockchain. So your question makes little sense.
The best way to get data from a blockchain to a database is to have a server-side process that connects to Ethereum node, listens for Solidity events and then copies and writes those events to your internal SQL database.
Upvotes: 1