• <option id="cacee"><noscript id="cacee"></noscript></option>
  • <table id="cacee"><noscript id="cacee"></noscript></table>
  • <td id="cacee"></td>
  • <option id="cacee"></option>
  • <table id="cacee"></table>
  • <option id="cacee"><option id="cacee"></option></option>
  • <table id="cacee"><source id="cacee"></source></table><td id="cacee"><rt id="cacee"></rt></td>
    <option id="cacee"><option id="cacee"></option></option>
     找回密碼
     立即注冊

    掃一掃,登錄網站

    首頁 自媒體 查看內容
    • 1680
    • 0
    • 分享到

    動手開發一個區塊鏈投票DAPP

    2018-9-25 11:18

    來源: blockchainbrother



    第一個區塊鏈投票DAPP


    前言


    • 我是一個菜鳥,所以在代碼質量上可能不太好,歡迎指點。

    • 閱讀本文可能需要一定的基礎,有疑問歡迎留言。


    本篇文章,將帶讀者用Truffle框架在ganache環境上



    搭建一個屬于自己的投票DAPP雛形,你可以在這基礎上進行擴展。這里如果你對ganache不熟悉的可以使用testrpc環境也是一樣的。


    開發包對應版本


    • web3.js   v0.20.5

    • Truffle  v4.1.3

    • Solidity v0.4.2

    • Ganache 1.1.0


    初始化工程


    這里我們需要提前安裝好 node 和 Truffle,如果不會的,可自行翻閱文檔,網上很多資料。


    • 新建一個文件夾

    • 在新建的文件下執行下面的命令

    truffle unbox pet-shop


    這個命令是通過 truffle 的 unbox 工具初始化一個寵物DAPP,我們這里偷個懶,在官方的 pet-shop 項目上進行修改。


    編寫合約


    在contracts文件夾下面新建一個 Election.sol 的合約文件,在這里我們進行合約編寫。



    合約內容如下:


    pragma solidity ^0.4.2;
    
    contract Election {    
        //結構體
        struct Candidate {
            uint id;
            string name;
            uint voteCount;
        }    //事件
        event votedEvent(
            uint indexed _candidateId
        );    //存儲結構體
        mapping (uint => Candidate) public candidates;    //是否已經投票了
        mapping (address=>bool) public voters;    //總數量
        uint public candidateCount;    //構造函數
        function Election () public {
            addCandidate("張三);
            addCandidate("李四);
        }    //添加候選人
        function addCandidate(string _name) private {
            candidateCount ++;
            candidates[candidateCount] = Candidate(candidateCount, _name, 0);
        }    //投票
        function vote(uint _candidateId) public {        //過濾
            require(!voters[msg.sender]);
           require(_candidateId > 0 && _candidateId <= candidateCount);
                   //記錄用戶已經投票了        voters[msg.sender] = true;        candidates[_candidateId].voteCount ++;        votedEvent(_candidateId);    } }


    合約部分不贅述,如果有疑問可以留言。


    部署合約


    Truffle框架部署合約很簡單,可以通過他的 migration 功能直接部署。


    • 在 migrations 文件夾下面,新建一個名為2_deploy_contract.js 的文件。

    • 在里面我們把我們的合約給加到 migration 里面,代碼如下:

    var Election = artifacts.require("./Election.sol);
    module.exports = function(deployer) {  deployer.deploy(Election); };


    這里說明下,如果你想偷懶,也可以直接在他下面的1_initial_migration.js文件里面導入Election.sol文件再加到 migration 里面。


    • 在一切準備就緒,只需要在終端上執行下面的命令

    truffle migrate --reset


    就能部署好了。為啥要加 --reset 如果你的合約第一次部署,可以不加,如果是迭代覆蓋部署,就的加這個參數,好從新給你分配一個地址,否者會出現莫名其妙的問題,具體詳細介紹,請查閱官方文檔。


    如果你這里使用的tesrpc環境,服務地址的端口是 8545 你需要去 修改下項目里面的 truffle.js文件里面的配置



    編寫html頁面


    由于我們是在 pet-shop 項目上進行修改的,所以我們只需要去修改 src/index.html 文件的內容就可以了。


    我們把內容修改成如下內容:


                 區塊鏈投票        

         

           

             

    區塊鏈投票

             


             
             

               

    Loading...

             

             

               

                                                                                                                                                                            
    #NameVotes

               


                                     

                 

                                               

                            

             

                   


             


           

         

       

                    


    代碼很簡單,不用解釋應該都能看懂哈。


    編寫js文件


    js部分是DAPP比較麻煩的地方,也是最初學者迷惑的地方,我這里先把最終代碼粘貼過來再解釋:


    App = {
      web3Provider: null,
      contracts: {},
      account: '0x0',
    
      init: function() {    return App.initWeb3();
      },
    
      initWeb3: function() {    if (typeof web3 !== 'undefined') {
          App.web3Provider = web3.currentProvider;
          console.warn("Meata);
        }else{
          App.web3Provider = new Web3.providers.HttpProvider('https://localhost:7545');
        }
        web3 = new Web3(App.web3Provider);    return App.initContract();
      },
    
      initContract: function() {
        
        $.getJSON("Election.json",function(election){
          
          App.contracts.Election = TruffleContract(election);
          App.contracts.Election.setProvider(App.web3Provider);
    
          App.listenForEvents();      return App.reander();
        })
        
      },
    
      reander: function(){    var electionInstance; 
      var $loader = $("#loader);    var $content = $("#content);    $loader.show();    $content.hide();    //獲得賬號信息    web3.eth.getCoinbase(function(err,account){      if(err === null){        App.account = account;        $("#accountAddress).html("您當前的賬號: " + account);      }    });    //加載數據    App.contracts.Election.deployed().then(function(instance){      electionInstance = instance;      return electionInstance.candidateCount();    }).then(function(candidatesCount)
      {      var $candidatesResults = $("#candidatesResults);      $candidatesResults.empty();  
          var $cadidatesSelect = $("#cadidatesSelect);      $cadidatesSelect.empty();      for (var i=1;i<=candidatesCount;i++){        electionInstance.candidates(i).then(function(candidate)
      {          var id = candidate[0];          var name = candidate[1];
                var voteCount = candidate[2];
                         var candidateTemplate =
    "";          $candidatesResults.append(candidateTemplate);          //投票          var cadidateOption = "
    "+id+""+name+""+voteCount+"
    • initWeb3方法里面主要是對web3.js進行初始化,應該都能看懂。

    • initContract方法中

      • getJSON 方法是從本地讀取json文件,在json文件讀取成功后,再調用 Truffle 的 TruffleContract 方法進行合約初始化。

      • 初始化合約后,通過 setProvider 方法我這里理解是設置代理。


    其他的都是調取的web3.js提供的api,除了api之外我覺得最有必要解釋的是 App.contracts.Election.deployed().then(function(instance)... 這一串代碼,這是實例化Election合約后會調取后面then 里面的方法同時,把實例化的變量通過 instance 帶入到方法的參數里面。


    同時在then里面有返回了一個方法 return instance.vote(candidateId,{from: App.account}); 這個方法又會執行,執行完后,又把執行的結果待會給下一個 then ,依次類推,這貌似是es6的鏈式語法。


    如果我解釋得不太明白,可以留言。


    運行起來


    上面的代碼啥的一切準備就緒,現在只需要執行


    npm run dev


    項目就啟動了,由于需要和testrpc或者Ganache交互,所有我們需要用到 MetaMask 插件,所以得要用谷歌瀏覽器,打開我們的項目,同時需要MetaMask 插件連接到我們的測試環境。



    就能看到出來的效果了。


    如果對MetaMask不了解的,可以在網上查閱相關資料。這里我的理解是,在DAPP中MetaMask充當的是一個橋梁作用,當我我們需要用到簽名時,他會出現一個簽名的界面讓你確認,如下圖:



    其實就是一個輕錢包。


    來源:簡書 作者:_謙益

    版權申明:本內容來自于互聯網,屬第三方匯集推薦平臺。本文的版權歸原作者所有,文章言論不代表鏈門戶的觀點,鏈門戶不承擔任何法律責任。如有侵權請聯系QQ:3341927519進行反饋。
    相關新聞
    發表評論

    請先 注冊/登錄 后參與評論

      回頂部
    • <option id="cacee"><noscript id="cacee"></noscript></option>
    • <table id="cacee"><noscript id="cacee"></noscript></table>
    • <td id="cacee"></td>
    • <option id="cacee"></option>
    • <table id="cacee"></table>
    • <option id="cacee"><option id="cacee"></option></option>
    • <table id="cacee"><source id="cacee"></source></table><td id="cacee"><rt id="cacee"></rt></td>
      <option id="cacee"><option id="cacee"></option></option>
      妖精视频