千家信息网

以太坊区块链如何使用NodeJs、Web3开发投票DApp

发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,这篇文章将为大家详细讲解有关以太坊区块链如何使用NodeJs、Web3开发投票DApp,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、开发完成后页面预览如下用户可
千家信息网最后更新 2025年12月02日以太坊区块链如何使用NodeJs、Web3开发投票DApp

这篇文章将为大家详细讲解有关以太坊区块链如何使用NodeJs、Web3开发投票DApp,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

1、开发完成后页面预览如下

用户可以查看到当前参与投票的候选人名单已经他们各自的目前所得票数,选择其中一名进行投票,被投票的人所得票数对应增加。

2、开发准备工作

  • 本地NodeJs环境

  • Ganache测试环境

  • 熟悉基础的Web3-Api操作,安装命令为: npm install web3@^0.20.0 --save

  • NodeJs安装Solc编译环境,安装命令为:npm install sol

  • 期间遇坑,安装Windows构建工具,安装命令为:npm install --global --production windows-build-tools

  • python27

3、编写智能合约

创建工作目录 Voting-Node,在此目录下新建 Voting.sol 智能合约文件,并在Remix中对此文件进行编辑,最后编辑完成后的文件内容如下:

pragma solidity ^0.4.18;contract Voting {  mapping (bytes32 => uint8) public votesReceived;  bytes32[] public candidateList;  constructor (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;   }}

4、编译、部署、测试 智能合约

在Voting-Node目录打开命令行并输入node 命令,可以进入REPL环境,分步执行编译部署命令,不过这种方式比较麻烦,不方便维护和修改,此处直接在Voting-Node目录中编写好了一个编译、部署、测试 的 depoy.js文件,直接在Nodejs中运行就可以看到结果,内容如下:

//引入web3模块let Web3 = require('web3');//初始化 web3let web3 = new Web3(new Web3.providers.HttpProvider("http://127.0.0.1:7545"));//输出初始化结果console.log('Initialization web3 complete,the first account is '+ web3.eth.accounts[0]);let fs = require('fs');let code = fs.readFileSync('Voting.sol').toString();let solc = require('solc');//编译合约为ABI文件let compiledCode = solc.compile(code);console.log('Compile Voting.sol complete');//部署合约至区块链节点let abiDefinition = JSON.parse(compiledCode.contracts[':Voting'].interface);//写入ABI文件至本地文件目录fs.writeFile('Voting.json',JSON.stringify(abiDefinition), {}, function(err) {    console.log('write ABI file [Voting.json] complete . ');});let VotingContract = web3.eth.contract(abiDefinition);let byteCode = compiledCode.contracts[':Voting'].bytecode;//调用VotingContract对象的new()方法来将投票合约部署到区块链。new()方法参数列表应当与合约的 构造函数要求相一致。对于投票合约而言,new()方法的第一个参数是候选人名单。let deployedContract = VotingContract.new(['Rama','Nick','Jose'],{data: byteCode, from: web3.eth.accounts[0], gas: 4700000});//输出合约 地址,如果此处没有返回地址,可以在Ganache日志中查看到console.log('deploy complete,deploy address is '+ deployedContract.address);//let contractInstance = VotingContract.at(deployedContract.address);let contractInstance = VotingContract.at('0xa167fddc1c6d3d6187a748947b8f00b0dc4fc8db');///这里改为你自己的deployedContract.address//测试合约调用contractInstance.voteForCandidate('Rama', {from: web3.eth.accounts[0]});contractInstance.voteForCandidate('Rama', {from: web3.eth.accounts[0]});contractInstance.voteForCandidate('Rama', {from: web3.eth.accounts[0]});contractInstance.voteForCandidate('Nick', {from: web3.eth.accounts[0]});contractInstance.voteForCandidate('Jose', {from: web3.eth.accounts[0]});contractInstance.voteForCandidate('Jose', {from: web3.eth.accounts[0]});console.log("--------------finish----------------");let RamaVote=contractInstance.totalVotesFor.call('Rama');let NickVote=contractInstance.totalVotesFor.call('Nick');let JoseVote=contractInstance.totalVotesFor.call('Jose');console.log("Rama's vote is "+RamaVote);console.log("Nick's vote is "+NickVote);console.log("Jose's vote is "+JoseVote);

5、网页交互

在完成上面的编写、编译、部署、测试环节后,添加网页交互那就很简单了。

在Voting-Node目录 打开命令行,执行初始化命令,如下:

npm init -y

会在此目录下生成 package.json 文件,修改此文件内容如下:

