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

指路牌

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

环境

windows 10 64bit

参考博客

youclavier -- 以太坊投票Dapp教程

背景

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

步骤

  1. 参考我另一片blog, 安装nvm
  2. 安装node 9.11.1 并切换环境
    nvm install 9.11.1
    nvm use 9.11.1
  3. 创建一个新的工作目录,并在命令行索引到该路径
  4. 安装ganche-cli、web3、solc
    npm install ganache-cli
    npm install [email protected]
    npm install [email protected]       //此处原博客没有版本,会安装高于0.4的版本,会导致后续编译smart contract编译失败 

    在安装了ganache-cli与web3时,由于教程版本问题会出现报错,但是不影响。

  5. 启动ganache-cli
    node_modules\.bin\ganache-cli

  6. 使用Solidity创建Smart Contract,命名为:Voting.sol
    
    pragma 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;
}}

7. 启动node交互控制台,依次输入以下命令

Web3 = require(‘web3‘)
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"))
web3.eth.accounts


 输入以上最后一条命令后会获取Ganache创建的10个帐号,如下

> 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)
  1. 下载web3.js文件,下载后放在工作根目录下。
    由cdn不知什么原因不可用,所以直接下载源文件,链接如下
    web3.js 0.20.6
  2. 在根目录下创建index.html文件,并粘贴以下代码,需要在截图标出处,更换成第8步自己部署的smart contract的address
    
    &lt;!DOCTYPE html&gt;
    &lt;html&gt;
    &lt;head&gt;
    &lt;title&gt;DApp&lt;/title&gt;
    &lt;link href=‘https://fonts.googleapis.com/css?family=Open Sans:400,700‘ rel=‘stylesheet‘ type=‘text/css‘&gt;
    &lt;link href=‘https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css‘ rel=‘stylesheet‘ type=‘text/css‘&gt;
    &lt;/head&gt;
    &lt;body class="container"&gt;
    &lt;h1&gt;Voting Application&lt;/h1&gt;
    &lt;div class="table-responsive"&gt;
    &lt;table class="table table-bordered"&gt;
    &lt;thead&gt;
    &lt;tr&gt;
    &lt;th&gt;Candidate&lt;/th&gt;
    &lt;th&gt;Votes&lt;/th&gt;
    &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
    &lt;tr&gt;
    &lt;td&gt;James&lt;/td&gt;
    &lt;td id="candidate-1"&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
    &lt;td&gt;Norah&lt;/td&gt;
    &lt;td id="candidate-2"&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
    &lt;td&gt;Jones&lt;/td&gt;
    &lt;td id="candidate-3"&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;/tbody&gt;
    &lt;/table&gt;
    &lt;/div&gt;
    &lt;input type="text" id="candidate" /&gt;
    &lt;a href="#" onclick="voteForCandidate()" class="btn btn-primary"&gt;Vote&lt;/a&gt;
    &lt;/body&gt;
<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)

