?1.環(huán)境安裝 ?
?1) node安裝
設(shè)置鏡像地址:? curl --silent --location https://rpm.nodesource.com/setup_8.x|bash -
下載安裝yum -yinstall nodejs
node -v 查看版本:
2)安裝truffle ?
$npm install -g truffle
3)安裝python
npm install python
2.創(chuàng)建truffle項(xiàng)目
我的項(xiàng)目安裝在 /usr/local下何缓、
所以分別執(zhí)行下面三個(gè)命令: ?1)cd /usr/local
? 2)mkdir pet_test ?//創(chuàng)建項(xiàng)目文件地址
? ? ? ? ? ?3)?truffle 幫我們打包了一些常用的經(jīng)典示例幔摸,放在box中, 這個(gè)是我們用到的pet_shop的地址:https://truffleframework.com/boxes/pet-shop
執(zhí)行:?truffle unbox pet-shop
這個(gè)命令會(huì)自動(dòng)幫我們初始化 truffle init亡脑,然后創(chuàng)建前端的文件夾。
介紹一下truffle的文件架構(gòu):
contracts/ : 智能合約文件存在這里莹规,后綴.sol (solidity)
migrations/ : 部署腳本
test/ : 測(cè)試腳本
truffle.js :truffle的配置文件
編寫智能合約:
在 contracts/ 目錄下創(chuàng)建 Adoption.sol 文件请梢,內(nèi)容如下:
pragma solidity ^0.4.17;
contract Adoption {
address[16] public adopters;
//adopting a pet
function adopt(uint petId) public returns (uint) {
require(petId >= 0 && petId <= 15);
adopters[petId] = msg.sender;
return petId;
}
//retrieve the adopters
function getAdopters() public view returns (address[16]) {
return adopters;
}
}
編寫前端:
用戶界面(UI)是前端工作,這里用的javascript辐马。主要文件是app.js拷橘,存在目錄 /src/js/app.js 中。文件內(nèi)容如下:
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() {
// Is there an injected web3 instance?
if (typeof web3 !== 'undefined') {
App.web3Provider = web3.currentProvider;
} else {
// If no injected web3 instance is detected, fall back to Ganache
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
}
web3 = new Web3(App.web3Provider);
return App.initContract();
},
initContract: function() {
$.getJSON('Adoption.json', function(data) {
// Get the necessary contract artifact file and instantiate it with truffle-contract
var AdoptionArtifact = data;
App.contracts.Adoption = TruffleContract(AdoptionArtifact);
// Set the provider for our contract
App.contracts.Adoption.setProvider(App.web3Provider);
// Use our contract to retrieve and mark the adopted pets
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) {
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;
// Execute adopt as a transaction by sending account
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();
});
});
到這里 整個(gè)項(xiàng)目的前端和合約部分都完成了喜爷。下面講述如何編譯部署合約和如何啟動(dòng)前端應(yīng)用冗疮。
因?yàn)椴渴鹗且押霞s部署到ropsten的測(cè)試網(wǎng)絡(luò)上,所以要提前配置好檩帐。部署就需要消耗gas术幔,那么就需要指定賬號(hào)。打開truffle的配置文件 truffle.js湃密。修改內(nèi)容為:
var HDWalletProvider = require("truffle-hdwallet-provider");
var mnemonic = "bomb when antenna suggest submit kitten thumb lazy silent uncover ten seek";
module.exports = {
networks: {
ropsten: {
provider: function() {
return new HDWalletProvider(mnemonic, "https://ropsten.infura.io/b59397a69a0f4639b4c70e9786a9db1f")
},
network_id: 3
}
}
};
詳細(xì)解釋一下?HDWalletProvider诅挑,mnemonic ,?https://ropsten.infura.io/b59397a69a0f4639b4c70e9786a9db1f泛源。
HDWalletProvider 需要提前安裝:?
npm install truffle-hdwallet-provider
我在執(zhí)行過程中報(bào)錯(cuò):
?因?yàn)槲沂莄entOs系統(tǒng)揍障,執(zhí)行安裝gcc:
yum -y update gcc
yum -y install gcc+ gcc-c++
?mnemonic 是你賬號(hào)的助記詞,是通過metaMask獲取的:
顯示的Your private seed phrase就是你的助記詞俩由。替換到這個(gè)變量中毒嫡。
?https://ropsten.infura.io/b59397a69a0f4639b4c70e9786a9db1f中,b59397a69a0f4639b4c70e9786a9db1f是你在infura的秘鑰。
Infura是一個(gè)托管的以太坊節(jié)點(diǎn)集群兜畸,可以將你開發(fā)的以太坊智能合約部署到infura提供的節(jié)點(diǎn)上努释,而無需搭建自己的以太坊節(jié)點(diǎn)。到這個(gè)地址注冊(cè):https://infura.io/ 在dashborad里找到自己的秘鑰拷貝過來咬摇。
編譯部署合約
1.首先執(zhí)行 truffle compile?
這里是編譯合約 把合約編譯成對(duì)應(yīng)的ABI ?二進(jìn)制文件伐蒂。
2. 下面要部署合約,教程的目的是把合約部署到 ropsten的測(cè)試網(wǎng)絡(luò)上肛鹏。結(jié)合truffle.js中的配置逸邦,讀者可以更好的理解部署命令:
truffle migrate --network ropsten
到這里你的合約就成功部署完成了。
因?yàn)閜et_shop是一個(gè)打包好的文件在扰,所以只需要執(zhí)行 npm run dev 就可以啟動(dòng)缕减。默認(rèn)的端口是3000,這個(gè)是lite sever 默認(rèn)的端口芒珠。
啟動(dòng)好以后就可以通過地址訪問了桥狡。注意我上面External 后面的IP是阿里云的內(nèi)網(wǎng)ip,需要替換成外面的ip訪問:http://120.55.51.210:3000/
然后可以通過錢包提交對(duì)合約的方法調(diào)用請(qǐng)求皱卓。
?至此裹芝,一個(gè)部署在Ropsten測(cè)試完的DAPP就部署完成了。