├── README.md ├── demo.js ├── index.html └── index.js /README.md: -------------------------------------------------------------------------------- 1 | # ethereum 2 | 以太坊DApp入门教程 3 | v1.0 4 | 5 | 本课程面向初学者,内容涵盖以太坊去中心化应用开发相关的诸多概念,如区块链、ganache仿真器、Solidity语言、solc编译器、web3js库、通证(代币)发行等,并将手把手地教大家如何构建一个基于以太坊的完整去中心化应用 —— 区块链投票系统。 6 | 7 | [http://xc.hubwiz.com/course/5a952991adb3847553d205d1](http://xc.hubwiz.com/course/5a952991adb3847553d205d1?affid=github20180308) 8 | 9 | * 一、初识以太坊 10 | 11 | * 1.1 课程概述 12 | * 1.2 课程项目简介 13 | * 1.3 开发迭代 14 | * 1.4 初识区块链 15 | * 1.5 C/S架构 —— 以服务器为中心 16 | * 1.6 去中心化架构 —— 彼此平等的节点 17 | * 1.7 以太坊 —— 世界计算机 18 | 19 | * 二、使用NodeJS开发DApp 20 | 21 | * 2.1 开发流程概述 22 | * 2.2 节点仿真器 23 | * 2.3 投票合约设计 24 | * 2.4 合约代码开发 25 | * 2.5 合约代码编译 26 | * 2.6 投票合约部署 27 | * 2.7 控制台交互 28 | * 2.8 网页交互 29 | * 2.9 课程小结 30 | 31 | * 三、使用Truffle开发DApp 32 | 33 | * 3.1 内容概述 34 | * 3.2 初始化项目 35 | * 3.3 升级投票应用代码 36 | * 3.4 迁移脚本 37 | * 3.5 合约的编译与部署 38 | * 3.6 控制台和网页交互 39 | * 3.7 总结 40 | 41 | * 四、使用数字代币/通证 42 | * 4.1 概述 43 | * 4.2 加权投票应用 44 | * 4.3 实现思路 45 | * 4.4 加权投票合约设计 46 | * 4.5 合约实现 —— 购买通证 47 | * 4.6 合约实现 —— 加权投票 48 | * 4.7 合约实现 —— 转账 49 | * 4.8 合约部署 50 | * 4.9 控制台交互 51 | * 4.10 网页交互 52 | -------------------------------------------------------------------------------- /demo.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | const Web3 = require('web3') 3 | const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')) 4 | console.log(web3.eth.accounts) 5 | 6 | const fs = require('fs') 7 | const solc = require('solc') 8 | const code = fs.readFileSync('Voting.sol').toString() 9 | console.log(code) 10 | const compiledCode = solc.compile(code) 11 | console.log(compiledCode) 12 | 13 | const abiDefinition = JSON.parse(compiledCode.contracts[':Voting'].interface) 14 | console.log(abiDefinition) 15 | const VotingContract = web3.eth.contract(abiDefinition) 16 | const byteCode = compiledCode.contracts[':Voting'].bytecode 17 | const deployedContract = VotingContract.new(['Rama','Nick','Jose'],{data:byteCode,from:web3.eth.accounts[0],gas:4700000}) 18 | setTimeout(()=>{ 19 | console.log(deployedContract.address) 20 | const contractInstance = VotingContract.at(deployedContract.address) 21 | 22 | console.log(contractInstance.totalVotesFor.call('Rama')) 23 | contractInstance.voteForCandidate('Rama',{from:web3.eth.accounts[0]}) 24 | contractInstance.voteForCandidate('Rama',{from:web3.eth.accounts[0]}) 25 | console.log(contractInstance.totalVotesFor.call('Rama')) 26 | },1000) 27 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hello World DApp 5 | 6 | 7 | 8 | 9 |

A Simple Hello World Voting Application

10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
CandidateVotes
Rama
Nick
Jose
33 |
34 | 35 | Vote 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | web3 = new Web3(new Web3.providers.HttpProvider("http://192.168.1.234:8545")); 2 | 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"}]') 3 | VotingContract = web3.eth.contract(abi); 4 | contractInstance = VotingContract.at('0x8ba5f28507becccfce3fb1b20658c1221dd7b512'); 5 | candidates = {"Rama": "candidate-1", "Nick": "candidate-2", "Jose": "candidate-3"} 6 | 7 | function voteForCandidate(candidate) { 8 | candidateName = $("#candidate").val(); 9 | try { 10 | contractInstance.voteForCandidate(candidateName, {from: web3.eth.accounts[0]}, function() { 11 | let div_id = candidates[candidateName]; 12 | $("#"+div_id).html(contractInstance.totalVotesFor.call(candidateName).toString()); 13 | }); 14 | } catch (err) { 15 | } 16 | } 17 | 18 | $(document).ready(function() { 19 | candidateNames = Object.keys(candidates); 20 | for (var i = 0; i < candidateNames.length; i++) { 21 | let name = candidateNames[i]; 22 | let val = contractInstance.totalVotesFor.call(name).toString() 23 | $("#"+candidates[name]).html(val); 24 | } 25 | }); 26 | --------------------------------------------------------------------------------