{  "name": "Voting-Node",  "version": "1.0.0",  "description": "",  "main": "index.js",  "dependencies": {    "solc": "^0.4.23",    "web3": "^0.19.0"  },  "devDependencies": {},  "scripts": {    "dev": "node index.js"  },  "keywords": [],  "author": "Ruoli",  "license": "ISC"}

在目录下新建 index.js 、 index.html、app.js 文件,如下所示。

index.js 内容如下:

var express = require('express');var app = express();var server = require('http').createServer(app);var Web3 = require("web3");app.use(express.static('.'));let web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));//这里导入你自己的ABIlet abi = JSON.parse('[{"constant":true,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"totalVotesFor","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"validCandidate","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","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"},{"constant":false,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"voteForCandidate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"candidateNames","type":"bytes32[]"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]')let VotingContract = web3.eth.contract(abi);//这里要替换成你自己的地址let contractInstance = VotingContract.at('0xcadcaf0cf38ad0adc259b8426b723bb31faa899d');app.get("/totalVotesFor", function(req, res) {        var voteName = req.query.voteName;        var vote_num=contractInstance.totalVotesFor.call(voteName).toString();        console.log(vote_num);        res.send(vote_num);});app.get("/voteForCandidate", function(req, res) {        var voteName = req.query.voteName;        contractInstance.voteForCandidate(voteName, {from: web3.eth.accounts[0]});        var vote_num=contractInstance.totalVotesFor.call(voteName).toString();        res.send(vote_num);});server.listen(3000);// 控制台会输出以下信息console.log('Server running at http://127.0.0.1:3000/index.html');

index.html 内容如下:

     Voting DApp       

简易投票 DApp

app.js 内容如下:

注意:此处需要将之前保存的 ABI文件内容引入。

let candidates = {"Rama": "candidate-1", "Nick": "candidate-2", "Jose": "candidate-3"}$(document).ready(function() {        //初始化余额        candidateNames = Object.keys(candidates);   for (var i = 0; i < candidateNames.length; i++) {                let voteName = candidateNames[i];              totalVotesFor(voteName);           }   //初始化事件   $(".vote-btn").click(function(){           //获取投票人名称           let voteName=$(this).prev().prev().text();           voteForCandidate(voteName);   });});function totalVotesFor(voteName) {    $.get("/totalVotesFor?voteName=" + voteName, function(data) {                if(data == "Error") {            alert('提示', '500');        } else {                        $("#"+candidates[voteName]).html(data);                }    });}function voteForCandidate(voteName) {    $.get("/voteForCandidate?voteName=" + voteName, function(data) {        if(data == "Error") {            alert('提示', '500');        } else {           let div_id = candidates[voteName];                   var vote_num = totalVotesFor(voteName);                   $("#"+div_id).html(data);//.fadeIn(800);                   $("#"+div_id);//.fadeOut(400);        }    });}

至此所有开发已经完成。

6、网页访问与测试

执行如下命令启动服务:

PS C:\Workspace\Ruoli-Code\Voting-Node> npm run dev> Voting-Node@1.0.0 dev C:\Workspace\Ruoli-Code\Voting-Node> node index.jsServer running at http://127.0.0.1:3000/index.html

执行完成后 在浏览器中 访问:http://127.0.0.1:3000/index.html

即可看到最开始的界面,至此所有开发完成。

关于"以太坊区块链如何使用NodeJs、Web3开发投票DApp"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

投票 文件 合约 命令 内容 目录 开发 测试 编译 区块 环境 地址 方法 智能 篇文章 网页 输出 以太 候选人 参数 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 河南科技大学直播互联网 国家网络安全宣传视频素材 软件开发项目修改表 软件开发员日志 电子政务外网网络安全总结 申请网络安全服务能力评定 福州新大陆软件开发需要技术吗 北京蓝果网络技术怎么样 专业卸载网站及数据库 开发工程师与数据库工程师 北京有名的软件开发培训班 电脑带网络安全模式能否上网 泰拉瑞亚在服务器怎么创建房子 川大首招网络安全人才 域服务器更换ip 广电网络安全机房 明日之后沙石古堡服务器人多吗 网络安全规划设计项目成员及分工 c 数据库 填充下拉 软件开发用的设备 网络安全防护专业就业前景 e点通网络安全保护 龙池莆田网络技术有限公司 人民银行软件开发中心每年招工吗 计算机网络安全专科排名 网络安全主题会会后心得500字 习水收费软件开发 为什么服务器没有属性了 视频软件开发好找工作吗 如何确立网络安全意识论文
0