美文网首页
以太坊智能合约实战 - 一个投票dapp

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

作者: 罗雪Melody | 来源:发表于2018-05-08 16:24 被阅读0次

前期准备

  • 编辑器
    理论上讲任何编辑器都可以编写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
  • 项目结构


    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<candidates.length; i++){
            if(candidates[i] == person){
                return true;
            }
        }
        return false;
    }

  • 完整版
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<candidates.length; i++){
            if(candidates[i] == person){
                return true;
            }
        }
        return false;
    }
   }
   
  • remix 检查调用情况


    image.png
    image.png
  • 复制粘贴并更换掉simple sample.sol 替换成voting


    image.png
  • 在migration换掉部署文件中相应部分


    image.png
  • 编译Voting.sol
    打开truffle控制台

$ truffle develop

编译合约


image.png

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


image.png
  • App.js里面 改json的import


    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
        }
      ],
  • 改路由


    image.png
  • 与链上交互
    通过get web3交互
    注:
    =>是个js 的箭头函数
    this.instantiateContract() 初始化合约

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


    image.png
  • 取到候选人的票数


    image.png

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


image.png
  • 修改状态机, 让网页上显示合约上的票数


    image.png
  • 写修改函数,注意参数不用var 定义变量


    image.png
  • 在remix里投票,看网页上也有实时变化
  • 加投票按钮


    image.png
  • 从input 里获取资料,ref


    image.png

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


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


    image.png

相关文章

网友评论

      本文标题:以太坊智能合约实战 - 一个投票dapp

      本文链接:https://www.haomeiwen.com/subject/ccmurftx.html