11. 在浏览器打开index.html,输入Candidate中的人名后,点击Vote即可投票,投票后效果如下
![](https://user-images.githubusercontent.com/37465243/64078736-f8de4d80-cd10-11e9-9e1a-173c812f2264.png)
每次点击投票,也都会生成一个新的区块,效果如下。
![](https://user-images.githubusercontent.com/37465243/64078737-f8de4d80-cd10-11e9-874c-d3e8570432fb.png)

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

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

####
***要获取更多Haytham原创文章,请关注公众号"许聚龙":***
![我的微信公众号](https://user-images.githubusercontent.com/37465243/63688227-5b2ede00-c839-11e9-9aa9-2b461444f463.png)

原文地址:https://blog.51cto.com/13852791/2438063

时间: 2024-10-09 16:00:51

区块链 Hello World -- 基于以太坊的投票Dapp的相关文章

区块链,使用 Go-Ethereum 搭建以太坊私有链

1.什么是Ethereum(以太坊) 以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约.开源的底层系统,以太坊从诞生到2017年5月,短短3年半时间,全球已有200多个以太坊应用诞生.以太坊是一个平台和一种编程语言,使开发人员能够建立和发布下一代分布式应用. 以太坊可以用来编程,分散,担保和交易任何事物:投票,域名,金融交易所,众筹,公司管理, 合同和大部分的协议,知识产权,还有得益于硬件集成的智能资产. 以太坊的白皮书:https://github.com/ethe

如何从零开始学习区块链技术——推荐从以太坊开发DApp开始

很多人迷惑于区块链和以太坊,不知如何学习,本文简单说了一下学习的一些方法和资源. 一. 以太坊和区块链的关系 从区块链历史上来说,先诞生了比特币,当时并没有区块链这个技术和名词,然后业界从比特币中提取了技术架构和体系,称之为区块链技术.从比特币提取的区块链技术称之为区块链1.0时代,那个时候的应用主要以电子货币和去中心化交易为主,比如各种山寨币.而以太坊将区块链带入了2.0的时代,区块链2.0不是推翻了1.0,而是在1.0的基础上实现了区块知晓.价值知晓.图灵完备,并进行了细节优化,从而形成了以

区块链入门(2):搭建以太坊私有链(private network of ethereum),以及挖矿的操作..

在做一些测试工作的时候, 为了方便控制以及更快的进入真正的测试工作,可能需要搭建一个私有的以太坊网络. 而以太坊节点之间能够互相链接需要满足1)相同的协议版本2)相同的networkid,所以搭建私有网络最方便的方法就是通过geth命令中的--networkid选项,设置一个与主网不同的networkid(主网的networkid为1),这也是官方推荐的方法. 下面开始建立私有以太坊网络: mkdir private-geth cd private-geth 建立创世纪区块文件,是一个json格

基于以太坊创建自己的代币(小白版)

写在前面 不可否认做为一个web前端工程师,转型区块链,"智能合约开发"是最好的一个切入点了.嗯,那么就做一个以太坊智能合约开发的系列教程吧.不奢望转型,只为了记录和见证自己的成长.这一篇算是引子.序或者叫前传. 本文会详细的介绍创建一个基于以太坊ERC20代币的整个流程,旨在帮助没有任何基础的小伙伴顺利创建自己的代币,并有一个较为完整的从开发部署到交易测试的体验. 一.开发前的准备 1.首先需要给你的chrome浏览器安装一个metaMask钱包插件. metaMask的安装有些偏离

搭建基于以太坊的私有链环境

零.概述 版本号:Ubuntu-16.04 ethereum-1.6.0-stable go - 1.7.4 一.Ubuntu下安装geth sudo apt-get install software-properties-common sudo add-apt-repository -y ppa:ethereum/ethereum sudo apt-get update sudo apt-get install ethereum 二.创建初始化文件 vim genesis.json {    

基于以太坊实现代币发布

https://blog.csdn.net/Y_xiaohe1234/article/details/76848150 一.什么是代币?代币是利用以太坊的智能合约编写的数字货币.程序员可以通过编写智能合约代码,创建一种新的数字货币.你可以实现的功能: 基本功能:-创建数字货币,设置货币的名称.货币总量.货币图标等基本参数.-创建货币交易功能.实现货币在不同用户之间的转移. 上面的是基本功能,已经可以实现基本的代表交换,下面是高级功能,可以实现更加复杂的应用.高级功能:-创建货币的管理者.虽然区块

基于以太坊的Token开发步骤

Token开发步骤 一.准备工具1.安装以太坊brew tap ethereum/ethereumbrew install ethereum2.node:brew install nodejs3.安装依赖库:npm install -g ganache-cli web3 solc truffle truffle-contract zeppelin-solidity4.运行ganache-cli,端口默认是85455.配置myetherwallet设置自定义的网络:https://www.myet

币圈Telegram ICO筹8.5亿美元, 拟建第三代区块链网络, 目标以太坊

据国外媒体报道,币圈核心即时通讯工具Telegram本周(至2月17日当周)稍早递交给美国证券交易委员会(SEC)的一份文件显示,该公司已经通过ICO筹集到8.5亿美元资金,用于开发TON开源网络.研发和维护Telegram Messenger以及其他目的. 一.关于Telegram Telegram是一款开源且跨平台的IM工具(类似 Whatsapp.Messenger.微信),Telegram也叫电报,于2013年推出,目前拥有1.8亿用户,每天发送700亿条信息.被称为"俄罗斯版'微信'&

{区块链教程}以太坊源码分析fast sync算法二

{区块链教程}以太坊源码分析fast sync算法二:上面的表格应该这样解释:如果我们每隔K个区块头验证一次区块头,在N个区块头之后,伪造的概率小于***者产生SHA3冲突的概率.这也意味着,如果确实发现了伪造,那么最后的N个头部应该被丢弃,因为不够安全.可以从上表中选择任何{N,K}对,为了选择一个看起来好看点的数字,我们选择N = 2048,K = 100.后续可能会根据网络带宽/延迟影响以及可能在一些CPU性能比较受限的设备上运行的情况来进行调整. Using this caveat ho