前面我们基于Embark Demo[1] 讲解了 Embark 框架,今天用于 Embark 来实实在在研发一个 DApp:从零研发研发一个投票DApp。之前我们也用于Truffle 研发过投票DApp[2],大家可以自行对比两个框架的好坏。通过本文可以自学到:1.用于 Embark 创立项目2.利用 EmbarkJS 与合约交互3.Embark 如果部署合约到主网(利用Infura节点)本文用于的 Embark 版本是 5.2.3创立Embark项目 embark new embark-election不会在当前目录下分解一个 embark-election 目录,并创立好了适当的项目框架文件:如: app/、contracts/、config/、embark.json等。
我们必须在对应的目录中,加到适当的构建。撰写合约在contracts/中加到合约Election.sol:pragma solidity ^0.6.0;contract Election {// Model a Candidatestruct Candidate {uint id;string name;uint voteCount;}mapping(address = bool) public voters;mapping(uint = Candidate) public candidates;// Store Candidates Countuint public candidatesCount;// voted eventevent votedEvent (uint indexed _candidateId);constructor () public {addCandidate("Tiny 熊");addCandidate("LearnBlockChain.cn");}function addCandidate (string memory _name) private {candidatesCount ++;candidates[candidatesCount] = Candidate(candidatesCount, _name, 0);}function vote (uint _candidateId) public {// require that they haven't voted beforerequire(!voters[msg.sender]);// require a valid candidaterequire(_candidateId0_candidateId = candidatesCount);// record that voter has votedvoters[msg.sender] = true;// update candidate vote Countcandidates[_candidateId].voteCount ++;// trigger voted eventemit votedEvent(_candidateId);}}之前有用于过Truffle研发过投票DApp[3],合约的代码几乎一样,就不出说明。Embark 合约编译器部署Embark 合约部署的配备在 config/contracts.js, 在 deploy 字段重新加入 Election 合约:deploy: { Election: { }}现在运营 embark run , Embark 不会自动编译器及部署Election.sol到 config/blockchain.js 配备的 development 网络。
embark run 等价 embark run development。blockchain.js 中 development 网络是用于 ganache-cli 启动的网络,其配备如下: development: {client: 'ganache-cli',clientConfig: { miningMode: 'dev'} }embark启动后,我们可以在 COCKPIT 或 DashBoard 看见Election.sol合约的部署日志,大约类似于下面:deploying Election with 351122 gas at the price of 1 Wei, estimated cost: 351122 Wei (txHash: 0x9da4dfb951149...d5c306dcabf300a4)Election deployed at 0x10C257c76Cd3Dc35cA2618c6137658bFD1fFCcfA using 346374 gas (txHash: 0x9da4dfb951149ea4...d5c306dcabf300a4)finished deploying contracts撰写前端代码Embark ArtifactsEmbark获取了一个 EmbarkJS的JavaScript库,来协助开发者和合约展开交互。在用于web3.js 时,和合约交互必须告诉合约的ABI及地址来创立JS环境中对应的合约对象,一般代码是这样的:// 必须ABI及地址创建对象var myContract = new web3.eth.Contract([...ABI...], '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe');Embark 在编译器部署后,每个合约不会分解一个对应的构件Artifact(可以在embarkArtifacts/contracts/ 目录下找的这些文件),我们可以必要用于 Artifact 分解的合约对象调用合约。
一个构件一般来说不会包括:合约的ABI、部署地址、启动代码及其他的配备数据。查阅一下Election.sol 对应的构件Election.js 代码就更容易解读:import EmbarkJS from '../embarkjs';let ElectionJSONConfig = {"contract_name":"Election","address":"0x10C257c76Cd3Dc35cA2618c6137658bFD1fFCcfA","code":"...", ... ,"abiDefinition":[...]};let Election = new EmbarkJS.Blockchain.Contract(ElectionJSONConfig);export default Election;Election.js 最后一行给定了一个与合约同名的JavaScript 对象,下面想到怎么用于这个对象。改动前端index.html在用于embark new embark-election创立项目时, 前端目录app/下分解了一个 index.html:html headtitleEmbark/titlelink href="http://www.qukuaiwang.com.cn/news/css/app.css"script src="http://www.qukuaiwang.com.cn/news/js/app.js"/script /head bodyh3Welcome to Embark!/h3 /body/html这里有一个地方必须留意一下,第5 6行引进了 css/app.css, js/app.js,而只不过app/下并没这两个文件,这两个文件只不过是按照 embark.json 配备的规程分解的。
embark.json 关于前端的配备如下: "app": {"http://www.qukuaiwang.com.cn/news/css/app.css": ["app/css/**"],"http://www.qukuaiwang.com.cn/news/js/app.js": ["app/js/index.js"],"images/": ["app/images/**"],"index.html": "app/index.html" },"http://www.qukuaiwang.com.cn/news/css/app.css": ["app/css/**"] 回应所有在app/css/目录下的文件不会被传输到 dist目录的 css/app.css ,app/js/index.js则不会编译器为js/app.js,其他的配备类似于。我猜测embark 这样统一 css 及 js代码,有可能是为了在IPFS之类的去中心化存储上采访一起更加便利,在IPFS上载整个目录时,不能以相对路径去采访资源。青睐facebook和我交流。
接下来改动前端部分的代码,主要是在index.html的body重新加入一个table表明候选人,以及重新加入一个投票板,代码如下(摘录):table theadtr th scope="col"#/th th scope="col"候选人/th th scope="col"得票数/th/tr /thead tbody /tbody/tabledivlabel for="candidatesSelect"自由选择候选人/labelselect/select/div前端,我们用于了 bootstrap css ,网卓新闻网,把文件拷贝到app/css目录下,接下来,想到关键的一步:前端如何与与合约交互。用于 Artifacts与合约交互EmbarkJS 相连 Web3创立项目时分解的app/js/index.js 分解了如下代码:import EmbarkJS from 'Embark/EmbarkJS';EmbarkJS.onReady((err) = { // You can execute contract calls after the connection});这段代码里,EmbarkJS为我们打算了一个onReady消息传递函数,这是因为EmbarkJS不会自动老大我们已完成与web3节点的相连与初始化,当这些准备就绪后(调用onReady),前端就可以和链展开交互了。大家或许不会奇怪EmbarkJS怎么告诉我们必须相连那个节点呢?只不过在config/contracts.js 有一个 dappConnection 配备项:dappConnection: [ "$EMBARK", "$WEB3", // 用于浏览器流经的web3, 如MetaMask等 "ws://localhost:8546", "http://localhost:8545"],$EMBARK : 是Embark在DApp和节点之前构建的一个代理,用于$EMBARK有几个益处:1.可以在config/blockchain.js 配备于DApp交互的账号 accounts。
2.可以更加友好关系的的看见交易记录。EmbarkJS 不会从上到下,依序尝试 dappConnection获取的相连,如果有一个可以相连上,就不会暂停尝试。提供合约数据图形界面当 EmbarkJS 环境打算 onReady后,就可以用于构件Election.js提供合约数据,如提供调用合约提供候选人数量:import EmbarkJS from 'Embark/EmbarkJS';import Election from '../../embarkArtifacts/contracts/Election.js';EmbarkJS.onReady((err) = {Election.methods.candidatesCount().call().then(count = console.log(" candidatesCount: " + count););});代码中必要用于构件给定的Election对象,调用合约方法 Election.methods.candidatesCount().call(), 调用合约方法与web3.js 完全一致。
理解了如何与合约交互,接下来图形界面就非常简单了,我们把代码整理下,分别定义3个函数: App.getAccount()、App.render()、App.onVote() 来提供当前账号(必须用来辨别哪些账号投过票)、界面图形、处置页面投标。EmbarkJS.onReady((err) = { App.getAccount(); App.render(); App.onVote();});App.getAccount() 的构建如下:import "./jquery.min.js"var App = { account: null, getAccount: function() {web3.eth.getCoinbase(function(err, account) { if (err === null) {App.account = account;console.log(account);$("#accountAddress").html("Your Account: " + account); }}) },}在代码中,我们必要用于了web3对象,就是因为EmbarkJS老大我们展开了web3的初始化。另外,我们引进jquery.min.js 来展开UI界面的图形。App.render() 的构建(主干)如下:render: function () {Election.methods.candidatesCount().call().then( candidatesCount = {var candidatesResults = $("#candidatesResults");var candidatesSelect = $('#candidatesSelect');for (var i = 1; i = candidatesCount; i++) { Election.methods.candidates(i).call().then(function(candidate) {var id = candidate[0];var name = candidate[1];var voteCount = candidate[2];// Render candidate Resultvar candidateTemplate = "trth" + id + "/thtd" + name + "/tdtd" + voteCount + "/td/tr";candidatesResults.append(candidateTemplate);// Render candidate ballot optionvar candidateOption = "option value='" + id + "' " + name + "/ option";candidatesSelect.append(candidateOption); });} }); }App.onVote() 的构建(主干)如下: onVote: function() {$("#vote").click(function(e){ var candidateId = $('#candidatesSelect').val(); Election.methods.vote(candidateId).send() .then(function(result) {App.render(); }).catch(function(err) {console.。
本文关键词:酷游ku官网
本文来源:酷游ku官网-www.andymdavidson.com