中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

區塊鏈 Hello World -- 基于以太坊的投票Dap

發布時間:2020-07-19 05:31:05 來源:網絡 閱讀:219 作者:wx5b3c8b549a762 欄目:建站服務器

指路牌

  • 以太坊
  • 區塊鏈
  • Dapp
  • 以太坊hello world

環境

windows 10 64bit

參考博客

youclavier -- 以太坊投票Dapp教程

背景

準備接手一個IPFS+Ethereum的項目,先學習一下Ethereum,并嘗試完成一個Hello World。

步驟

  1. 參考我另一片blog, 安裝nvm
  2. 安裝node 9.11.1 并切換環境
    nvm install 9.11.1
    nvm use 9.11.1
  3. 創建一個新的工作目錄,并在命令行索引到該路徑
  4. 安裝ganche-cli、web3、solc
    npm install ganache-cli
    npm install web3@0.20.1
    npm install solc@0.4.21       //此處原博客沒有版本,會安裝高于0.4的版本,會導致后續編譯smart contract編譯失敗 

    在安裝了ganache-cli與web3時,由于教程版本問題會出現報錯,但是不影響。

  5. 啟動ganache-cli
    node_modules\.bin\ganache-cli

    區塊鏈 Hello World -- 基于以太坊的投票Dap

  6. 使用Solidity創建Smart Contract,命名為:Voting.sol
    
    pragma solidity ^0.4.18; 

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;
}}

7. 啟動node交互控制臺,依次輸入以下命令

Web3 = require('web3')
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"))
web3.eth.accounts


 輸入以上最后一條命令后會獲取Ganache創建的10個帳號,如下

區塊鏈 Hello World -- 基于以太坊的投票Dap

> code = fs.readFileSync('Voting.sol').toString()
> solc = require('solc')
> compiledCode = solc.compile(code)

全部完成會得到如下截圖的輸出,表示smart contract編譯成功
區塊鏈 Hello World -- 基于以太坊的投票Dap
8.部署smart contract

> abi = JSON.parse(compiledCode.contracts[':Voting'].interface)
> VotingContract = web3.eth.contract(abi)
> byteCode = compiledCode.contracts[':Voting'].bytecode
> deployedContract = VotingContract.new(['James', 'Norah', 'Jones'],{data: byteCode, from: web3.eth.accounts[0], gas: 4700000})
> deployedContract.address

此時會獲取address,記下來后續會用到

contractInstance = VotingContract.at(deployedContract.address)
  1. 下載web3.js文件,下載后放在工作根目錄下。
    cdn不知什么原因不可用,所以直接下載源文件,鏈接如下
    web3.js 0.20.6
  2. 在根目錄下創建index.html文件,并粘貼以下代碼,需要在截圖標出處,更換成第8步自己部署的smart contract的address
    
    &lt;!DOCTYPE html&gt;
    &lt;html&gt;
    &lt;head&gt;
    &lt;title&gt;DApp&lt;/title&gt;
    &lt;link href='https://fonts.googleapis.com/css?family=Open Sans:400,700' rel='stylesheet' type='text/css'&gt;
    &lt;link  rel='stylesheet' type='text/css'&gt;
    &lt;/head&gt;
    &lt;body class="container"&gt;
    &lt;h2&gt;Voting Application&lt;/h2&gt;
    &lt;div class="table-responsive"&gt;
    &lt;table class="table table-bordered"&gt;
    &lt;thead&gt;
    &lt;tr&gt;
    &lt;th&gt;Candidate&lt;/th&gt;
    &lt;th&gt;Votes&lt;/th&gt;
    &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
    &lt;tr&gt;
    &lt;td&gt;James&lt;/td&gt;
    &lt;td id="candidate-1"&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
    &lt;td&gt;Norah&lt;/td&gt;
    &lt;td id="candidate-2"&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
    &lt;td&gt;Jones&lt;/td&gt;
    &lt;td id="candidate-3"&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;/tbody&gt;
    &lt;/table&gt;
    &lt;/div&gt;
    &lt;input type="text" id="candidate" /&gt;
    &lt;a href="#" onclick="voteForCandidate()" class="btn btn-primary"&gt;Vote&lt;/a&gt;
    &lt;/body&gt;
<script src="web3.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script>
<script language="javascript" type="text/javascript">
    web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
    abi = JSON.parse('[{"constant":false,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"totalVotesFor","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"validCandidate","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"votesReceived","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"x","type":"bytes32"}],"name":"bytes32ToString","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"candidateList","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"voteForCandidate","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"contractOwner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"inputs":[{"name":"candidateNames","type":"bytes32[]"}],"payable":false,"type":"constructor"}]')
    VotingContract = web3.eth.contract(abi);
    contractInstance = VotingContract.at('0x47f49b300eb86d972f91f103913376fb0a8e52e7');
    candidates = {"James": "candidate-1", "Norah": "candidate-2", "Jones": "candidate-3"}

    function voteForCandidate(candidate) {
        candidateName = $("#candidate").val();
        try {
            contractInstance.voteForCandidate(candidateName, {from: web3.eth.accounts[0]}, function() {
            let div_id = candidates[candidateName];
            $("#"+div_id).html(contractInstance.totalVotesFor.call(candidateName).toString());
        });
        } catch (err) {
        }
    }

    $(document).ready(function() {
        candidateNames = Object.keys(candidates);
        for (var i = 0; i < candidateNames.length; i++) {
            let name = candidateNames[i];
            let val = contractInstance.totalVotesFor.call(name).toString()
            $("#"+candidates[name]).html(val);
        }
    });
</script>

</html>


![更換address](https://user-images.githubusercontent.com/37465243/64078738-f976e400-cd10-11e9-82ef-20468a8e6ba5.png)

11. 在瀏覽器打開index.html,輸入Candidate中的人名后,點擊Vote即可投票,投票后效果如下
![](https://user-images.githubusercontent.com/37465243/64078736-f8de4d80-cd10-11e9-9e1a-173c812f2264.png)
每次點擊投票,也都會生成一個新的區塊,效果如下。
![](https://user-images.githubusercontent.com/37465243/64078737-f8de4d80-cd10-11e9-874c-d3e8570432fb.png)

## 后記
以上步驟就完成了一個基于Ethereum的投票Dapp的完整搭建流程,整合個補全后步驟應該不會有坑的可以順利搭建完成。

就像“hello world”的字面意思一樣,0-1的過程是最艱難的,但是開了頭,剩下的1-n也就會順暢不少。

####
***要獲取更多Haytham原創文章,請關注公眾號"許聚龍":***
![我的微信公眾號](https://user-images.githubusercontent.com/37465243/63688227-5b2ede00-c839-11e9-9aa9-2b461444f463.png)
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

康定县| 竹溪县| 岳阳县| 五原县| 当阳市| 红河县| 和政县| 临猗县| 城固县| 临湘市| 高阳县| 慈利县| 丹棱县| 苗栗县| 灵寿县| 瑞安市| 泗水县| 恩施市| 桑植县| 进贤县| 民权县| 仙居县| 潜山县| 柳林县| 彩票| 红河县| 丹棱县| 舞阳县| 瑞安市| 湾仔区| 渭源县| 阳西县| 巴彦淖尔市| 清水县| 明光市| 湟中县| 东山县| 阿图什市| 罗江县| 满城县| 政和县|