区块链投票应用:使用solidity+truffle+metamsk开发Dapp应用
Posted NUDT_林逸飞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区块链投票应用:使用solidity+truffle+metamsk开发Dapp应用相关的知识,希望对你有一定的参考价值。
参考教程:https://www.bilibili.com/video/BV14z4y1Z7Jd?p=8
本博客是学习Dapp开发过程的笔记,感谢令狐一冲老师精彩讲解。上述是老师B站视频链接。
Ganache
ganache是一个本地区块链环境,每次启动后会在内存中模拟一个区块链。
1.环境安装
1.安装Node.js
2.安装 ganache-cli(ganache也可以)
3.运行ganache
ganache-cli
!!Truffle
安装truffle
sudo npm install -g truffle
安装过程中可能出错,可能解决方式
//升级node.js
sudo npm install -g n
sudo n stable
安装完成之后检查安装
truffle -v //版本
开发DApp(投票为例)
1.编写智能合约
投票合约
// SPDX-License-Identifier: SimPL-2.0
pragma solidity >=0.4.18 <0.8.0;
contract Voting{
bytes32[] public candodateList;
mapping(bytes32 => uint8) public votesReceived;
constructor(bytes32[] memory _candidateListName) public {
candodateList = _candidateListName;
}
function validateCan(bytes32 _candidate) internal view returns(bool) {
for(uint8 i = 0; i< candodateList.length; i++) {
if(candodateList[i] == _candidate)
return true;
}
return false;
}
function voteForCan(bytes32 _candidate) public {
votesReceived[_candidate] += 1;
}
function totalVotes(bytes32 _candidate)public view returns(uint8) {
return votesReceived[_candidate];
}
}
2.创建项目
mkdir Voting
cd Voting
truffle unbox webpack
//webpack 可以换成其他的模板文件,也可以换成init不用模板
//遇到问题了,
/*
✔ Preparing to download box
✖ Downloading
Unbox failed!
✖ Downloading
Unbox failed!
Error: Error connecting to github.com. Please check your internet connection and try again.
*/
//也可以通过如下方式获取
git clone https://github.com/truffle-box/webpack-box.git
$ cd truffle-init-webpack
3.修改合约部署脚本
1.启动ganache
删除模板里其他合约,将自己的合约部署到ganache上
2.修改合约部署脚本
修改migration中的2_deploy+contract.js(照着葫芦画瓢)
// const ConvertLib = artifacts.require("ConvertLib");
// const MetaCoin = artifacts.require("MetaCoin");
const Voting = artifacts.require("Voting");
module.exports = function(deployer) {
// deployer.deploy(ConvertLib);
// deployer.link(ConvertLib, MetaCoin);
// deployer.deploy(MetaCoin);
deployer.deploy(Voting, [
"0x4100000000000000000000000000000000000000000000000000000000000000",
"0x4200000000000000000000000000000000000000000000000000000000000000"
]);
//注意Voting部署时有参数
};
3.编译合约
wakin@ubuntu:~/Documents/course/truffle/vote1/webpack-box$ truffle compile
4.修改网络方式
修改truffle-conflig.js,改成ganach
(好像不用改)
module.exports = {
networks: {
development: {
host: 'localhost',
port: 8545,
network_id: '*' // Match any network id
}
}
}
4.部署合约
truffle migrate
//注意有参数,并且还要是bytes32//部署成功之后,可以打开truffle自带的控制台来测试一下
4.编写前端界面
<!DOCTYPE html>
<html>
<head>
<title>Voting</title>
</head>
<style>
input {
display: block;
margin-bottom: 12px;
}
</style>
<body>
<h1>Voting App</h1>
<p>Alice : <strong id="alice">loading...</strong> tickets</p>
<p>Bob : <strong id="bob">loading...</strong> tickets</p>
<label>VotoFor :</label>
<input type="text" id="candidate" />
<button onclick="App.voteForCan()">vote</button>
<script src="index.js"></script>
</body>
</html>
必须在app目录下
sudo npm run dev//先到指定目录安装依赖npm install
去浏览器看看一下界面
http://127.0.0.1:8080/
5.前端与区块链交互
编辑index.js
import Web3 from "web3";
//导入Voting.json
import votingArtifact from "../../build/contracts/Voting.json";
//定义两个值,方便传参
const aInBytes32 = "0x4100000000000000000000000000000000000000000000000000000000000000";
const bInBytes32 = "0x4200000000000000000000000000000000000000000000000000000000000000";
//定义了app
const App = {
web3: null,
account: null,
voting: null, //定义一个voting的实例
//启动时需要的
start: async function() {
const { web3 } = this;
try {
// get contract instance
const networkId = await web3.eth.net.getId();
//要改成自己的网络
const deployedNetwork = votingArtifact.networks[networkId];
this.voting = new web3.eth.Contract(
votingArtifact.abi,
deployedNetwork.address,
);
// get accounts
const accounts = await web3.eth.getAccounts();
this.account = accounts[0];
//先刷新一下界面
this.ready();
} catch (error) {
console.error("Could not connect to contract or chain.");
}
},
//start函数后还应该有哪些函数呢
//1.refresh展示最新票数
refresh: async function(id, nameInBytes32) {
const { totalVotes } = this.voting.methods;
//从区块链拿到票数
const tickets = await totalVotes(nameInBytes32).call();
//写到页面上去,并更新最新票数
const element = document.getElementById(id);
element.innerHTML = tickets.toString();
},
//2.ready:当网页好的时候要把票数读出来
ready: async function() {
try {
this.refresh("alice", aInBytes32);
this.refresh("bob", bInBytes32);
} catch (err) {
console.log(err);
}
},
//3.votingfor函数(中间需要展示票数的函数)
voteForCan: async function() {
try {
//先获取到合约的方法
const { voteForCan } = this.voting.methods;
//再获取候选者名字:来自输入框
const candidateName = document.getElementById("candidate").value;
//拿到票数后对应加一
if (candidateName == "Alice") {
await voteForCan(aInBytes32).send({ from: this.account });
this.refresh("alice", aInBytes32);
} else if (candidateName == "Bob") {
await voteForCan(bInBytes32).send({ from: this.account });
this.refresh("bob", bInBytes32);
}
} catch (err) {
//如果有err就打印一下
console.log(err);
}
}
};
window.App = App;
window.addEventListener("load", function() {
if (window.ethereum) {
// use MetaMask's provider
App.web3 = new Web3(window.ethereum);
window.ethereum.enable(); // get permission to access accounts
} else {
console.warn(
"No web3 detected. Falling back to http://127.0.0.1:8545. You should remove this fallback when you deploy live",
);
// fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
App.web3 = new Web3(
new Web3.providers.HttpProvider("http://127.0.0.1:8545"),
);
}
App.start();
});
6.metamask的使用(如遇问题,经常刷新)
1.通过私钥导入账户
2.链接到本地网络
Localhost 8545
3.连接账户
4.投票操作
总结
1.编写智能合约
2.编译
truffle compile
3.部署
truffle migrate
4.启动本地区块链
ganache -cli
5.编写Dapp(html和js)
6.(app目录下)启动Dapp
sudo npm run dev
7.http://127.0.0.1:8080/
查看界面,并于小狐狸交互
注意:每次都要重新进行2-6操作
以上是关于区块链投票应用:使用solidity+truffle+metamsk开发Dapp应用的主要内容,如果未能解决你的问题,请参考以下文章
区块链投票应用:使用solidity+truffle+metamsk开发Dapp应用
以太坊 DApp 开发入门实战! 用Node.js和truffle框架搭建——区块链投票系统!