两个简单的DApp, 宠物商店+投票
2018-08-19 本文已影响23人
rajs20222007
0x1 宠物商店
合约分析
宠物商店的合约内容如下, 其Dapp实现的是在宠物商店提供十六个宠物, 领养者可以选择一个进行领取. 合约使用solidity
pragma solidity ^ 0.4.18;
contract Adoption {
address[16] public adopters;
function adopt(uint petId) public returns(uint) {
require(petId >= 0 && petId <= 15);
adopters[petId] = msg.sender;
return petId;
}
function getAdopters() public view returns(address[16]) {
return adopters;
}
}
<code>Adoption</code>就是合约名.
<code>address[16]</code>保存了领取宠物的用户地址, 16个宠物对应了十六个领取地址.
function adopt(uint petId) public returns(uint) {
//先判断宠物id是否在0~15, 宠物商店只提供16种宠物
require(petId >= 0 && petId <= 15);
//领养人的地址存储到对应的宠物领养位置
//msg.sender是发起此方法的用户, 也就是领养用户发起的消息中的发起者
adopters[petId] = msg.sender;
//返回领取成功的宠物id
return petId;
}
<code>getAdopters</code>方法获取所有领养人.
宠物商店Web3
/scr/js目录下app.js文件内容如下:
App = {
web3Provider: null,
contracts: {},
init: function() {
// 加载宠物和其详细信息
$.getJSON('../pets.json', function(data) {
var petsRow = $('#petsRow');
var petTemplate = $('#petTemplate');
for (i = 0; i < data.length; i ++) {
petTemplate.find('.panel-title').text(data[i].name);
petTemplate.find('img').attr('src', data[i].picture);
petTemplate.find('.pet-breed').text(data[i].breed);
petTemplate.find('.pet-age').text(data[i].age);
petTemplate.find('.pet-location').text(data[i].location);
petTemplate.find('.btn-adopt').attr('data-id', data[i].id);
petsRow.append(petTemplate.html());
}
});
//返回加载后的实例
return App.initWeb3();
},
initWeb3: function() {
//如果有注入的web3, 则使用注入的web3
if (typeof web3 !== 'undefined') {
App.web3Provider = web3.currentProvider;
} else {
//如果没有注入的web3示例, 则在本地端口创建
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:8545');
}
web3 = new Web3(App.web3Provider);
return App.initContract();
},
initContract: function() {
$.getJSON('Adoption.json', function(data) {
//用Adoption.json数据创建一个可交互的TruffleContract合约实例。
var AdoptionArtifact = data;
App.contracts.Adoption = TruffleContract(AdoptionArtifact);
return App.markAdopted();
});
return App.bindEvents();
},
bindEvents: function() {
$(document).on('click', '.btn-adopt', App.handleAdopt);
},
markAdopted: function(adopters, account) {
var adoptionInstance;
App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance;
// 调用合约的getAdopters(), 用call读取信息不用消耗gas
return adoptionInstance.getAdopters.call();
}).then(function(adopters) {
for (i = 0; i < adopters.length; i++) {
if (adopters[i] !== '0x0000000000000000000000000000000000000000') {
$('.panel-pet').eq(i).find('button').text('Success').attr('disabled', true);
}
}
}).catch(function(err) {
console.log(err.message);
});
},
handleAdopt: function(event) {
event.preventDefault();
var petId = parseInt($(event.target).data('id'));
var adoptionInstance;
// 获取用户账号
web3.eth.getAccounts(function(error, accounts) {
if (error) {
console.log(error);
}
var account = accounts[0];
App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance;
// 发送交易领养宠物
return adoptionInstance.adopt(petId, {from: account});
}).then(function(result) {
return App.markAdopted();
}).catch(function(err) {
console.log(err.message);
});
});
}
};
$(function() {
$(window).load(function() {
App.init();
});
});
0x2 投票
合约分析
投票Dapp实现了一个对候选人进行投票的系统.
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;
}
}
投票Web3
/scr/js目录下app.js文件内容如下:
App = {
web3Provider: null,
contracts: {},
account: '0x0'
init: function() {
return App.initWeb3();
},
initWeb3: function() {
if (typeof web3 !== 'undefined') {
App.web3Provider = web3.currentProvider;
console.warn("Meata");
} else {
App.web3Provider = new Web3.providers.HttpProvider('https://localhost:7545');
}
web3 = new Web3(App.web3Provider);
return App.initContract();
},
initContract: function() {
$.getJSON("Election.json",function(election){
App.contracts.Election = TruffleContract(election);
App.contracts.Election.setProvider(App.web3Provider);
App.listenForEvents();
return App.reander();
})
},
reander: function(){
var electionInstance;
var $loader = $("#loader");
var $content = $("#content");
$loader.show();
$content.hide(); //获得账号信息
web3.eth.getCoinbase(function(err,account){
if(err === null){
App.account = account;
$("#accountAddress").html("您当前的账号: " + account);
}
});
//加载数据
App.contracts.Election.deployed().then(function(instance){
electionInstance = instance;
return electionInstance.candidateCount();
}).then(function(candidatesCount){
var $candidatesResults = $("#candidatesResults");
$candidatesResults.empty();
var $cadidatesSelect = $("#cadidatesSelect");
$cadidatesSelect.empty();
for (var i=1;i<=candidatesCount;i++){
electionInstance.candidates(i).then(function(candidate){
var id = candidate[0];
var name = candidate[1];
var voteCount = candidate[2];
var candidateTemplate = "<tr><th>"+id+"</th><td>"+name+"</td><td>"+voteCount+"</td></tr>";
$candidatesResults.append(candidateTemplate); //投票
var cadidateOption = "<option value='"+id+"'>"+name+"</option>";
$cadidatesSelect.append(cadidateOption);
});
}
return electionInstance.voters(App.account);
}).then(function(hasVoted){
if(hasVoted){
$('form').hide();
}
$loader.hide();
$content.show();
}).catch(function(err){
console.warn(err);
});
},
//投票
castVote: function(){
var $loader = $("#loader");
var $content = $("#content");
var candidateId = $('#cadidatesSelect').val();
App.contracts.Election.deployed().then(function(instance){
return instance.vote(candidateId,{
from: App.account
});
}).then(function(result){
$content.hide();
$loader.show();
}).catch(function(err){
console.warn(err);
});
},
//监听事件
listenForEvents: function(){
App.contracts.Election.deployed().then(function(instance){
instance.votedEvent({},{
formBlock:0, toBlock: 'latest'
}).watch(function(error,event){
console.log("event triggered",event);
App.reander();
});
})
}
};
$(function() {
$(window).load(function() {
App.init();
});
});
0x3 总结
Dapp开发主要内容是合约的开发和Web端开发, 在合约设计实现时要根据自己的目标Dapp功能设计合适的外部接口, 在Dapp实现时合适的调用合约接口即可完成Dapp开发. 跟多定义关于合约的设计内容可以去Truffle boxes查找Demo.
