Truffle-pet-user-interface

Truffle pet demo

延續

建立一個前端介面

上一篇初始化的程式中也包含了前端的程式碼

但是只有一部分

需要做一些補全

  1. 打開 /src/js/app.js
  2. app.js 裡面已經有 一個物件叫做 App 控制我們的前端
  3. init() 負責 load data
  4. initWeb3() web3 lib他可以取回使用者帳號的資訊,發送交易需求
  5. 移除 initWeb3() 中的註解 加上下面這段程式碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
initWeb3: async function() {
if(window.ethereum) {
App.web3Provider = window.ethereum;

try {
await window.ethereum.enable();
} catch (error) {
console.error("User denied account access")
}
} else if(window.web3) {
App.web3Provider = window.web3.currentProvider;
} else {
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
}

web3 = new Web3(App.web3Provider);

return App.initContract();
},
  • 先檢查瀏覽器中是否有 ethereum provider 如果有的話就建立自己的 web3 物件來取得帳號資訊,但是依舊要呼叫 ethereum.enable()
  • 如果 ethereum 不存在,檢查 window.web3 是否存在來引用舊版的 provider
  • 如果沒有的話就是測試使用 localhost:7545

Instantiating the contract

處理好 web3 的初始化之後

現在需要來解決一下如何實際在前端取得合約的資料

truffle 有一個 lib 可以協助處理這件事情: truffle-contract

他會在 有新的 migrations 同步合約上的資訊

所以你不用修改合約的位址

  1. /src/js/app.js 中有 initContract 的函式
1
2
3
4
5
6
7
8
9
10
11
12
initContract: function() {
$.getJSON('Adoption.json', function(data) {
const AdoptionArtifact = data;
App.contracts.Adoption = TruffleContract(AdoptionArtifact);

App.contracts.Adoption.setProvider(App.web3Provider);

return App.markAdopted();
});

return App.bindEvents();
},
  • 先檢索在鏈上的合約文件,AdoptionArtifact 是合約的內容資訊,包含位址 DApp 接口(ABI)
  • 一但我們取得 Artifact 會將他 pass 給 TruffleContract(). 他會產生一個新的物件,這個物件會提供一下 method 讓我們可以跟合約溝通
  • 產生的 實例會設定給 App.web3Provider 以方便 web3使用
  • 然後呼叫 APP 的 markAdopted() function 封裝這個是因為方便在合約改變的時候可以同時改變 UI
1
2
Note: ABI: Application Binary Interface 應用程式機器碼介面
ABI 是一個 Javascript 對象,用來定義如何跟合約相互溝通的接口

Getting The Adopted Pets and Updating The UI

/src/js/app.js 中移除 markAdopted 中的註解並填入下述程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
markAdopted: function(adopters, account) {
let adoptionInstance;

App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance;
return adoptionInstance.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(error) {
console.log(error.message)
});
},

這一段程式碼中闡述了

  • 同意部署 Adoption 合約,然後呼叫 getAdopters() 在這個實例中
  • 因為宣告了adoptionInstance 在最外面,所以在之後可以呼叫他
  • call() 可以讓我們讀取資料而不用發送一個交易,代表我們不用花費任何乙太幣
  • 呼叫 getAdopters() 使用一個迴圈訪問所有的 pet 確定是否已經有了位址,因為以太使用 16 個位元的初始值,而不是用 null
  • 如果找到有相對應位址的就禁用按鈕並將按鈕的文字改為 成功 以便使用者了解這些資訊
  • 所有的錯誤都會顯示在 console

Handling the adopt() Function

依舊是在 /src/js/app.js 中,移除 handleAdopt 函式中的註解,替換為下列程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
handleAdopt: function(event) {
event.preventDefault();

let petId = parseInt($(event.target).data('id'));

let adoptionInstance;

web3.eth.getAccounts(function(error, accounts) {
if(error) {
console.log(error);
}

let 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(error) {
console.log(error.message);
});
});
}
  • 利用 web3 取得使用者帳號列,含有 error 檢查是否錯誤,若無誤 取第一個帳號
  • 在這裡已經取得部署成功的合約,將它 指定給 adoptionInstance 這個變數,這一次我們會發送一個交易請求而且必須要有 from 這個位址,這個動作會產生一些費用,在乙太中 這個費用叫做 gas,這是一種手續費用,在你儲存或是計算的時候需要付出部分 gas adopt() 中含有 寵物的 ID 和一個物件,這些資訊會被儲存在 account
  • 發送交易後的結果是一個物件,如果沒有錯誤的話會呼叫 markAdopted() 來同步 UI 和儲存的資訊

最簡單的方式是透過 MetaMask 這個在 chrome 和 firefox 都有相關的擴充套件

  1. 安裝 MetaMask
  2. 點擊同意
  3. 閱讀如何使用
  4. 輸入密碼
  5. 完成
  6. 在 MetaMask 中選擇 New RPC URL 並且輸入 http://127.0.0.1:7545

Installing and configuring lite-server

可以起一個 local 的 service 來看看結果

  1. 編輯 bs-config.json 改為下述程式碼
1
2
3
4
5
{
"server": {
"baseDir": ["./src", "./build/contracts"]
}
}
1
$ npm run dev

Result

Image

文章目录
  1. 1. Truffle pet demo
  2. 2. 建立一個前端介面
    1. 2.1. Instantiating the contract
    2. 2.2. Getting The Adopted Pets and Updating The UI
    3. 2.3. Handling the adopt() Function
    4. 2.4. Installing and configuring lite-server
  3. 3. Result
|