背景:
wek有一个宠物店,最多可以同时托管16只宠物。他希望可以利用以太坊开发一个去中心化应用,让大家来领养宠物。Truffle Box已经提供了框架代码,我们只需要开发智能合约和接口交互部分。
环境搭建
https://blog.csdn.net/The_Reader/article/details/83187194
安装Ganache,链接:http://truffleframework.com/ganache/
创建项目
打开webstorm,新建一个文件夹,然后在这个文件夹下打开终端,输入命令:truffle unbox pet-shop
然后你就可以看到:
输入命令:npm run dev
开启服务,打开浏览器,输入localhost:3000,你就可以看到主页了:
如果只显示一个Pete's Pet Shop,则更改:
然后重启服务就可以了。注: https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js
目录结构
默认的truffle项目文件结构如下:
- contracts/: Solidity智能合约的文件夹,所有的智能合约文件都放置在这里,其中包含一个重要的合约Migrations.sol(稍后再讲);
migrations/
: Truffle使用迁移系统来处理智能合约的部署,迁移系统是一个额外的智能合约,用来跟踪智能合约的变化;test/
:智能合约测试用例文件夹,包含Solidity和JavaScript测试用例;truffle.js
: Truffle项目配置文件。- pet-shop还有其他的文件和文件夹,我们先不用理会。
编写智能合约
在contracts文件夹下新建一个adoption.sol文件:
代码为:
pragma solidity ^0.4.18;
contract Adoption{
address[16] public adoptor;
function adopt(uint _petId)public returns(uint){
require(_petId>=0 && _petId<=15);
adoptor[_petId] = msg.sender;
return _petId;
}
function getAdoptor()public view returns(address[16]){
return adoptor;
}
}
然后进入终端,进入到pet-shop这个文件夹下,输入命令: truffle compile :
然后在migrations文件夹下新建一个2_adoption_migration.js文件。
内容从1_initial_migration.js照搬考过去,然后更如下:
然后进入终端,进入到pet-shop这个文件夹下,输入命令: truffle migrate 部署上去
部署之前需要将ganache打开,让其在后台运行着就可以。
然后我们写一下测试文件,在Test文件夹下新建一个TestAdoption.sol文件,内容为:
pragma solidity ^0.4.19;
import "truffle/DeployAddress.sol";
import "truffle/Assert.sol";
import "../contracts/Adoption.sol";
contract TestAdoption{
Adoption adoption = Adoption(DeployedAddresses.Adoption());
function testAdoptPet() public {
uint returnId = adoption.adopt(8);
uint expected = 8;
Assert.equal(returnId,expected,"adoption of pet id should be 8");
}
}
然后接下来呢,就是交互了,你可以看到有个src文件夹下面有个index.html,这个就是我们在网站上看到的首页面,我们通过这个文件来进行与合约的交互,当然呢,我们想要与合约交互数据,只有这个是不太好的,所以我们需要一个web3.js的接口来实现这个功能,你可以在js文件夹下,看到一个app.js文件,这个文件就是交互数据最关键的一个。
编辑app.js文件
App = {
web3Provider: null,
contracts: {},
init: function() {
// Load pets.
$.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注入
if (typeof web3 != 'undefined') {
App.web3Provider = web3.currentProvider; // 已注入的情况
} else {
App.web3Provider = new Web3.providers.HttpProvider("http://127.0.0.1:7545");
}
web3 = new Web3(App.web3Provider);
return App.initContract();
},
initContract: function() {
$.getJSON('Adoption.json', function(data) {
var AdoptionArtifact = data;
App.contracts.Adoption = TruffleContract(AdoptionArtifact); // adopt合约实例
App.contracts.Adoption.setProvider(App.web3Provider);
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;
return adoptionInstance.getAdopters.call();
}).then(function (adopters) {
// 遍历 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();
});
});
然后 npm run dev
然后打开浏览器输入:localhost:3000,并且需要google浏览器,添加metamask插件,并进入私有网络。端口号要与ganache的端口号一致,
注册metamask,并登录,然后用ganache中的一个账户
然后你就可以领养宠物了。抓紧试一试吧。