手把手教创建你的第一个以太智能合约:ETHEREUM PET SHOP(译)
手把手教創建你的第一個以太智能合約:ETHEREUM PET SHOP(譯)
原文地址?:?http://truffleframework.com/tutorials/pet-shop
譯者:lucia3
譯者steemit主頁:++https://steemit.com/@lucia3++
譯者以太地址:++0x2a703d8ae21d5f23d6ffab3a10c62f0a64825867++
如果覺得這個教程對你有用,請不要吝嗇打賞喲~
這個系列的教程將會手把手帶你搭建你的第一個dapp應用——一個寵物商店的領養追蹤系統。
這個教程是為那些有基本的以太鏈和智能合約知識,懂得一些HTML和JavaScript,但是從來沒開發過dapp的人準備的。
注意:如果想要補充以太坊基礎,請在繼續學習本教程前閱讀 Truffle的教程Ethereum Overview
在這個教程里,我們將會學習以下內容:
- 搭建開發環境(Truffle框架下開發以太坊智能合約)
- 通過使用Truffle Box創建一個Truffle項目
- 編寫一個智能合約
- 編譯合約以及將合約遷移到區塊鏈上
- 測試智能合約
- 創建一個與智能合約交互的UI
- 在瀏覽器里使用你創建的dapp
背景
皮特對于使用以太坊技術處理他們店里的寵物領養非常有興趣。這家店有16只寵物等待領養,這些寵物已經錄入了數據庫。作為一個概念的初步證明,Pete希望看到一個將一個以太坊地址與一只個寵物關聯起來的dapp。
本項目的網站結構和樣式已經提供。?我們的工作是為其編寫智能合同和前端邏輯。
搭建開發環境
在我們開始之前, 請安裝以下內容:
- ++Node.js v6+ LTS and npm (comes with Node)++
- ++Git++
一旦我們安裝了這些,我們只需要一個命令來安裝Truffle:
npm install -g truffle要驗證Truffle是否正確安裝,請在終端上輸入truffle version:
truffle version如果您看到錯誤,請確保您的npm模塊已添加到您的路徑中。
通過使用Truffle Box創建一個Truffle項目
項目目錄結構
默認的Truffle目錄結構包含以下內容:
- contracts/: 包含了我們的項目的智能合約的源文件(++Solidity++語言開發的)。 在這里有一個重要的合約Migrations.sol,我們稍后再討論。
- migrations/: Truffle uses a migration system to handle smart contract deployments. A migration is an additional special smart contract that keeps track of changes.truffle使用遷移系統來處理智能合約部署。 遷移是追蹤變化的一種額外的特殊智能合約。
- test/: contracts包含了對我們智能合約中JavaScript和Solidity的測試
- truffle.js: Truffle配置文件
pet-shop?Truffle Box項目里還有些其它的文件和文件夾,但我們目前不用關注它們。
編寫一個智能合約
我們將從編寫充當后端邏輯和存儲的智能合約開始,來開發我們的dapp。
注意事項:
在合同的頂部注明了所需的最低版本:pragma solidity ^0.4.4;。?pragma意味著“只有編譯器關心的附加信息”,而脫字符號(^)表示“指定的版本或更高版本”。
像JavaScript或PHP一樣,語句以分號結尾
定義變量
Solidity是一種靜態類型的語言,意味著像字符串,整數和數組等數據類型必須被定義。?Solidity有一個稱為address的獨特類型。 Addresses址是以太坊地址,一個存儲為20個字節的值。 以太坊區塊鏈上的每個賬戶和智能合約都有一個地址,并可以通過此地址發送和接收以太幣。
在contract Adoption {之后,在下一行添加以下變量。
address[16] public adopters;注意事項:
- 我們已經定義了一個變量:adopters。 這是一個以太坊地址數組。 數組包含一種類型,可以有一個固定的或可變的長度。 在這個例子中,類型是address,長度是16。
- 你還會注意到adopters是公共的。?公共變量具有自動getter方法,但是如果在公共變量是數組的情況下,鍵是必需的,給定了key的數組只會返回數組中的一個值。 稍后,我們將編寫一個函數來返回整個數組,供我們的用戶界面使用。
你的第一個函數:領養寵物
首先要讓用戶可以領養寵物。
注意事項:
在Solidity中,必須指定函數參數和輸出的類型。 在這種情況下,我們將獲取一個petId(整數)并返回一個整數。
首先要檢查petId,以確保petId不會超出我們定義的數組范圍。 Solidity中的數組起始索引為0,因此ID值將需要介于0和15之間。我們使用require()語句來確保ID在數組范圍內。
如果ID在范圍內,我們往adopters數組中添加 address。?調用此函數的人員或智能合約的地址由msg.sender表示。
最后,我們返回傳入的petId作為確認。
你的第二個函數:獲取領養人
如上所述,數組getters方法只從給定的鍵返回一個單一的值。 我們的UI需要更新所有的寵物收養狀態,但是調用16次getters方法并不明智。 所以我們下一步是編寫一個函數來返回整個數組。
將以下getAdopters()函數添加到智能合約中,在我們上面添加的adopt()函數之后:
// Retrieving the adopters function getAdopters() public returns (address[16]) {return adopters; }由于adopters已經聲明,我們可以簡單地返回它。 確保將返回類型(在這個例子中是adopters的類型)指定為address[16]。
編譯合約以及將合約遷移到區塊鏈上
現在我們已經編寫了我們的智能合約,接下來的步驟是編譯合約以及將合約遷移到區塊鏈上。
Truffle有一個內置的開發者控制臺,我們稱之為Truffle Develop,它生成一個開發區塊鏈,我們可以用來測試部署合同。 它還能夠直接從控制臺運行Truffle命令。 我們將使用Truffle Develop在本教程中執行我們合同中的大部分操作。
編譯
Solidity是一種編譯語言,這意味著我們需要將我們的Solidity編譯為用于以太坊虛擬機(EVM)執行的字節碼。 把它看作是將我們人類可讀的“固體”(Solidity)翻譯成EVM所理解的東西。
你會看到一個提示,顯示你現在在Truffle Develop中。 下文除非另有說明,否則所有命令都將從此控制臺運行。
truffle(develop)>注意:如果你在Windows上并遇到運行此命令的問題,請參閱有關++解決Windows上的命名沖突++的文檔。
在執行完上面那條命令后,你應該看到類似于下面的輸出:
Compiling ./contracts/Migrations.sol... Compiling ./contracts/Adoption.sol... Writing artifacts to ./build/contracts注意:如果你沒有使用Truffle Develop,這些命令可以在你的終端上使用truffle前綴。 如在編譯中,在終端上運行truffle compile。
但是,如果你不使用Truffle Develop,你將不得不使用另一個測試區塊鏈,如++TestRPC++。
將合約遷移到區塊鏈上
現在我們已經成功編譯了我們的合同,現在是時候將它們遷移到區塊鏈了!
遷移是一個部署腳本,旨在改變應用程序合同的狀態,將其從一個狀態轉移到另一個狀態。?對于第一次遷移,您可能只是部署新的代碼,但隨著時間的推移,其他遷移可能會移動數據或用新的代碼替換合同。
注意:在Truffle文檔中關于++遷移++的信息。
你將在migrations /目錄中看到一個JavaScript文件:1_initial_migration.js。 這將處理部署Migrations.sol合同以觀察后續的智能合同遷移,并確保將來不會對未更改的合同進行雙重遷移。
現在我們準備創建我們自己的遷移腳本。
在migrations /目錄下創建一個名為2_deploy_contracts.js的新文件。
將以下內容添加到2_deploy_contracts.js文件中:
在執行完上面那條命令后,你應該看到類似于下面的輸出:
Using network 'develop'.Running migration: 1_initial_migration.jsDeploying Migrations...Migrations: 0x75175eb116b36ff5fef15ebd15cbab01b50b50d1 Saving successful migration to network... Saving artifacts... Running migration: 2_deploy_contracts.jsDeploying Adoption...Adoption: 0xb9f485451a945e65e48d9dd7fc5d759af0a89e21 Saving successful migration to network... Saving artifacts...您可以按順序看到正在執行的遷移,然后是每個部署的合同的區塊鏈地址。 (你的地址會有所不同。)
您現在已經寫好了您的第一個智能合約,并將其部署到本地運行的測試區塊鏈中。 現在是時候與我們的智能合約進行互動,以確保它符合我們的要求。
測試智能合約
在智能合約測試方面,Truffle非常靈活,因為測試可以用JavaScript或Solidity編寫。 在本教程中,我們將在Solidity中編寫我們的測試。
在test /目錄下創建一個名為TestAdoption.sol的新文件。
將以下內容添加到TestAdoption.sol文件中:
我們用三個imports開始合同:
- Assert.sol:使我們在測試中使用的各種斷言。 在測試中,一個斷言會檢查如平等,不平等或判空之類的事情,以便從我們的測試中返回通過/失敗。?++truffle包含的斷言的完整列表++。
- DeployedAddresses.sol:運行測試時,Truffle會將正在測試的合約的新實例部署到TestRPC。 這個智能合約獲得了已經被部署的合約的地址。
- Adoption.sol:我們想要測試的智能合約。
注意:
前兩個imports是引用自全局Truffle文件,而不是truffle目錄。 你不會看到你的test/目錄里有truffle目錄。
然后我們定義一個包含要測試的智能合約的合同范圍的變量,調用DeployedAddresses智能合約來獲得它的地址。
測試 adopt()函數
要測試adopt()函數,成功時返回給定的petId。 我們可以通過比較采用的返回值和我們傳入的ID來確保返回的ID是正確的。
注意事項:
- 我們調用前面聲明的智能合約adoption,傳入的參數ID為8。
- 然后我們聲明我們預期的函數返回值expected為8。
- 最后,我們將實際得到的返回值returnedId,期望值expected和失敗消息(如果測試未通過,將打印到控制臺)作為入參傳遞給Assert.equal()。
測試根據給定寵物id獲得領養人的函數
由于數組只能給定一個鍵返回一個值,所以我們為整個數組創建了自己的getter。
請注意adopters的memory屬性。?memory屬性告訴Solidity將數據臨時存儲在內存中,而不是將其保存到合同的存儲。 由adopters是一個數組,我們從第一個領養函數的測試中知道我們領養了petId為 8的寵物,所以我們將測試合約地址與數組中的index為8的位置存儲的地址進行比較。
執行測試函數
創建一個與智能合約交互的UI
現在,我們已經創建了智能合約,將其部署到我們的本地測試區塊鏈中,并確認我們可以通過控制臺與它進行交互,現在是時候創建一個UI,讓Pete有一些東西可以用于他的寵物店!
這個應用程序的前端代碼在pet-shop項目目錄里。 存在于src /目錄中。
本項目的前端不使用構建系統(webpack,grunt等),盡可能簡單地開始。 該應用程序的結構已經提供; 我們將專注于編寫以太坊特有的函數。 這樣,您就可以將這些知識應用到您自己的前端開發中。
初始化 web3
在文本編輯器中打開/src/js/app.js。
檢查文件。 請注意,有一個全局App對象來管理我們的應用程序,在init()中加載寵物數據,然后調用函數initWeb3()。?++web3 JavaScript++庫與以太坊區塊鏈交互。 它可以檢索用戶帳戶,發送交易,與智能合約交互等等。
從initWeb3中刪除多行注釋并將其替換為以下內容:
注意事項:
首先,我們檢查web3實例是否已經存在。 (以太坊瀏覽器(如++Mist++或者帶有++MetaMask++擴展的Chrome)將注入自己的web3實例。)如果注入的web3實例存在,我們將獲取它的提供者并使用它創建我們的web3對象。
如果沒有web3實例存在,我們將基于我們的本地提供者創建我們的web3對象。 (對于開發環境來說,這種回退很好,但不安全,不適合生產。)
初始化智能合約
現在我們可以通過web3與以太坊互動,我們需要實例化我們的智能合約,以便web3知道在哪里找到它,以及它如何工作。 Truffle有一個庫來幫助實現這些——truffle-contract。 它將有關合同的信息與遷移保持同步,因此您不需要手動更改合同的部署地址。
注意事項:
首先我們獲取我們的智能合約的artifact文件。?artifact是關于我們的合同的信息,例如其部署的地址和應用程序二進制接口(ABI)。 ABI是一個JavaScript對象,定義了如何與契約進行交互,包括變量,函數和參數。
一旦我們在回調中獲得了artifact,我們將它們傳遞給TruffleContract()。 這創建了一個我們可以與之交互的合同實例。
實例化我們的合約之后,我們將合約提供者設置成App.web3Provider,這是之前設置web3提供者時存儲的值。
然后我們調用應用程序的markAdopted()函數,標記已經被領養的寵物。 我們把它封裝在一個單獨的函數中,因為我們需要在更改智能合約的數據時更新UI。
獲取已經領養的寵物&更新UI
注意事項:
我們訪問已部署的Adoption合同,然后在該實例上調用getAdopters()。
我們首先在智能合約調用之外聲明變量adoptionInstance,這樣我們可以在初始化實例之后的函數里訪問實例。
使用call()允許我們從區塊鏈讀取數據,而不必發送完整的交易,這意味著我們不必花費任何代價。
在調用getAdopters()之后,我們循環遍歷所有的寵物,檢查每個寵物是否存儲了領養人的地址。 由于數組包含地址類型,以太坊使用16個空地址初始化數組。 這就是為什么我們檢查一個空的地址字符串,而不是null或其他錯誤的值。
一旦找到了一個有相應地址的petId,我們禁用其領養按鈕,并將按鈕文本改為“成功”,這樣用戶就知道哪些寵物已經被領養了。
任何錯誤都被記錄到控制臺。
處理adopt()函數
注意事項:
- 我們使用web3來獲取用戶的帳戶。 在錯誤檢查后的回調中,我們然后選擇第一個帳戶。
- 從那里,我們像上面那樣得到已部署的合約,并將實例存儲在adoptionInstance中。 這一次,我們將發送一個交易,而不是一個調用。 交易需要"from"地址,并會產生相關費用。 這個費用是用以太幣支付的,被稱為gas。?gas是在智能合約中執行計算和/或存儲數據產生的費用。
我們通過執行adopt()函數來發送交易,函數的入參是寵物ID和一個包含我們先前存儲在賬戶中的賬戶地址的對象。 - 發送交易的返回是一個交易對象。 如果沒有錯誤,我們繼續調用我們的markAdopted()函數來同步UI和我們新存儲的數據。
在瀏覽器里使用你創建的dapp
現在你可以開始使用你的dapp啦!
安裝和配置MetaMask
在瀏覽器中與我們的dapp交互的最簡單的方法是通過MetaMask,Chrome的擴展插件。
在您的瀏覽器中安裝MetaMask。
安裝完成后,您會看到地址欄旁邊的MetaMask狐貍圖標。 點擊圖標,你會看到這個屏幕出現
點擊接受接受隱私聲明。
那么你會看到使用條款。 閱讀它們,滾動到底部,然后單擊接受。
現在你會看到最初的MetaMask屏幕。 點擊Import Existing DEN。
6.在標有“Wallet Seed”的框中,輸入登陸Truffle Develop時顯示的助記詞:
警告:請勿在以太網主網絡(mainnet)上使用此助記符。 如果您將ETH發送到由此助記符生成的任何帳戶,您將會失去所有您發送到該地址上的ETH!
在下面輸入密碼,然后單擊?OK。
創建的每個賬戶都有100個eth。 你會注意到它在第一個賬戶上稍微少一些,因為當合同本身被部署時使用了一些gas。
現在配置完成。
安裝和配置lite-server
我們現在可以啟動一個本地Web服務器并使用dapp。 我們正在使用lite-server庫來為我們的靜態文件提供服務。 這是pet-shop?Truffle Box里已經有的服務器,但讓我們來看看它是如何工作的。
這告訴lite-server哪些文件包含在我們的基礎目錄中。 我們為我們的網站文件添加./src目錄,為合同工件添加./build/contracts目錄。
我們還在項目的根目錄下的package.json文件中的scripts對象中添加了一個dev命令。?scripts對象允許我們將控制臺命令別名為單個npm命令。 在這種情況下,我們只是做一個單一的命令,但可能有更復雜的配置。 比如像:
這告訴npm在我們從控制臺執行npm run dev的時候運行我們的lite-server的本地安裝。
使用dapp
開發服務器將啟動并自動打開一個新的瀏覽器選項卡,其中包含您的dapp。
Pete's Pet Shop
要使用dapp,請點擊您選擇的寵物上的?Adopt?按鈕。
系統將自動提示您通過MetaMask批準交易。 點擊?Submit?以批準交易。
Adoption transaction review
就像我們期望的一樣,你會看到被寵物寵物改變的旁邊的按鈕,說“成功”,并被禁用,因為寵物已經被領養。
Adoption success
注意:如果按鈕不會自動改變為"Success",刷新瀏覽器中的應用程序應該會觸發它。
MetaMask transaction
恭喜! 你已經邁出了一大步,成為一個成熟的dapp開發者。 為了在本地進行開發,您可以使用所有工具開始制作更高級的繪圖。 如果您希望讓您的dapp能夠讓其他人使用,請繼續關注我們將來部署到Ropsten測試網絡的教程。
(完)
總結
以上是生活随笔為你收集整理的手把手教创建你的第一个以太智能合约:ETHEREUM PET SHOP(译)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IPFS + 区块链 系列】 入门篇 -
- 下一篇: Truffle 4.0、Geth 1.7