Dapp簡單的投票小例子

準備工作

相關命令

  • mkdir simple_voting_dapp //創建文件夾
  • cd simple_voting_dapp //進入文件夾
  • npm init? //初始化npm包管理文件,輸入ls 可以看到創建的package.json文件
  • npm intsall web3@0.20.1 //安裝web3
  • npm install solc@0.4.25? ?//安裝solc
  • npm install -g ganache-cli? ?//安裝ganache-cli??參考文檔?
  • 輸入ganache-cli 啟動,出現如下界面,表示啟動成功,列出10個賬戶以及各自的秘鑰,每個賬戶都有100以太,這個類似dev私鏈的模式

Solidity合約

合約內容

  • 構造函數,用來初始化一些候選者
  • 用來投票的方法(對于票數加 1)
  • 返回候選者獲得的總的票數的方法

合約代碼

pragma solidity ^0.4.22;contract Voting{mapping (bytes32 => uint8)public votesReceived;bytes32[] public candidateList;constructor(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;}}
}

合約編譯

編譯前測試

  • 查看安裝的版本 npm list web3;npm list solc
  • node 進入命令行
  • var Web3 =? require('web3')
  • var web3 = new Web3(new Web3.providers.HttpProvider('Http://localhost:8545'))//這個需要和ganache-cli設置的一致,才可以連接上。
  • 使用web3.isConnected()//查看是否連接上,此時需要將ganache-cli啟動
  • 使用命令web3.eth.accounts,獲取目前的賬戶,需要注意每次啟動ganache-cli都會產生全新的賬號和秘鑰

正式開始編譯

  • var solc = require('solc')
  • 輸入solc. 查看可以使用的命令
  • var sourceCode = fs.readFileSync('Voting.sol').toString()? //需要注意,必須給與文件讀取權限
  • 輸入sourceCode 可以查看編碼文件
  • var compiledCode = solc.compile(sourceCode)? //這個就是正式的編譯過程
  • 輸入compiledCode可以查看字節碼文件,編譯結果如下圖所示

  • 這是一個js對象,最關鍵的是bytecode(字節碼)和interface接口(ABI),這兩個文件是部署合約最關鍵的文件
  • 部署合約 var abi = JSON.parse(compiledCode.contracts[':Voting'].interface);? ? 輸入abi進行驗證,是否取到正確的值,JSON.parse是為了Json格式化代碼
  • var byteCode = compiledCode.contracts[':Voting'].bytecode 取到字節碼? ? ?其中:Voting是合約名稱
  • 創建合約對象 var VotingContract = web3.eth.contract(abi)
  • var deployTxObj = {data:byteCode,from:web3.eth.accounts[0],gas:30000000}? 定義一筆交易
  • 定義合約實例 var contractInstance = VotingContract.new(["Alice","Bob","Cary"],deployTxObj);
  • contractInstance = VotingContract.new(["Alice","Bob","Cary"],{data:byteCode,from:web3.eth.accounts[0],gas:5000000});
  • 上面這一條命令是 定義合約實例 和 定義一筆交易的結合體,如果分開,有可能會報錯
  • 取到合約實例的地址 contractInstance.address? 這就將合約部署在區塊鏈上,這個區塊鏈是本地起的ganache-cli模擬區塊鏈
  • contractInstance.vote("Alice",{from:web3.eth.accounts[0]})? 賬號0給Alice投出一票
  • contractINstance.totalVotesFor("Alice").toString()? 查看Alice的總共的票數
  • contractINstance.totalVotesFor.call("Alice").toString() 查看
  • contractInstance.vote.sendTransaction("Alice",{from:web3.eth.accounts[0]})?

頁面交互

頁面 index.html

<!DOCTYPE html>
<html><head><title>Voting DApp</title><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 Voting Application</h1><div class="table-responsive"><table class="table table-bordered"><thead><tr><th>Candidate</th><th>Votes</th></tr></thead><tbody><tr><td>Alice</td><td id="candidate-1"></td></tr><tr><td>Bob</td><td id="candidate-2"></td></tr><tr><td>Cary</td><td id="candidate-3"></td></tr></tbody></table></div><input type="text" id="candidate" /><a href="#" onclick="voteForCandidate()" class="btn btn-primary">Vote</a></body><script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js"></script><script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script><script src="./index.js"></script></html>

注意

  • 不再需要引入web3對象,因為頁面里面就包含了web3對象,https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js,打開這個鏈接之后,在頁面的最下面會顯示,

index.js

