友情提示:本文講解比較快,若看不懂,可以先看看我的另一篇文章,鏈接給出 開發一個簡單的智能合約 ,之后再來看本篇文章,會完全掌握開發步驟,
一、環境搭建
- 安裝nodejs,npm會同時安裝,下載地址:Nodejs
- 安裝truffle框架,這是一個流行的以太坊開發框架,內置的智能合約編譯,連接,部署等功能,安裝命令:
npm install -g truffle
- 安裝以太坊網路模擬軟體Ganachi,安裝命令:
npm install -g ganachi-cli
- 安裝web3.js,web3.js能夠幫助我們與智能合約互動,
npm install web3
二、開發步驟
- 隨便在一個目錄下創建一個空目錄,命名為Voting,在控制臺上進入這個檔案,之后再輸入turffle unbox webpack

- 這樣會初始化這個檔案
- 撰寫智能合約代碼,智能合約是用Solidity語言撰寫的,想要更多了解Solidity,可以去閱讀我的其它文章,有很完整的Solidity學習的知識點,在這里我們之間給出智能合約的代碼:
pragma solidity ^0.4.18; this code will use
contract Voting {
// 儲存候選人及其所得票數
mapping (bytes32 => uint8) public votesReceived;
// 儲存候選人的名字
bytes32[] public candidateList;
// 構造方法,加入候選人
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) view public returns (bool) {
for(uint i = 0; i < candidateList.length; i++) {
if (candidateList[i] == candidate) {
return true;
}
}
return false;
}
}
- 代碼邏輯很清晰,要看懂一個沒什么問題,

將智能合約的代碼放在contracts目錄下,這是儲存合約代碼的目錄,命名為Voting.sol
- app目錄下是儲存前端代碼的地方,在這里給出前端代碼,首先是html代碼,修改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代碼:
// 匯入css
import "../stylesheets/app.css";
// 匯入需要的包
import { default as Web3} from 'web3';
import { default as contract } from 'truffle-contract'
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().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");
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: 32px;
}
h3 {
font-weight: normal;
color: #AAA;
font-size: 24px;
}
.black {
color: black;
}
#balance {
color: black;
}
.hint {
color: #666;
}
- 修改部署方式,在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 compile編譯,truffle migrate部署智能合約,npm run dev運行
-
設定metamask的錢包網路為8545(和Ganache一致):

問題:什么是metamask?
- metamask是一個谷歌瀏覽器的插件,是輕量級的以太坊錢包,支持正式的以太坊網路,也可以用于測驗合約代碼,它有以下簡單的功能:
- 創建新賬戶
- 發幣和收幣
- 購買正式幣和測驗幣(根據不同的網路,獲取方式不一致)
- 更改地址所在的網路
- 呼叫合約功能測驗
- 打開index.html,就能直接運行了:

- 這個投票的智能合約的所有成品我會發出來,關注我就能下載了:
下載鏈接:DApp投票系統
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/247218.html
標籤:區塊鏈
