以太坊协议将尽可能简单,即便以某些数据存储和时间上的低效为代价。一个普通的程序员也能够完美地去实现完整的开发说明。这将最终有助于降低任何特殊个人或精英团体可能对协议的影响并且推进以太坊作为对所有人开放的协议的应用前景。添加复杂性的优化将不会被接受,除非它们提供了非常根本性的益处。
开发以太坊dapp首先可以用官方框架安装truffle
npm install -g truffle1环境依赖
NodeJS v8.9.4 或 之后的版本
Windows, Linux or Mac OS X
安装过程中可能遇到问题解决办法如下:
安装命令:sudo npm install -g truffle 安装过程中可能遇到问题解决: sudo npm install -g nsudo n stable 安装完成检车是否成功:truffle -v
接下来说一下怎么使用truffle 开发属于自己的dapp
一:创建相关文件夹下载模板
1.cd Voting2.truffle unbox webpack12二:创建合约
cd contractsrm meta.sol Lib.solvim Voting把写好的代码拷贝到其中
三:修改模板配置文件(truffle\voting\webpack-box\migrations\2_deploy_contracts.js)
//const ConvertLib = artifacts.require("ConvertLib");//const MetaCoin = artifacts.require("MetaCoin");const Voting = artifacts.require("Voting");
module.exports = function(deployer) { //deployer.deploy(ConvertLib); //deployer.link(ConvertLib, MetaCoin); //deployer.deploy(MetaCoin); deployer.deploy(Voting,["0x4100000000000000000000000000000000000000000000000000000000000000","0x4200000000000000000000000000000000000000000000000000000000000000"]);};
四:编译合约
cd truffle\voting\webpack-boxtruffle compile
五:部署合约启动ganache-cli(如果失败,则重新安装npm install -g ganache-cli)注意:启动以太坊模拟区块链,默认端口8545
/*** Use this file to configure your truffle project. It's seeded with some* common settings for different networks and features like migrations,* compilation and testing. Uncomment the ones you need or modify* them to suit your project as necessary.** More information about configuration can be found at:** truffleframework.com/docs/advanced/configuration** To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider)* to sign your transactions before they're sent to a remote public node. Infura accounts* are available for free at: infura.io/register.** You'll also need a mnemonic - the twelve word phrase the wallet uses to generate* public/private key pairs. If you're publishing your code to GitHub make sure you load this* phrase from a file you've .gitignored so it doesn't accidentally become public.**/
// const HDWallet = require('truffle-hdwallet-provider');// const infuraKey = "fj4jll3k.....";//// const fs = require('fs');// const mnemonic = fs.readFileSync(".secret").toString().trim();
module.exports = { /** * Networks define how you connect to your ethereum client and let you set the * defaults web3 uses to send transactions. If you don't specify one truffle * will spin up a development blockchain for you on port 9545 when you * run `develop` or `test`. You can ask a truffle command to use a specific * network from the command line, e.g * * $ truffle test --network <network-name> */
networks: { // Useful for testing. The `development` name is special - truffle uses it by default // if it's defined here and no other network is specified at the command line. // You should run a client (like ganache-cli, geth or parity) in a separate terminal // tab if you use this network and you must also set the `host`, `port` and `network_id` // options below to some value. // development: { host: "localhost", // Localhost (default: none) port: 8545, // Standard Ethereum port (default: none) network_id: "*", // Any network (default: none) }, //develop: { // port: 8545 //},
// Another network with more advanced options... // advanced: { // port: 8777, // Custom port // network_id: 1342, // Custom network // gas: 8500000, // Gas sent with each transaction (default: ~6700000) // gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei) // from: <address>, // Account to send txs from (default: accounts[0]) // websockets: true // Enable EventEmitter interface for web3 (default: false) // },
// Useful for deploying to a public network. // NB: It's important to wrap the provider as a function. // ropsten: { // provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`), // network_id: 3, // Ropsten's id // gas: 5500000, // Ropsten has a lower block limit than mainnet // confirmations: 2, // # of confs to wait between deployments. (default: 0) // timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50) // skipDryRun: true // Skip dry run before migrations? (default: false for public nets ) // },
// Useful for private networks // private: { // provider: () => new HDWalletProvider(mnemonic, `https://network.io`), // network_id: 2111, // This network is yours, in the cloud. // production: true // Treats this network as if it was a public net. (default: false) // } },
// Set default mocha options here, use special reporters etc. mocha: { // timeout: 100000 },
// Configure your compilers compilers: { solc: { // version: "0.5.1", // Fetch exact version from solc-bin (default: truffle's version) // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) // settings: { // See the solidity docs for advice about optimization and evmVersion // optimizer: { // enabled: false, // runs: 200 // }, // evmVersion: "byzantium" // } } }}
部署
truffle migrate1部署完检验方法打开truffle console控制台
truffle consolelet instance = await Voting.deployed()instance
六:修改前端页面
<!DOCTYPE html><html> <head> <title>MyVoting 投票DAPP测试</title> </head> <style> input { display: block; margin-bottom: 12px; } </style> <body> <h1>MyVoting 投票DAPP测试</h1>
<p>Jerry : <strong id ="Jerry">loding...</strong> tickets</p><p>Amy : <strong id ="Amy">loding...</strong> tickets</p><input type="text" id="candidate"/><button onclick="App.voteForCandidate()">vote</button> <script src="index.js"></script> </body></html>七:修改index.js
import Web3 from "web3";import votingArtifact from "../../build/contracts/Voting.json";
const aInBytes32="0x4100000000000000000000000000000000000000000000000000000000000000";const bInBytes32="0x4200000000000000000000000000000000000000000000000000000000000000";
const App = { web3: null, account: null, voting: null,
start: async function() { const { web3 } = this;
try { // get contract instance const networkId = await web3.eth.net.getId(); const deployedNetwork = votingArtifact.networks[networkId]; this.voting = new web3.eth.Contract( votingArtifact.abi, deployedNetwork.address, ); // get accounts const accounts = await web3.eth.getAccounts(); this.account = accounts[0]; //this.refreshBalance(); this.ready(); } catch (error) { console.error("Could not connect to contract or chain."); } }, refresh : async function (id,nameInBytes32){ const {LookForCandidate} =this.voting.methods; const tickets = await LookForCandidate(nameInBytes32).call(); const element = document.getElementById(id); element.innerHTML = tickets.toString(); }, ready: async function(){ try{ this.refresh("Jerry",aInBytes32); this.refresh("Amy",bInBytes32); }catch(err){ console.log(err) } },voteForCandidate: async function(){try{ const {voteForCandidate} = this.voting.methods; const candidateName = document.getElementById("candidate").value; console.log(candidateName); if(candidateName == "Jerry"){ await voteForCandidate(aInBytes32).send({from:this.account}); this.refresh("Jerry",aInBytes32); }else if(candidateName == "Amy"){ await voteForCandidate(bInBytes32).send({from:this.account}); this.refresh("Amy",bInBytes32); }}catch(err){ console.info(err)}}};
window.App = App;
window.addEventListener("load", function() { if (window.ethereum) { // use MetaMask's provider App.web3 = new Web3(window.ethereum); window.ethereum.enable(); // get permission to access accounts } else { console.warn( "No web3 detected. Falling back to http://127.0.0.1:8545. You should remove this fallback when you deploy live", ); // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail) App.web3 = new Web3( new Web3.providers.HttpProvider("http://127.0.0.1:8545"), ); }
App.start();});
八:运行即可
npm run dev1浏览器输入对应网站
以太坊是一个平台,它上面提供各种模块让用户来搭建应用,如果将搭建应用比作造房子,那么以太坊就提供了墙面、屋顶、地板等模块,用户只需像搭积木一样把房子搭起来,因此在以太坊上建立应用的成本和速度都大大改善。具体来说,以太坊通过一套图灵完备的脚本语言(Ethereum Virtual Machinecode,简称EVM语言)来建立应用,它类似于汇编语言。我们知道,直接用汇编语言编程是非常痛苦的,但以太坊里的编程并不需要直接使用EVM语言,而是类似C语言、Python、Lisp等高级语言,再通过编译器转成EVM语言。