1.环境说明
- 系统:deepin20
- web3:0.20.1
- solc:0.4.22
- ganache-cli:6.12.2
- 失败过程:win10上面solc编译直接闪退,然后在centos上编译得到abi、合约地址拿到win10来用,投票的时候html不更新,但是ganche显示发送了交易;猜测是合约地址的问题,所以在deepin桌面上进行实验
2.智能合约
pragma solidity^0.4.22;
contract Voting {
mapping(bytes32 => uint8) public votesReceived;
bytes32[] public candidateList;
constructor (bytes32[] candidateNames) public {
candidateList = candidateNames;
}
function candidateVotes(bytes32 candidate) public view returns(uint8) {
require(_candidateValidation(candidate), "Invalid candidate.");
return votesReceived[candidate];
}
function VoteToCandidate(bytes32 candidate) public {
require(_candidateValidation(candidate), "Invalid candidate.");
votesReceived[candidate]++;
}
function _candidateValidation(bytes32 candidate) private view returns(bool) {
for(uint i = 0; i < candidateList.length; ++i) {
if(candidateList[i] == candidate)
return true;
}
return false;
}
}
3.html
<!DOCTYPE html>
<html>
<head>
<title>Hello World DApp</title>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
<link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet' type='text/css'>
</head>
<body class="container">
<h1>A Simple Hello World Voting Application</h1>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Candidate</th>
<th>Votes</th>
</tr>
</thead>
<tbody>
<tr>
<td>Justin</td>
<td id="candidate-1"></td>
</tr>
<tr>
<td>UltraMan</td>
<td id="candidate-2"></td>
</tr>
<tr>
<td>Omega</td>
<td id="candidate-3"></td>
</tr>
</tbody>
</table>
</div>
<input type="text" id="candidate" />
<a href="#" onclick="VoteToCandidate()" class="btn btn-primary">Vote</a>
</body>
<script src="./web3.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script>
<script src="./index.js"></script>
</html>
4.编译、部署合约
1)启动ganache-cli
cd web3_test
cd node_modules
cd ganache-cli
node cli.js
2)编译部署
Web3 = require('web3')
var web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
var fs = require('fs');
var solc = require('solc');
var sourceCode = fs.readFileSync('Voting.sol').toString();
var compileCode = solc.compile(sourceCode,1);
var temp = compileCode.contracts[':Voting'].interface;
var abi = JSON.parse(temp);
var byteCode = compileCode.contracts[':Voting'].bytecode
var VotingContract = web3.eth.contract(abi)
var deployTxObject = {from:web3.eth.accounts[0],data:byteCode,gas:3000000}
var contractInstance = VotingContract.new(["Justin","UltraMan","Omega"],deployTxObject)
3)获取abi、address,编写index.js
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
abi = JSON.parse('[{"constant":true,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"candidateVotes","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"VoteToCandidate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"votesReceived","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"candidateList","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"candidateNames","type":"bytes32[]"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]')
VotingContract = web3.eth.contract(abi);
contractInstance = VotingContract.at('0xec43af27fabe5b8e3efaa96ee3445cee60026fb6');
candidates = {"Justin": "candidate-1", "UltraMan": "candidate-2", "Omega": "candidate-3"}
function VoteToCandidate() {
candidateName = $("#candidate").val();
contractInstance.VoteToCandidate(candidateName, {from: web3.eth.accounts[0]}, function() {
let div_id = candidates[candidateName];
$("#" + div_id).html(contractInstance.candidateVotes.call(candidateName).toString());
});
}
$(document).ready(function() {
candidateNames = Object.keys(candidates);
for (var i = 0; i < candidateNames.length; i++) {
let name = candidateNames[i];
let val = contractInstance.candidateVotes.call(name).toString()
$("#" + candidates[name]).html(val);
}
});
5.演示
注:我没有写node server,用的vs code插件live server