编辑推荐: |
本文讲解以太坊,
区块链, Dapp, 以太坊hello world等希望对您有所帮助
本文来自于腾讯云社区,由火龙果软件Delores编辑、推荐。 |
|
指路牌
以太坊
区块链
Dapp
以太坊hello world
环境
windows 10 64bit
背景
准备接手一个IPFS+Ethereum的项目,先学习一下Ethereum,并尝试完成一个Hello World。
步骤
安装nvmnvm install 9.11.1
nvm use 9.11.1npm install ganache-cli
npm install web3@0.20.1
npm install solc@0.4.21
安装node 9.11.1 并切换环境
创建一个新的工作目录,并在命令行索引到该路径
安装ganche-cli、web3、solc
启动ganache-clinode_modules\.bin\ganache-cli
ganache-cli启动后输出如下
6. 使用Solidity创建Smart Contract,命名为:Voting.solpragma 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;
}}> Web3 = require('web3')
> web3 = new Web3 (new Web3.providers.HttpProvider ("http://localhost:8545"))
> web3.eth.accounts 输入以上最后一条命令后会 获取Ganache创建的10个帐号,如下 |
启动node交互控制台,依次输入以下命令
> code = fs.readFileSync ('Voting.sol').toString()
> solc = require('solc')
> compiledCode = solc.compile(code) |
全部完成会得到如下截图的输出,表示smart contract编译成功
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)下载web3.js文件,下载后放在工作根目录下。
由cdn不知什么原因不可用,所以直接下载源文件
在根目录下创建index.html文件,并粘贴以下代码,需要在截图标出处,更换成第8步自己部署的smart contract的address< !DOCTYPE html >
<html>
<head> <title>DApp</title>
<link href= 'https://fonts.googleapis.com/css?family =Open
Sans:400,700' rel='stylesheet' type='text/css'>
<link href= 'https://maxcdn.bootstrapcdn.com/bootstrap /3.3.7/css/bootstrap.min.css'
rel='stylesheet' type='text/css'> </head>
<body class="container"> <h1>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>James</td> <td id="candidate-1"></td>
</tr> <tr> <td>Norah</td>
<td id="candidate-2"></td>
</tr> <tr> <td>Jones</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="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> |
在浏览器打开index.html,输入Candidate中的人名后,点击Vote即可投票,投票后效果如下
每次点击投票,也都会生成一个新的区块,效果如下。
后记
以上步骤就完成了一个基于Ethereum的投票Dapp的完整搭建流程,整合个补全后步骤应该不会有坑的可以顺利搭建完成。
就像“hello world”的字面意思一样,0-1的过程是最艰难的,但是开了头,剩下的1-n也就会顺畅不少。
|