var web3 = new Web3(new Web3.providers.HttpProvider("Http://localhost:8545"));
var abi = JSON.parse('[{"constant":true,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"totalVotesFor","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"validCandidate","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"votesReceived","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"candidateList","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"voteForCandidate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"candidateNames","type":"bytes32[]"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]');
// var contractAddr = "0x3577f4d4902f4766753056468bd08ef68df6c623";
var VotingContract = new web3.eth.Contract(abi); 
// var contractInstance =new web3.eth.Contract(abi,contractAddr);
// contractInstance = VotingContract.at(contractAddr);
var contractInstance = VotingContract.at('0x3577f4d4902f4766753056468bd08ef68df6c623');
var candidates = {"Alice":"candidate-1","Bob":"candidate-2","Cary":"candidate-3"
};
function voteForCandidate(){let candidateName = $("#candidate").val();try{contractInstance.voteForCandidate(candidateName),{from:web3.eth.accounts[0]},(err,res)=>{if(err)console.log("Error:",err);else{let div_id = candidates[candidateName];let count = contractInstance.totalVotesFor(candidateName).toString();$("#" + id).html(count);}}}catch(err){}
};$(document).ready(function(){candidateNames = Object.keys(candidates);for(let i=0;i<candidateNames.length;i++){let name = candidateNames[i];let val = contractInstance.totalVotesFor.call(name).toString();$("#" + candidates[name]).html(val);}
});

報錯

無解

  • at無法使用
  • 如果使用 var contractInstance =new web3.eth.Contract(abi,contractAddr);避免了at,但是無法使用call回調函數,依然報錯

部署服務

server.js

  • 異步的方式啟動,同步的會報錯
var http = require('http');
var fs = require('fs');
var url = require('url');http.createServer(function(req,res){var pathName = url.parse(req.url).pathname;console.log("Request for:"+pathName + "received.");fs.readFile(pathName.substr(1),function(err,data){if(err){console.log(err);res.writeHead(400,{'Content-Type':"text/html"});}else{res.writeHead(200,{'Content-Type':"text/html"});res.write(data.toString());}res.end();});
}).listen(8888);
  • 使用命令 node server.js啟動服務器
  • 瀏覽器輸入 http://127.0.0.1:8888/index.html 查看

  • 如果報錯 沒有favicon.ico? 直接創建一個就好,這個是圖標文件

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/447147.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/447147.shtml
英文地址,請注明出處:http://en.pswp.cn/news/447147.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用mocha進行測試 區塊鏈

mocha安裝 npm install mocha --save-dev mocha簡介 mocha是一個JavaScript的單元測試的框架&#xff0c;既可以運行在瀏覽器環境中&#xff0c;也可以運行在node.js環境中&#xff0c;只需要編寫測試用例&#xff0c;mocha就會將測試自動的運行&#xff0c;并且給出測試的結…

Linux學習筆記(六)

參考書籍&#xff1a;linux就該這么學 6.存儲結構與磁盤劃分 6.1 文件系統與數據資料 6.2 掛載硬件設備 6.2.1 mount 命令用于掛載文件系統 6.2.2 umount 命令用于撤銷已經掛載的設備文件 6.3 添加硬盤 6.3.1 fdisk 命令用于管理磁盤分區 6.3.2 用于查看文件數據占用量的 du 命…

實現Linux系統外部和容器內部的文件傳輸

主機和容器之間進行文件傳輸&#xff0c;需要使用容器的ID即可 獲取方法如下 輸入指令 docker ps -a只需要CONTAINER ID傳輸命令 docker cp 本地文件路徑 容器ID:容器的路徑將文件從容器拷貝到本地的原理是一致的&#xff0c;只需要將對應路徑的位置進行更換即可

Linux學習筆記(五)

參考書籍&#xff1a;linux就該這么學 5 用戶身份與文件權限 5.1 用戶身份與能力 強烈推薦大家在學習時使用 root 管理員權限&#xff01;因為在 Linux 的學習過程中如果使用普通用戶身份進行操作&#xff0c;則在配置服務之后出現錯誤時很難判斷是系統自身的問題還是因為權限不…

清除Docker的占用空間問題

使用命令查看磁盤的空間 docker system df &#xff0c;類似于Linux的df命令&#xff0c;用于查看Docker使用的磁盤空間Docker鏡像占據了4.789GBDocker容器占據了348BDocker數據卷占據了0B 執行刪除命令 docker system prune命令可以用于清理磁盤&#xff0c;刪除關閉的容器、…

集訓01-03 (c++實現)

#include<bits/stdc.h>與using namespace std;在第一第二行加上就行&#xff0c;無需了解 cin cout endl為c的輸入&#xff0c;輸出與換行符 Istringsteam 是string流,用來string轉換為int 五個函數&#xff08;需要稍微了解c迭代器&#xff0c;lambda(類似函數)&#xf…

區塊鏈的完整流程 自動化執行代碼

通過npm script機制&#xff0c; 在package.json文件中&#xff0c;輸入對應的代碼&#xff0c;就可以自動化執行相關的函數使用npm run test執行package.json中的內容&#xff0c;因為package.json包含test&#xff0c;所以可行&#xff0c;但是使用npm run compile會報錯

集訓04-06 (c++實現)

極力推薦《算法筆記》這本書&#xff01;&#xff01;&#xff01; 極力推薦《算法筆記》這本書&#xff01;&#xff01;&#xff01; 極力推薦《算法筆記》這本書&#xff01;&#xff01;&#xff01; &#xff08;重要的事情說三遍&#xff09; 數據結構和算法講的很好&…

