歡迎來到另一個教程!在本教程中,我們將討論如何使用 Ethereum、Web3js、VueJS 和 Vuex 建立一個簡單的、響應式的去中心化應用程式。您可能需要對 javascript 和 web 應用程式有一些瞭解才能真正享受本教程。如果您不瞭解 Vue,不用擔心,我們將在實現應用程式時簡要地介紹一下基礎知識。
我們的應用將會很簡單。使用者可以在 1 到 10 之間下注以太幣。當使用者猜對時,他得到了他的獎勵 x10(略低於莊家切牌)。
第一部分,我們將討論專案設定和智慧合約的建立。第二部分,我們將介紹 web3js API 和 VueJS/Vuex,第三部分,我們將融會貫通並將應用程式連線到合約中。跟著一起,享受旅程,會很棒的。
我們的最終應用程式。
前提條件
由於專案比較簡單,我們不會使用 truffle。我們將在測試網路上使用 MetaMask 和 Remix(https://remix.ethereum.org)編寫和部署智慧合約。
我們需要做的第一件事是安裝 nodeJS 和 NPM,在您的作業系統上按照步驟進行安裝:https://nodejs.org/en/。在終端視窗執行如下命令檢查 node 是否正確安裝:
1 2 3 |
node -v npm -v |
接下來,如果您還沒安裝 metamask,則安裝 metamask:https://metamask.io/
我們最後一個條件是 vue-cli,它將幫助我們輕鬆設定 VueJS 專案:
1 |
npm i vue-cli -g |
專案設定
我們將使用 remix 編寫和部署智慧合約,並通過 metamask 外掛部署到 Ropsten 測試網路。在前端應用程式中,需要與合約互動的是合同地址和 ABI ( ABI 定義瞭如何在機器程式碼中訪問資料結構或計算程式)。
我們的前端將是一個 vue-cli 生成的 vueJS 應用程式。我們也將使用 web3 來與合約通訊。遵循以下簡單步驟,為客戶端應用程式建立 backbone :
- 開啟一個終端,並將目錄更改為您想要建立應用程式的地方。
- 在終端視窗輸入以下命令來建立我們的專案,並輸入“回車”來完成嚮導:
1vue init webpack betting-dapp
- 現在我們將進入我們的專案資料夾並安裝 web3,vuex 和 font-awesome:
12345cd betting-dappnpm i web3@^0.20.0 vuex font-awesome -s//To start the dummy project generated by the vue-cli use 'npm start'
我們沒有使用 web3 1.0.0 測試版,因為它在寫入時與 MetaMask 不相容。
編寫智慧合約
在我們毫無頭緒地編碼之前,我們必須首先分析我們需要的元件:
- 我們需要知道合約的所有者並擁有訪問許可權(為簡單起見,我們將不再修改所有者)
- 合約的所有者可以銷燬合約並提取餘額
- 使用者可以在 1 – 10 之間下注
- 在合約建立時,所有者能夠設定最低下注金額和莊家上風(為簡單起見,建立後不可更改)
第一步和第二步非常簡單,我們已經新增了註釋,這樣就沒問題了。 開啟 [Remix](http://remix.ethereum.org)開始工作(文章結尾處的要點連結):
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 26 27 28 29 30 31 32 33 34 35 36 37 |
pragma solidity ^0.4.10; contract Ownable { address owner; function Ownable() public { //Set owner to who creates the contract owner = msg.sender; } //Access modifier modifier Owned { require(msg.sender == owner); _; } } contract Mortal is Ownable { //Our access modifier is present, only the contract creator can use this function function kill() public Owned { selfdestruct(owner); } } |
首先我們建立合約 Ownable,建構函式 _Ownable()_將在建立時被呼叫,並將狀態變數 ‘owner’ 設定為建立者的地址。 我們還定義了一個訪問控制,當我們附加的函式的呼叫者不是合約所有者時,它將丟擲異常。
我們將此功能傳遞到 Mortal 合約中(Mortal 繼承自 Ownabe )。 它有一個函式,允許合約所有者(訪問控制)銷燬合約並將剩餘資金髮回給他。
你已經走到這一步了?你做的很好!我們的合約差不多準備好了。
現在我們在步驟3和步驟4將建立 Casino 合約:
首先我們需要 minBet 和 houseEdge,可以在建立合約時設定。通過將引數傳遞給建構函式 _Casino() 實現。我們將會使建構函式為 payable,這樣我們就可以在部署時使用 Ether 預先載入合約。我們也會實現回退過程:
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 26 27 28 29 30 31 |
contract Casino is Mortal{ uint minBet; uint houseEdge; //in % //true+amount or false+0 event Won(bool _status, uint _amount); function Casino(uint _minBet, uint _houseEdge) payable public { require(_minBet > 0); require(_houseEdge <= 100); minBet = _minBet; houseEdge = _houseEdge; } function() public { //fallback revert(); } } |
這還不夠,所以接下來我們將新增函式用於下注一個數字。此函式將生成一個隨機數(此方式不安全!),然後計算併傳送贏得的獎勵。在你的回退函式下面加上如下部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
function bet(uint _number) payable public { require(_number > 0 && _number <= 10); require(msg.value >= minBet); uint winningNumber = block.number % 10 + 1; if (_number == winningNumber) { uint amountWon = msg.value * (100 — houseEdge)/10; if(!msg.sender.send(amountWon)) revert(); Won(true, amountWon); } else { Won(false, 0); } } |
為了在 1 – 10 之間生成一個隨機數,我們取當前區塊編號,並取當前區塊號的模量(除數餘數)。這總是會產生 0-9 之間的一個數,所以我們加1,從而得到一個 1 – 10 之間的“隨機”數字。
例如:如果我們在新的匿名視窗中使用 javascript VM 在 remix 上部署合約,並在部署後呼叫 bet 函式,我們將總是得到 2 作為中獎號碼。這是因為第一個塊是 #1。1 的模是 1,加 1 等於 2。
** 請注意,這並不是真正隨機的,因為很容易預測下一個區塊號。更多地瞭解 solidity 的隨機性,請檢視[https:/ /www.youtube.com/watch?v=3wY5PRliphE].(https://www.youtube.com/watch?v=3wY5PRliphE)
為了計算贏取的獎金,我們只需計算一個乘數:
1 |
bet * (100 — houseEdge)/10 |
如果莊家上風為 0,我們的乘數是 10;如果莊家上風是 10%,則乘數是 9。
最後,我們將為所有者新增一個函式,以檢查合約的餘額,理想情況下,我們還希望為所有者新增一個提取函式,但我們現在就不做了。在你的 bet 函式下面新增以下幾行:
1 2 3 4 5 |
function checkContractBalance() Owned public view returns(uint) { return this.balance; } |
**偉大的工作!**合約現在已經準備好進行測試了!
在 remix 上測試我們的合約
在 remix 的右上角單擊 run 選項卡。確保將環境設定為 Javascript VM。在 value 欄位中輸入 20 並從下拉選單中選擇 Ether而不是 Wei 。這將在部署時使用 20 Eth 預載入合約。下面,在 create 按鈕旁邊輸入我們的構造器引數 minBet 和 houseEdge (比如,10000 wei 和 10% 的莊家上風)。
在點選“建立”之前,它應該是這樣的。
現在單擊 create 按鈕,合約例項應該出現在螢幕的右下角。將會有四個函式可見,點選 getContractBalance() 檢查一切是否正常,應該返回 20000000000000000000,這是我們傳送的 20 ether 轉換成 wei 得到的。你也會在右上角的賬戶旁邊看到你的餘額,現在將略低於80 ether。
點選“建立”合約後,餘額應該是 20*1e18 wei。
好了!一切執行正常。就像前面提到的,當使用 javascript VM 時,第一個塊總是 1,所以第一個中獎號碼總是 2。我們可以通過在 value 欄位中輸入 1 ether 來測試,並將 2 作為引數傳遞給 bet。
當點選 bet 時,我們應該看到餘額再次增加,在控制檯點選詳情,並滾動到“日誌”。我們應該看到一個我們已經贏了的事件:
我們贏了 9 以太幣!
在下一節中,我們將在 Ropsten 測試網路上部署我們的合約,並獲取合約地址和 ABI ,以便在我們的客戶端應用程式中使用。