以太坊智能合约实战 - 一个投票dapp

前期准备

  • 编辑器
    理论上讲任何编辑器都可以编写Solidity合约代码,比如:WebStorm,VSCode,Sublime等。我选择atom
    autocomplete-solidity代码自动补齐
    linter-solium、linter-solidity代码错误检查
    language-ethereum支持Solidity代码高亮以及Solidity代码片段
  • 环境
    node.js
    开发框架:truffle(用react box)
    安装truffle
$ npm install -g ethereumjs-testrpc truffle

创建项目

luoxuedeMacBook-Pro:~ luoxue$ cd desktop
luoxuedeMacBook-Pro:desktop luoxue$ mkdir voting
luoxuedeMacBook-Pro:desktop luoxue$ cd voting
luoxuedeMacBook-Pro:voting luoxue$ truffle unbox react-box
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!

Commands:

  Compile:              truffle compile
  Migrate:              truffle migrate
  Test contracts:       truffle test
  Test dapp:            npm test
  Run dev server:       npm run start
  Build for production: npm run build
  • 项目结构


    以太坊智能合约实战 - 一个投票dapp_第1张图片
    image.png
  • contracts:编写智能合约的文件夹,所有的智能合约文件都放置在这里
  • migrations:部署合约配置的文件夹
  • src:基于React的Web端源码
  • test:智能合约测试用例文件夹

编写智能合约

  • 在contracts文件夹下创建Voting.sol文件
  • 编译环境: remix-online (remix.ethereum.org)
  • 创建合约对象Voting,存candidtae,bytes23[]是可变的
contract Voting{
    
    
   // luo
   // xue
   // ll
   // xx
   // mm
   
   
   bytes32[] candidates = new bytes32[](5);
}
  • 构造函数
 function Voting(bytes32[] _candidates) public{
        
        for(uint i =0; i<_candidates.length;i++){
            candidates[i] = _candidates[i];
        }
        
    }
  • 创建一个字典:候选人-》票数
mapping(bytes32 => uint) candidatesVotingCount;
  • 创建投票方法
 function votingToPerson(bytes32 person) public {
        candidatesVotingCount[person]+=1;
       }
  • 检查是否是合法的候选人
    function isValidPerson(bytes32 person) constant internal returns(bool){
        for(uint i = 0; i
  • 完整版
pragma solidity ^0.4.4;

contract Voting{
    
    
   // luo
   // xue
   // ll
   // xx
   // mm
   
   // ["luo","xue","ll","xx","mm"]
   bytes32[] candidates = new bytes32[](5);
   
   mapping(bytes32 => uint)candidatesVotingCount;
   
   function Voting(bytes32[] _candidates) public {
       for(uint i =0; i<_candidates.length;i++){
           candidates[i] = _candidates[i];
       }
   }
   
   function votingToPerson(bytes32 person) public {
        assert(isValidPerson(person));
        candidatesVotingCount[person]+=1;
       }
       
    function votingTotalToPerson(bytes32 person) constant public returns (uint) {
        return candidatesVotingCount[person];
    }
    
    function isValidPerson(bytes32 person) constant internal returns(bool){
        for(uint i = 0; i
  • remix 检查调用情况


    以太坊智能合约实战 - 一个投票dapp_第2张图片
    image.png

    以太坊智能合约实战 - 一个投票dapp_第3张图片
    image.png
  • 复制粘贴并更换掉simple sample.sol 替换成voting


    以太坊智能合约实战 - 一个投票dapp_第4张图片
    image.png
  • 在migration换掉部署文件中相应部分


    以太坊智能合约实战 - 一个投票dapp_第5张图片
    image.png
  • 编译Voting.sol
    打开truffle控制台

$ truffle develop

编译合约


以太坊智能合约实战 - 一个投票dapp_第6张图片
image.png

发现build文件夹里多了一个 voting.json文件


以太坊智能合约实战 - 一个投票dapp_第7张图片
image.png
  • App.js里面 改json的import


    以太坊智能合约实战 - 一个投票dapp_第8张图片
    image.png
  • 改this.state里面的状态,存储候选人相关信息

constructor(props) {
    super(props)

    this.state = {
      canddidates:[
        {
          name:"luo",
          count:0,
          id:101
        },
        {
          name:"xue",
          count:0,
          id:102
        },
        {
          name:"ll",
          count:0,
          id:103
        },
        {
          name:"xx",
          count:0,
          id:104
        },
        {
          name:"mm",
          count:0,
          id:105
        }
      ],
  • 改路由


    以太坊智能合约实战 - 一个投票dapp_第9张图片
    image.png
  • 与链上交互
    通过get web3交互
    注:
    =>是个js 的箭头函数
    this.instantiateContract() 初始化合约

    以太坊智能合约实战 - 一个投票dapp_第10张图片
    image.png

  • 修改合约初始化,获取合约实例


    以太坊智能合约实战 - 一个投票dapp_第11张图片
    image.png
  • 取到候选人的票数


    以太坊智能合约实战 - 一个投票dapp_第12张图片
    image.png

看控制台输出:
两个1票3个0票


以太坊智能合约实战 - 一个投票dapp_第13张图片
image.png
  • 修改状态机, 让网页上显示合约上的票数


    以太坊智能合约实战 - 一个投票dapp_第14张图片
    image.png
  • 写修改函数,注意参数不用var 定义变量


    以太坊智能合约实战 - 一个投票dapp_第15张图片
    image.png
  • 在remix里投票,看网页上也有实时变化
  • 加投票按钮


    以太坊智能合约实战 - 一个投票dapp_第16张图片
    image.png
  • 从input 里获取资料,ref


    以太坊智能合约实战 - 一个投票dapp_第17张图片
    image.png

    从name里获得了input的value
    把contract变成全局变量
    在点击button里面调用


    image.png

    但要注意,这里from 的要用web3来调用
  • 然后刷新票数,直接复制上面即可


    以太坊智能合约实战 - 一个投票dapp_第18张图片
    image.png

你可能感兴趣的:(以太坊智能合约实战 - 一个投票dapp)