數字簽名和數字信封之間的介紹

介紹 公鑰密碼體制在實際應用中包含數字簽名和數字信封兩種方式 數字簽名 指用戶用自己的【私鑰】對原始數據的哈希摘要進行加密所得的數據。數字簽名定義兩種互補的運算&#xff1a;一個用于簽名&#xff0c;另一個用于驗證。"私鑰簽名,公鑰驗證"簽名&#xff1a;…

Linux學習筆記(三)

參考書籍&#xff1a;Linux就該怎么學 3 管道符、重定向與環境變量 3.1.1 輸入輸出重定向 ? 標準輸入重定向&#xff08;STDIN&#xff0c;文件描述符為 0&#xff09;&#xff1a;默認從鍵盤輸入&#xff0c;也可從其他文件或命令中輸入。 ? 標準輸出重定向&#xff08;STDO…

windows版本的clion軟件除了使用wsl配置Ubuntu子系統外,還可以使用MinGW-w64來配置gcc和g++

主要內容 MinGW-w64安裝CMake安裝環境配置參考鏈接 MinGW-w64安裝配置 安裝配置分為在線版本和離線版本&#xff0c;推薦使用離線版本&#xff0c;因為在線版本很慢&#xff0c;需要插入網線進行操作參考鏈接 這個是百度云下載地址&#xff0c;相對于從官網下載速度稍微快一些…

python學習路線

自用 Task1: 如果對一個列表&#xff0c;既要遍歷索引又要遍歷元素時&#xff0c;首先可以這樣寫&#xff1a; list1 ["這", "是", "一個", "測試"] for i in range (len(list1)):print i ,list1[i]#上述方法有些累贅&#xff0c…

解決使用MinGW編譯C++代碼報cannot find -lxxxx的問題

報錯的截圖如下面所示 我一開始使用target_link_libraries(ThreadTest libsdf_core.dll)這條命令來將dll庫文件和項目文件關聯起來&#xff0c;但是解決不了問題也嘗試在編譯代碼的環境時候&#xff0c;將dll庫文件的絕對路徑加入到編譯環境中&#xff0c;但是也沒有用解決辦法…

Linux搭建深度學習環境使用指南

本文檔歸納不收悉的linux知識點&#xff0c;自用 終端美化&#xff1a;https://zhuanlan.zhihu.com/p/37195261&#xff08;unix終端通用&#xff09; 基礎linux命令&#xff1a;https://blog.csdn.net/q357010621/article/details/80248611 shell是什么&#xff1f;shell是一…

CLion 輸出遇到亂碼解決辦法,GBK和utf-8的轉換

具體操作 File -> Settings -> Default Settings -> Editor -> File Encodings:Global Encoding: UTF-8Project Encoding : UTF-8Default encoding for properties files: UTF-8 圖片展示 然后&#xff0c;在main.cpp右下角選擇語言編碼格式為GBK&#xff0c;在彈…

Vim使用方法歸納

編輯模式i 0 &#xff1a;光標移至行首d0 : 刪除到行首$ &#xff1a;光標移至行尾D/d$ : 刪除到行尾dd &#xff1a; 刪除當前行yy/nyy : 復制當前行/復制n行p/P &#xff1a; 粘貼&#xff08;vim中刪除是剪切&#xff0c;可以刪除后用p粘貼&#xff09;u &#xff1a; 撤回…

區塊鏈中涉及到密碼學的場景

區塊鏈中涉及到密碼學的場景 共識算法&#xff08;Consensus algorithm&#xff09;交易簽名&#xff08;Signing transaction)第二層網絡如何在第一層網絡中驗證&#xff08;Layer2’s verification on Layer1&#xff09;驗證跨鏈交易&#xff08;Verifying the cross chain…

epoll 轉kqueue的用法介紹和實例 實現跨平臺Macos

網上關于kqueue的博客很少 我來補充一個例子echo 的例子 #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include<stdio.h> #include<arpa/inet.h> #include<sys/event.…

區塊鏈中的密碼學,使用ABE結合區塊鏈

ABE 密碼學&#xff0c;以及與區塊鏈結合的價值 背景 區塊鏈技術具備篡改難度高、使用成本低、分布式的優點&#xff0c;本應成為各行各業的重要助力。但是由于鏈上參與方擔心自己的核心數據外泄&#xff0c;不愿將自己的核心數據上鏈&#xff0c;這個原因成為阻止區塊鏈落地…

VMware虛擬機安裝Ubuntu系統教程

所使用的文件如下&#xff1a; VMware Workstation 17 Pro ubuntu-22.04.3-desktop-amd64.iso 一、ubuntu 命名規則及各版本一覽表 1.ubuntu 命名規則&#xff1a; 例如&#xff1a;ubuntu 16.04 LTS 是長期維護版本&#xff1b;ubuntu 17.04 是新特性版本 前兩位數字為發…