首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >区块链 Hello World -- 基于以太坊的投票Dapp

区块链 Hello World -- 基于以太坊的投票Dapp

原创
作者头像
HaythamXu
修改2019-09-10 17:01:41
7080
修改2019-09-10 17:01:41
举报

指路牌

  • 以太坊
  • 区块链
  • Dapp
  • 以太坊hello world

环境

windows 10 64bit

参考博客

youclavier -- 以太坊投票Dapp教程

背景

准备接手一个IPFS+Ethereum的项目,先学习一下Ethereum,并尝试完成一个Hello World。

步骤

  1. 参考我另一片blog, 安装nvmnvm install 9.11.1 nvm use 9.11.1npm install ganache-cli npm install web3@0.20.1 npm install solc@0.4.21 //此处原博客没有版本,会安装高于0.4的版本,会导致后续编译smart contract编译失败 在安装了ganache-cli与web3时,由于教程版本问题会出现报错,但是不影响。
  2. 安装node 9.11.1 并切换环境
  3. 创建一个新的工作目录,并在命令行索引到该路径
  4. 安装ganche-cli、web3、solc
  5. 启动ganache-clinode_modules\.bin\ganache-cli
    ganache-cli启动后输出如下
    ganache-cli启动后输出如下
    6. 使用Solidity创建Smart Contract,命名为:Voting.solpragma solidity ^0.4.18; 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; }}> Web3 = require('web3') > web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) > web3.eth.accounts 输入以上最后一条命令后会获取Ganache创建的10个帐号,如下
  6. 启动node交互控制台,依次输入以下命令
> code = fs.readFileSync('Voting.sol').toString()
> solc = require('solc')
> compiledCode = solc.compile(code)

全部完成会得到如下截图的输出,表示smart contract编译成功

8.部署smart contract

> abi = JSON.parse(compiledCode.contracts[':Voting'].interface)
> VotingContract = web3.eth.contract(abi)
> byteCode = compiledCode.contracts[':Voting'].bytecode
> deployedContract = VotingContract.new(['James', 'Norah', 'Jones'],{data: byteCode, from: web3.eth.accounts[0], gas: 4700000})
> deployedContract.address

此时会获取address,记下来后续会用到contractInstance = VotingContract.at(deployedContract.address)下载web3.js文件,下载后放在工作根目录下。 由cdn不知什么原因不可用,所以直接下载源文件,链接如下 web3.js 0.20.6 在根目录下创建index.html文件,并粘贴以下代码,需要在截图标出处,更换成第8步自己部署的smart contract的address<!DOCTYPE html> <html> <head> <title>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>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>James</td> <td id="candidate-1"></td> </tr> <tr> <td>Norah</td> <td id="candidate-2"></td> </tr> <tr> <td>Jones</td> <td id="candidate-3"></td> </tr> </tbody> </table> </div> <input type="text" id="candidate" /> <a href="#" onclick="voteForCandidate()" class="btn btn-primary">Vote</a> </body><script src="web3.js"></script> <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script> <script language="javascript" type="text/javascript"> web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); abi = JSON.parse('[{"constant":false,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"totalVotesFor","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"validCandidate","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"votesReceived","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"x","type":"bytes32"}],"name":"bytes32ToString","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"candidateList","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"voteForCandidate","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"contractOwner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"inputs":[{"name":"candidateNames","type":"bytes32[]"}],"payable":false,"type":"constructor"}]') VotingContract = web3.eth.contract(abi); contractInstance = VotingContract.at('0x47f49b300eb86d972f91f103913376fb0a8e52e7'); candidates = {"James": "candidate-1", "Norah": "candidate-2", "Jones": "candidate-3"} function voteForCandidate(candidate) { candidateName = $("#candidate").val(); try { contractInstance.voteForCandidate(candidateName, {from: web3.eth.accounts[0]}, function() { let div_id = candidates[candidateName]; $("#"+div_id).html(contractInstance.totalVotesFor.call(candidateName).toString()); }); } catch (err) { } } $(document).ready(function() { candidateNames = Object.keys(candidates); for (var i = 0; i < candidateNames.length; i++) { let name = candidateNames[i]; let val = contractInstance.totalVotesFor.call(name).toString() $("#"+candidates[name]).html(val); } }); </script></html> ``` ![更换address](https://user-images.githubusercontent.com/37465243/64078738-f976e400-cd10-11e9-82ef-20468a8e6ba5.png)

  1. 在浏览器打开index.html,输入Candidate中的人名后,点击Vote即可投票,投票后效果如下
    每次点击投票,也都会生成一个新的区块,效果如下。

后记

以上步骤就完成了一个基于Ethereum的投票Dapp的完整搭建流程,整合个补全后步骤应该不会有坑的可以顺利搭建完成。

就像“hello world”的字面意思一样,0-1的过程是最艰难的,但是开了头,剩下的1-n也就会顺畅不少。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 指路牌
  • 环境
  • 参考博客
  • 背景
  • 步骤
  • 后记
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档