DApp投票合约简单开发步骤(完整)

友情提示:本文讲解比较快,若看不懂,可以先看看我的另一篇文章,链接给出 开发一个简单的智能合约 ,之后再来看本篇文章,会完全掌握开发步骤。

一、环境搭建

  1. 安装nodejs,npm会同时安装,下载地址:Nodejs
  2. 安装truffle框架,这是一个流行的以太坊开发框架,内置的智能合约编译,连接,部署等功能,安装命令:

npm install -g truffle

  1. 安装以太坊网络模拟软件Ganachi,安装命令:

npm install -g ganachi-cli

  1. 安装web3.js,web3.js能够帮助我们与智能合约交互。

npm install web3

二、开发步骤

  1. 随便在一个目录下创建一个空目录,命名为Voting,在控制台上进入这个文件,之后再输入turffle unbox webpack
    在这里插入图片描述
  • 这样会初始化这个文件
  1. 编写智能合约代码,智能合约是用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
  1. app目录下是储存前端代码的地方,在这里给出前端代码,首先是html代码,修改index.html代码如下:

<html>
<head>
  <title>Hello World DApptitle>
  <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 Applicationh1>
  <div id="address">div>
  <div class="table-responsive">
    <table class="table table-bordered">
      <thead>
        <tr>
          <th>Candidateth>
          <th>Votesth>
        tr>
      thead>
      <tbody>
        <tr>
          <td>Ramatd>
          <td id="candidate-1">td>
        tr>
        <tr>
          <td>Nicktd>
          <td id="candidate-2">td>
        tr>
        <tr>
          <td>Josetd>
          <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">Votea>
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
    }
  }
}

三、开始运行

  1. 打开一个终端运行ganache-cli:
    DApp投票合约简单开发步骤(完整)_第1张图片

  2. 打开另一个终端,执行truffle compile编译,truffle migrate部署智能合约,npm run dev运行

  3. 设置metamask的钱包网络为8545(和Ganache一致):
    DApp投票合约简单开发步骤(完整)_第2张图片
    问题:什么是metamask?

  • metamask是一个谷歌浏览器的插件,是轻量级的以太坊钱包,支持正式的以太坊网络,也可以用于测试合约代码,它有以下简单的功能:
  1. 创建新账户
  2. 发币和收币
  3. 购买正式币和测试币(根据不同的网络,获取方式不一致)
  4. 更改地址所在的网络
  5. 调用合约功能测试
  1. 打开index.html,就能直接运行了:
    DApp投票合约简单开发步骤(完整)_第3张图片
  2. 这个投票的智能合约的所有成品我会发出来,关注我就能下载了:

下载链接:DApp投票系统

你可能感兴趣的:(智能合约,Solidity,开发步骤,区块链,dapp,智能合约,以太坊,数字货币)