机器环境
* win10
* nodev8.9.4
初始化项目
* npm install -g truffle
* npm install -g ganache-cli
* truffle unbox webpack
编写投票的智能合约–Voting.sol
* Voting.sol pragma solidity ^0.4.18; //We have to specify what version of
compiler this code will use contract Voting { /* mapping is equivalent to an
associate arrayor hash The key of the mapping is candidate name stored as type
bytes32 and value is an unsigned integer which used to store the vote count */
mapping (bytes32 => uint8)public votesReceived; /* Solidity doesn't let you
create an arrayof strings yet. We will use an array of bytes32 instead to store
the listof candidates */ bytes32[] public candidateList; // Initialize all the
contestants function Voting(bytes32[] candidateNames) public { candidateList =
candidateNames; }function totalVotesFor(bytes32 candidate) view public returns
(uint8) { require(validCandidate(candidate));return votesReceived[candidate]; }
function voteForCandidate(bytes32 candidate) public {
require(validCandidate(candidate)); votesReceived[candidate] +=1; } function
validCandidate(bytes32 candidate) viewpublic returns (bool) { for(uint i = 0; i
< candidateList.length; i++) {if (candidateList[i] == candidate) { return true;
} }return false; } }
编写前端–app目录
* index.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 id="address"></div> <div class=
"table-responsive"> <table class="table table-bordered"> <thead> <tr> <th>
Candidate</th> <th>Votes</th> </tr> </thead> <tbody> <tr> <td>Rama</td> <td id=
"candidate-1"></td> </tr> <tr> <td>Nick</td> <td id="candidate-2"></td> </tr> <
tr> <td>Jose</td> <td id="candidate-3"></td> </tr> </tbody> </table> <div id=
"msg"></div> </div> <input type="text" id="candidate" /> <a href="#" onclick=
"voteForCandidate()" class="btn btn-primary">Vote</a> </body> <script src=
"https://code.jquery.com/jquery-3.1.1.slim.min.js"></script> <script src=
"app.js"></script> </html>
* javascript/app.js // Import the page's CSS. Webpack will know what to do
with it. import "../stylesheets/app.css"; // Import libraries we need. import {
default as Web3} from 'web3'; import { default as contract } from
'truffle-contract' /* * When you compile and deploy your Voting contract, *
truffle stores the abi and deployed address in a json * file in the build
directory. We will use this information * to setup a Voting abstraction. We
will use this abstraction * later to create an instance of the Voting contract.
* Compare this against the index.js from our previous tutorial to see the
difference *
https://gist.github.com/maheshmurthy/f6e96d6b3fff4cd4fa7f892de8a1a1b4#file-index-js
*/ import voting_artifacts from '../../build/contracts/Voting.json' var Voting
= contract(voting_artifacts);let candidates = {"Rama": "candidate-1", "Nick":
"candidate-2", "Jose": "candidate-3"} window.voteForCandidate = function
(candidate) { let candidateName = $("#candidate").val(); try { $("#msg").html(
"Vote has been submitted. The vote count will increment as soon as the vote is
recorded on the blockchain. Please wait.") $("#candidate").val(""); /*
Voting.deployed() returns an instance of the contract. Every call * in Truffle
returns a promise which is why we have used then() * everywhere we have a
transaction call */ Voting.deployed().then(function(contractInstance) {
contractInstance.voteForCandidate(candidateName, {gas:140000, from:
web3.eth.accounts[0]}).then(function() { let div_id = candidates[candidateName];
return contractInstance.totalVotesFor.call(candidateName).then(function(v) { $(
"#" + div_id).html(v.toString()); $("#msg").html(""); }); }); }); } catch (err)
{ console.log(err); } } $( document ).ready(function() { if (typeof web3 !==
'undefined') { console.warn("Using web3 detected from external source like
Metamask") // Use Mist/MetaMask's provider window.web3 = new
Web3(web3.currentProvider); }else { console.warn("No web3 detected. Falling
back to http://localhost:8545. You should remove this fallback when you deploy
live, as it's inherently insecure. Consider switching to Metamask for
development. More info here:
http://truffleframework.com/tutorials/truffle-and-metamask"); // fallback - use
your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
window.web3 =new Web3(new Web3.providers.HttpProvider("http://localhost:8545"
)); } Voting.setProvider(web3.currentProvider);let candidateNames = Object
.keys(candidates);for (var i = 0; i < candidateNames.length; i++) { let name =
candidateNames[i]; Voting.deployed().then(function(contractInstance) {
contractInstance.totalVotesFor.call(name).then(function(v) { $("#" +
candidates[name]).html(v.toString()); }); }) } });
* stylesheets/app.css body { margin-left: 25%; margin-right: 25%; margin-top:
10%; font-family: "Open Sans", sans-serif; } label { display: inline-block;
width: 100px; } input { width: 500px; padding: 5px; font-size: 16px; } button {
font-size: 16px; padding: 5px; } h1, h2 { display: inline-block; vertical-align:
middle; margin-top: 0px; margin-bottom: 10px; } h2 { color: #AAA; font-size: 32
px; } h3 { font-weight: normal; color: #AAA; font-size: 24px; } .black { color:
black; } #balance { color: black; } .hint { color: #666; }
修改migrate文件
* migrations/2_deploy_contract.js var Voting = artifacts.require(
"./Voting.sol"); module.exports = function(deployer) { deployer.deploy(Voting, [
'Rama', 'Nick', 'Jose']); };
配置truffle.js
// Allows us to use ES6 in our migrations and tests. require('babel-register')
module.exports = { networks: { development: { host: 'localhost', port: 8545,
network_id: '*', gas: 6600000 } } }
启动项目
* 开一个终端执行 ganache-cli
* 开另一个终端执行:truffle migrate ,npm run dev
* 设置metamask钱包的网络为 localhost:8545 并导入ganache-cli的第一个private-key进metamask
Github地址
* https://github.com/maheshmurthy/ethereum_voting_dapp
<https://github.com/maheshmurthy/ethereum_voting_dapp>
热门工具 换一换