日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

手把手教创建你的第一个以太智能合约:ETHEREUM PET SHOP(译)

發(fā)布時(shí)間:2025/3/15 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手把手教创建你的第一个以太智能合约:ETHEREUM PET SHOP(译) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

手把手教創(chuàng)建你的第一個(gè)以太智能合約:ETHEREUM PET SHOP(譯)

原文地址?:?http://truffleframework.com/tutorials/pet-shop

譯者:lucia3

譯者steemit主頁(yè):++https://steemit.com/@lucia3++

譯者以太地址:++0x2a703d8ae21d5f23d6ffab3a10c62f0a64825867++

如果覺(jué)得這個(gè)教程對(duì)你有用,請(qǐng)不要吝嗇打賞喲~

這個(gè)系列的教程將會(huì)手把手帶你搭建你的第一個(gè)dapp應(yīng)用——一個(gè)寵物商店的領(lǐng)養(yǎng)追蹤系統(tǒng)。

這個(gè)教程是為那些有基本的以太鏈和智能合約知識(shí),懂得一些HTML和JavaScript,但是從來(lái)沒(méi)開(kāi)發(fā)過(guò)dapp的人準(zhǔn)備的。

注意:如果想要補(bǔ)充以太坊基礎(chǔ),請(qǐng)?jiān)诶^續(xù)學(xué)習(xí)本教程前閱讀 Truffle的教程Ethereum Overview

在這個(gè)教程里,我們將會(huì)學(xué)習(xí)以下內(nèi)容:

  • 搭建開(kāi)發(fā)環(huán)境(Truffle框架下開(kāi)發(fā)以太坊智能合約)
  • 通過(guò)使用Truffle Box創(chuàng)建一個(gè)Truffle項(xiàng)目
  • 編寫(xiě)一個(gè)智能合約
  • 編譯合約以及將合約遷移到區(qū)塊鏈上
  • 測(cè)試智能合約
  • 創(chuàng)建一個(gè)與智能合約交互的UI
  • 在瀏覽器里使用你創(chuàng)建的dapp





背景

皮特對(duì)于使用以太坊技術(shù)處理他們店里的寵物領(lǐng)養(yǎng)非常有興趣。這家店有16只寵物等待領(lǐng)養(yǎng),這些寵物已經(jīng)錄入了數(shù)據(jù)庫(kù)。作為一個(gè)概念的初步證明,Pete希望看到一個(gè)將一個(gè)以太坊地址與一只個(gè)寵物關(guān)聯(lián)起來(lái)的dapp。

本項(xiàng)目的網(wǎng)站結(jié)構(gòu)和樣式已經(jīng)提供。?我們的工作是為其編寫(xiě)智能合同和前端邏輯。





搭建開(kāi)發(fā)環(huán)境

在我們開(kāi)始之前, 請(qǐng)安裝以下內(nèi)容:

  • ++Node.js v6+ LTS and npm (comes with Node)++
  • ++Git++

一旦我們安裝了這些,我們只需要一個(gè)命令來(lái)安裝Truffle:

npm install -g truffle

要驗(yàn)證Truffle是否正確安裝,請(qǐng)?jiān)诮K端上輸入truffle version:

truffle version

如果您看到錯(cuò)誤,請(qǐng)確保您的npm模塊已添加到您的路徑中。





通過(guò)使用Truffle Box創(chuàng)建一個(gè)Truffle項(xiàng)目

  • Truffle會(huì)在當(dāng)前的目錄中初始化,所以首先在你選擇的開(kāi)發(fā)文件夾中創(chuàng)建一個(gè)目錄,然后進(jìn)入這個(gè)目錄。
  • mkdir pet-shop-tutorialcd pet-shop-tutorial
  • 我們已經(jīng)為這個(gè)pet-shop教程創(chuàng)建了一個(gè)特殊的++Truffle Box++,其中包括基本的項(xiàng)目結(jié)構(gòu)以及用戶界面的代碼。 使用truffle unbox命令解壓這個(gè)Truffle Box。
  • truffle unbox pet-shop > ##### 注意:truffle可以通過(guò)幾種不同的方式進(jìn)行初始化。 另一個(gè)有用的初始化命令是`truffle init`,它創(chuàng)建一個(gè)空的Truffle項(xiàng)目,不包含任何示例合同。 有關(guān)更多信息,請(qǐng)參閱[++創(chuàng)建項(xiàng)目文檔++]( http://truffleframework.com/docs/getting_started/project )。?


    項(xiàng)目目錄結(jié)構(gòu)

    默認(rèn)的Truffle目錄結(jié)構(gòu)包含以下內(nèi)容:

    • contracts/: 包含了我們的項(xiàng)目的智能合約的源文件(++Solidity++語(yǔ)言開(kāi)發(fā)的)。 在這里有一個(gè)重要的合約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使用遷移系統(tǒng)來(lái)處理智能合約部署。 遷移是追蹤變化的一種額外的特殊智能合約。
    • test/: contracts包含了對(duì)我們智能合約中JavaScript和Solidity的測(cè)試
    • truffle.js: Truffle配置文件

    pet-shop?Truffle Box項(xiàng)目里還有些其它的文件和文件夾,但我們目前不用關(guān)注它們。





    編寫(xiě)一個(gè)智能合約

    我們將從編寫(xiě)充當(dāng)后端邏輯和存儲(chǔ)的智能合約開(kāi)始,來(lái)開(kāi)發(fā)我們的dapp。

  • 在contracts /目錄下創(chuàng)建一個(gè)名為Adoption.sol的新文件。
  • 將以下內(nèi)容添加到文件中:
  • pragma solidity ^0.4.4;contract Adoption {}

    注意事項(xiàng):

    • 在合同的頂部注明了所需的最低版本:pragma solidity ^0.4.4;。?pragma意味著“只有編譯器關(guān)心的附加信息”,而脫字符號(hào)(^)表示“指定的版本或更高版本”。

    • 像JavaScript或PHP一樣,語(yǔ)句以分號(hào)結(jié)尾

    定義變量

    Solidity是一種靜態(tài)類型的語(yǔ)言,意味著像字符串,整數(shù)和數(shù)組等數(shù)據(jù)類型必須被定義。?Solidity有一個(gè)稱為address的獨(dú)特類型。 Addresses址是以太坊地址,一個(gè)存儲(chǔ)為20個(gè)字節(jié)的值。 以太坊區(qū)塊鏈上的每個(gè)賬戶和智能合約都有一個(gè)地址,并可以通過(guò)此地址發(fā)送和接收以太幣。

    在contract Adoption {之后,在下一行添加以下變量。

    address[16] public adopters;

    注意事項(xiàng):

    • 我們已經(jīng)定義了一個(gè)變量:adopters。 這是一個(gè)以太坊地址數(shù)組。 數(shù)組包含一種類型,可以有一個(gè)固定的或可變的長(zhǎng)度。 在這個(gè)例子中,類型是address,長(zhǎng)度是16。
    • 你還會(huì)注意到adopters是公共的。?公共變量具有自動(dòng)getter方法,但是如果在公共變量是數(shù)組的情況下,鍵是必需的,給定了key的數(shù)組只會(huì)返回?cái)?shù)組中的一個(gè)值。 稍后,我們將編寫(xiě)一個(gè)函數(shù)來(lái)返回整個(gè)數(shù)組,供我們的用戶界面使用。

    你的第一個(gè)函數(shù):領(lǐng)養(yǎng)寵物

    首先要讓用戶可以領(lǐng)養(yǎng)寵物。

  • 在上面設(shè)置的變量聲明之后,將下面的函數(shù)添加到智能合約中。
  • // Adopting a pet function adopt(uint petId) public returns (uint) {require(petId >= 0 && petId <= 15);adopters[petId] = msg.sender;return petId; }

    注意事項(xiàng):

    • 在Solidity中,必須指定函數(shù)參數(shù)和輸出的類型。 在這種情況下,我們將獲取一個(gè)petId(整數(shù))并返回一個(gè)整數(shù)。

    • 首先要檢查petId,以確保petId不會(huì)超出我們定義的數(shù)組范圍。 Solidity中的數(shù)組起始索引為0,因此ID值將需要介于0和15之間。我們使用require()語(yǔ)句來(lái)確保ID在數(shù)組范圍內(nèi)。

    • 如果ID在范圍內(nèi),我們往adopters數(shù)組中添加 address。?調(diào)用此函數(shù)的人員或智能合約的地址由msg.sender表示。

    • 最后,我們返回傳入的petId作為確認(rèn)。

    你的第二個(gè)函數(shù):獲取領(lǐng)養(yǎng)人

    如上所述,數(shù)組getters方法只從給定的鍵返回一個(gè)單一的值。 我們的UI需要更新所有的寵物收養(yǎng)狀態(tài),但是調(diào)用16次getters方法并不明智。 所以我們下一步是編寫(xiě)一個(gè)函數(shù)來(lái)返回整個(gè)數(shù)組。

    將以下getAdopters()函數(shù)添加到智能合約中,在我們上面添加的adopt()函數(shù)之后:

    // Retrieving the adopters function getAdopters() public returns (address[16]) {return adopters; }

    由于adopters已經(jīng)聲明,我們可以簡(jiǎn)單地返回它。 確保將返回類型(在這個(gè)例子中是adopters的類型)指定為address[16]。





    編譯合約以及將合約遷移到區(qū)塊鏈上

    現(xiàn)在我們已經(jīng)編寫(xiě)了我們的智能合約,接下來(lái)的步驟是編譯合約以及將合約遷移到區(qū)塊鏈上。

    Truffle有一個(gè)內(nèi)置的開(kāi)發(fā)者控制臺(tái),我們稱之為T(mén)ruffle Develop,它生成一個(gè)開(kāi)發(fā)區(qū)塊鏈,我們可以用來(lái)測(cè)試部署合同。 它還能夠直接從控制臺(tái)運(yùn)行Truffle命令。 我們將使用Truffle Develop在本教程中執(zhí)行我們合同中的大部分操作。

    編譯

    Solidity是一種編譯語(yǔ)言,這意味著我們需要將我們的Solidity編譯為用于以太坊虛擬機(jī)(EVM)執(zhí)行的字節(jié)碼。 把它看作是將我們?nèi)祟惪勺x的“固體”(Solidity)翻譯成EVM所理解的東西。

  • 登陸Truffle Develop。 確保你在包含dapp的目錄中執(zhí)行下列命令。
  • truffle develop

    你會(huì)看到一個(gè)提示,顯示你現(xiàn)在在Truffle Develop中。 下文除非另有說(shuō)明,否則所有命令都將從此控制臺(tái)運(yùn)行。

    truffle(develop)>

    注意:如果你在Windows上并遇到運(yùn)行此命令的問(wèn)題,請(qǐng)參閱有關(guān)++解決Windows上的命名沖突++的文檔。

  • 編譯dapp
  • compile

    在執(zhí)行完上面那條命令后,你應(yīng)該看到類似于下面的輸出:

    Compiling ./contracts/Migrations.sol... Compiling ./contracts/Adoption.sol... Writing artifacts to ./build/contracts

    注意:如果你沒(méi)有使用Truffle Develop,這些命令可以在你的終端上使用truffle前綴。 如在編譯中,在終端上運(yùn)行truffle compile。
    但是,如果你不使用Truffle Develop,你將不得不使用另一個(gè)測(cè)試區(qū)塊鏈,如++TestRPC++。

    將合約遷移到區(qū)塊鏈上

    現(xiàn)在我們已經(jīng)成功編譯了我們的合同,現(xiàn)在是時(shí)候?qū)⑺鼈冞w移到區(qū)塊鏈了!

    遷移是一個(gè)部署腳本,旨在改變應(yīng)用程序合同的狀態(tài),將其從一個(gè)狀態(tài)轉(zhuǎn)移到另一個(gè)狀態(tài)。?對(duì)于第一次遷移,您可能只是部署新的代碼,但隨著時(shí)間的推移,其他遷移可能會(huì)移動(dòng)數(shù)據(jù)或用新的代碼替換合同。

    注意:在Truffle文檔中關(guān)于++遷移++的信息。

    你將在migrations /目錄中看到一個(gè)JavaScript文件:1_initial_migration.js。 這將處理部署Migrations.sol合同以觀察后續(xù)的智能合同遷移,并確保將來(lái)不會(huì)對(duì)未更改的合同進(jìn)行雙重遷移。

    現(xiàn)在我們準(zhǔn)備創(chuàng)建我們自己的遷移腳本。

  • 在migrations /目錄下創(chuàng)建一個(gè)名為2_deploy_contracts.js的新文件。

  • 將以下內(nèi)容添加到2_deploy_contracts.js文件中:

  • var Adoption = artifacts.require("Adoption");module.exports = function(deployer) {deployer.deploy(Adoption); };
  • 回到我們的控制臺(tái),將合同遷移到區(qū)塊鏈。
  • migrate

    在執(zhí)行完上面那條命令后,你應(yīng)該看到類似于下面的輸出:

    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...

    您可以按順序看到正在執(zhí)行的遷移,然后是每個(gè)部署的合同的區(qū)塊鏈地址。 (你的地址會(huì)有所不同。)

    您現(xiàn)在已經(jīng)寫(xiě)好了您的第一個(gè)智能合約,并將其部署到本地運(yùn)行的測(cè)試區(qū)塊鏈中。 現(xiàn)在是時(shí)候與我們的智能合約進(jìn)行互動(dòng),以確保它符合我們的要求。

    測(cè)試智能合約

    在智能合約測(cè)試方面,Truffle非常靈活,因?yàn)闇y(cè)試可以用JavaScript或Solidity編寫(xiě)。 在本教程中,我們將在Solidity中編寫(xiě)我們的測(cè)試。

  • 在test /目錄下創(chuàng)建一個(gè)名為T(mén)estAdoption.sol的新文件。

  • 將以下內(nèi)容添加到TestAdoption.sol文件中:

  • pragma solidity ^0.4.11;import "truffle/Assert.sol"; import "truffle/DeployedAddresses.sol"; import "../contracts/Adoption.sol";contract TestAdoption {Adoption adoption = Adoption(DeployedAddresses.Adoption());}

    我們用三個(gè)imports開(kāi)始合同:

    • Assert.sol:使我們?cè)跍y(cè)試中使用的各種斷言。 在測(cè)試中,一個(gè)斷言會(huì)檢查如平等,不平等或判空之類的事情,以便從我們的測(cè)試中返回通過(guò)/失敗。?++truffle包含的斷言的完整列表++。
    • DeployedAddresses.sol:運(yùn)行測(cè)試時(shí),Truffle會(huì)將正在測(cè)試的合約的新實(shí)例部署到TestRPC。 這個(gè)智能合約獲得了已經(jīng)被部署的合約的地址。
    • Adoption.sol:我們想要測(cè)試的智能合約。

    注意:
    前兩個(gè)imports是引用自全局Truffle文件,而不是truffle目錄。 你不會(huì)看到你的test/目錄里有truffle目錄。

    然后我們定義一個(gè)包含要測(cè)試的智能合約的合同范圍的變量,調(diào)用DeployedAddresses智能合約來(lái)獲得它的地址。

    測(cè)試 adopt()函數(shù)

    要測(cè)試adopt()函數(shù),成功時(shí)返回給定的petId。 我們可以通過(guò)比較采用的返回值和我們傳入的ID來(lái)確保返回的ID是正確的。

  • 在Adoption的聲明之后,在TestAdoption.sol智能合同中添加以下函數(shù):
  • // Testing the adopt() function function testUserCanAdoptPet() {uint returnedId = adoption.adopt(8);uint expected = 8;Assert.equal(returnedId, expected, "Adoption of pet ID 8 should be recorded."); }

    注意事項(xiàng):

    • 我們調(diào)用前面聲明的智能合約adoption,傳入的參數(shù)ID為8。
    • 然后我們聲明我們預(yù)期的函數(shù)返回值expected為8。
    • 最后,我們將實(shí)際得到的返回值returnedId,期望值expected和失敗消息(如果測(cè)試未通過(guò),將打印到控制臺(tái))作為入?yún)鬟f給Assert.equal()。

    測(cè)試根據(jù)給定寵物id獲得領(lǐng)養(yǎng)人的函數(shù)

    由于數(shù)組只能給定一個(gè)鍵返回一個(gè)值,所以我們?yōu)檎麄€(gè)數(shù)組創(chuàng)建了自己的getter。

  • 在TestAdoption.sol中先前添加的函數(shù)下添加此函數(shù)。
  • // Testing retrieval of all pet owners function testGetAdopterAddressByPetIdInArray() {// Expected owner is this contractaddress expected = this;// Store adopters in memory rather than contract's storageaddress[16] memory adopters = adoption.getAdopters();Assert.equal(adopters[8], expected, "Owner of pet ID 8 should be recorded."); }

    請(qǐng)注意adopters的memory屬性。?memory屬性告訴Solidity將數(shù)據(jù)臨時(shí)存儲(chǔ)在內(nèi)存中,而不是將其保存到合同的存儲(chǔ)。 由adopters是一個(gè)數(shù)組,我們從第一個(gè)領(lǐng)養(yǎng)函數(shù)的測(cè)試中知道我們領(lǐng)養(yǎng)了petId為 8的寵物,所以我們將測(cè)試合約地址與數(shù)組中的index為8的位置存儲(chǔ)的地址進(jìn)行比較。

    執(zhí)行測(cè)試函數(shù)

  • 回到Truffle Develop中,執(zhí)行下列命令:
  • test
  • 如果所有的測(cè)試都通過(guò)了,你會(huì)看到類似這樣的控制臺(tái)輸出:
  • Using network 'develop'.Compiling ./contracts/Adoption.sol...Compiling ./test/TestAdoption.sol...Compiling truffle/Assert.sol...Compiling truffle/DeployedAddresses.sol...TestAdoption? testUserCanAdoptPet (91ms)? testGetAdopterAddressByPetId (70ms)? testGetAdopterAddressByPetIdInArray (89ms)3 passing (670ms)






    創(chuàng)建一個(gè)與智能合約交互的UI

    現(xiàn)在,我們已經(jīng)創(chuàng)建了智能合約,將其部署到我們的本地測(cè)試區(qū)塊鏈中,并確認(rèn)我們可以通過(guò)控制臺(tái)與它進(jìn)行交互,現(xiàn)在是時(shí)候創(chuàng)建一個(gè)UI,讓Pete有一些東西可以用于他的寵物店!

    這個(gè)應(yīng)用程序的前端代碼在pet-shop項(xiàng)目目錄里。 存在于src /目錄中。

    本項(xiàng)目的前端不使用構(gòu)建系統(tǒng)(webpack,grunt等),盡可能簡(jiǎn)單地開(kāi)始。 該應(yīng)用程序的結(jié)構(gòu)已經(jīng)提供; 我們將專注于編寫(xiě)以太坊特有的函數(shù)。 這樣,您就可以將這些知識(shí)應(yīng)用到您自己的前端開(kāi)發(fā)中。

    初始化 web3

  • 在文本編輯器中打開(kāi)/src/js/app.js。

  • 檢查文件。 請(qǐng)注意,有一個(gè)全局App對(duì)象來(lái)管理我們的應(yīng)用程序,在init()中加載寵物數(shù)據(jù),然后調(diào)用函數(shù)initWeb3()。?++web3 JavaScript++庫(kù)與以太坊區(qū)塊鏈交互。 它可以檢索用戶帳戶,發(fā)送交易,與智能合約交互等等。

  • 從initWeb3中刪除多行注釋并將其替換為以下內(nèi)容:

  • // Is there is an injected web3 instance? if (typeof web3 !== 'undefined') {App.web3Provider = web3.currentProvider; } else {// If no injected web3 instance is detected, fallback to the TestRPCApp.web3Provider = new Web3.providers.HttpProvider('http://localhost:8545'); } web3 = new Web3(App.web3Provider);

    注意事項(xiàng):

    • 首先,我們檢查web3實(shí)例是否已經(jīng)存在。 (以太坊瀏覽器(如++Mist++或者帶有++MetaMask++擴(kuò)展的Chrome)將注入自己的web3實(shí)例。)如果注入的web3實(shí)例存在,我們將獲取它的提供者并使用它創(chuàng)建我們的web3對(duì)象。

    • 如果沒(méi)有web3實(shí)例存在,我們將基于我們的本地提供者創(chuàng)建我們的web3對(duì)象。 (對(duì)于開(kāi)發(fā)環(huán)境來(lái)說(shuō),這種回退很好,但不安全,不適合生產(chǎn)。)

    初始化智能合約

    現(xiàn)在我們可以通過(guò)web3與以太坊互動(dòng),我們需要實(shí)例化我們的智能合約,以便web3知道在哪里找到它,以及它如何工作。 Truffle有一個(gè)庫(kù)來(lái)幫助實(shí)現(xiàn)這些——truffle-contract。 它將有關(guān)合同的信息與遷移保持同步,因此您不需要手動(dòng)更改合同的部署地址。

  • 仍然在/src/js/app.js中,從initContract中刪除多行注釋并將其替換為以下內(nèi)容:
  • $.getJSON('Adoption.json', function(data) {// Get the necessary contract artifact file and instantiate it with truffle-contractvar AdoptionArtifact = data;App.contracts.Adoption = TruffleContract(AdoptionArtifact);// Set the provider for our contractApp.contracts.Adoption.setProvider(App.web3Provider);// Use our contract to retrieve and mark the adopted petsreturn App.markAdopted(); });

    注意事項(xiàng):

    • 首先我們獲取我們的智能合約的artifact文件。?artifact是關(guān)于我們的合同的信息,例如其部署的地址和應(yīng)用程序二進(jìn)制接口(ABI)。 ABI是一個(gè)JavaScript對(duì)象,定義了如何與契約進(jìn)行交互,包括變量,函數(shù)和參數(shù)。

    • 一旦我們?cè)诨卣{(diào)中獲得了artifact,我們將它們傳遞給TruffleContract()。 這創(chuàng)建了一個(gè)我們可以與之交互的合同實(shí)例。

    • 實(shí)例化我們的合約之后,我們將合約提供者設(shè)置成App.web3Provider,這是之前設(shè)置web3提供者時(shí)存儲(chǔ)的值。

    • 然后我們調(diào)用應(yīng)用程序的markAdopted()函數(shù),標(biāo)記已經(jīng)被領(lǐng)養(yǎng)的寵物。 我們把它封裝在一個(gè)單獨(dú)的函數(shù)中,因?yàn)槲覀冃枰诟闹悄芎霞s的數(shù)據(jù)時(shí)更新UI。

    獲取已經(jīng)領(lǐng)養(yǎng)的寵物&更新UI

  • 仍然在/src/js/app.js中,從markAdopted中刪除多行注釋,并將其替換為以下內(nèi)容:
  • 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); });

    注意事項(xiàng):

    • 我們?cè)L問(wèn)已部署的Adoption合同,然后在該實(shí)例上調(diào)用getAdopters()。

    • 我們首先在智能合約調(diào)用之外聲明變量adoptionInstance,這樣我們可以在初始化實(shí)例之后的函數(shù)里訪問(wèn)實(shí)例。

    • 使用call()允許我們從區(qū)塊鏈讀取數(shù)據(jù),而不必發(fā)送完整的交易,這意味著我們不必花費(fèi)任何代價(jià)。

    • 在調(diào)用getAdopters()之后,我們循環(huán)遍歷所有的寵物,檢查每個(gè)寵物是否存儲(chǔ)了領(lǐng)養(yǎng)人的地址。 由于數(shù)組包含地址類型,以太坊使用16個(gè)空地址初始化數(shù)組。 這就是為什么我們檢查一個(gè)空的地址字符串,而不是null或其他錯(cuò)誤的值。

    • 一旦找到了一個(gè)有相應(yīng)地址的petId,我們禁用其領(lǐng)養(yǎng)按鈕,并將按鈕文本改為“成功”,這樣用戶就知道哪些寵物已經(jīng)被領(lǐng)養(yǎng)了。

    • 任何錯(cuò)誤都被記錄到控制臺(tái)。

    處理adopt()函數(shù)

  • 仍然在/src/js/app.js中,從handleAdopt中刪除多行注釋,并將其替換為以下內(nèi)容:
  • 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 accountreturn adoptionInstance.adopt(petId, {from: account});}).then(function(result) {return App.markAdopted();}).catch(function(err) {console.log(err.message);}); });

    注意事項(xiàng):

    • 我們使用web3來(lái)獲取用戶的帳戶。 在錯(cuò)誤檢查后的回調(diào)中,我們?nèi)缓筮x擇第一個(gè)帳戶。
    • 從那里,我們像上面那樣得到已部署的合約,并將實(shí)例存儲(chǔ)在adoptionInstance中。 這一次,我們將發(fā)送一個(gè)交易,而不是一個(gè)調(diào)用。 交易需要"from"地址,并會(huì)產(chǎn)生相關(guān)費(fèi)用。 這個(gè)費(fèi)用是用以太幣支付的,被稱為gas。?gas是在智能合約中執(zhí)行計(jì)算和/或存儲(chǔ)數(shù)據(jù)產(chǎn)生的費(fèi)用。
      我們通過(guò)執(zhí)行adopt()函數(shù)來(lái)發(fā)送交易,函數(shù)的入?yún)⑹菍櫸颕D和一個(gè)包含我們先前存儲(chǔ)在賬戶中的賬戶地址的對(duì)象。
    • 發(fā)送交易的返回是一個(gè)交易對(duì)象。 如果沒(méi)有錯(cuò)誤,我們繼續(xù)調(diào)用我們的markAdopted()函數(shù)來(lái)同步UI和我們新存儲(chǔ)的數(shù)據(jù)。

    在瀏覽器里使用你創(chuàng)建的dapp

    現(xiàn)在你可以開(kāi)始使用你的dapp啦!

    安裝和配置MetaMask

    在瀏覽器中與我們的dapp交互的最簡(jiǎn)單的方法是通過(guò)MetaMask,Chrome的擴(kuò)展插件。

  • 在您的瀏覽器中安裝MetaMask。

  • 安裝完成后,您會(huì)看到地址欄旁邊的MetaMask狐貍圖標(biāo)。 點(diǎn)擊圖標(biāo),你會(huì)看到這個(gè)屏幕出現(xiàn)








  • 點(diǎn)擊接受接受隱私聲明。

  • 那么你會(huì)看到使用條款。 閱讀它們,滾動(dòng)到底部,然后單擊接受。








  • 現(xiàn)在你會(huì)看到最初的MetaMask屏幕。 點(diǎn)擊Import Existing DEN









    6.在標(biāo)有“Wallet Seed”的框中,輸入登陸Truffle Develop時(shí)顯示的助記詞:

  • candy maple cake sugar pudding cream honey rich smooth crumble sweet treat

    警告:請(qǐng)勿在以太網(wǎng)主網(wǎng)絡(luò)(mainnet)上使用此助記符。 如果您將ETH發(fā)送到由此助記符生成的任何帳戶,您將會(huì)失去所有您發(fā)送到該地址上的ETH

    在下面輸入密碼,然后單擊?OK。








  • 現(xiàn)在我們需要將MetaMask連接到由Truffle Develop創(chuàng)建的區(qū)塊鏈。 點(diǎn)擊顯示“Main Network”的菜單并選擇Custom RPC。








  • 在標(biāo)題為“New RPC URL”的框中輸入http:// localhost:9545,然后單擊Save。








  • 點(diǎn)擊"Settings"旁邊的向左箭頭關(guān)閉頁(yè)面并返回到“帳戶”頁(yè)面。Truffle Develop?


    創(chuàng)建的每個(gè)賬戶都有100個(gè)eth。 你會(huì)注意到它在第一個(gè)賬戶上稍微少一些,因?yàn)楫?dāng)合同本身被部署時(shí)使用了一些gas。









    現(xiàn)在配置完成。



  • 安裝和配置lite-server

    我們現(xiàn)在可以啟動(dòng)一個(gè)本地Web服務(wù)器并使用dapp。 我們正在使用lite-server庫(kù)來(lái)為我們的靜態(tài)文件提供服務(wù)。 這是pet-shop?Truffle Box里已經(jīng)有的服務(wù)器,但讓我們來(lái)看看它是如何工作的。

  • 在文本編輯器(在項(xiàng)目的根目錄下)中打開(kāi)bs-config.json并檢查其內(nèi)容:
  • {"server": {"baseDir": ["./src", "./build/contracts"]} }

    這告訴lite-server哪些文件包含在我們的基礎(chǔ)目錄中。 我們?yōu)槲覀兊木W(wǎng)站文件添加./src目錄,為合同工件添加./build/contracts目錄。




    我們還在項(xiàng)目的根目錄下的package.json文件中的scripts對(duì)象中添加了一個(gè)dev命令。?scripts對(duì)象允許我們將控制臺(tái)命令別名為單個(gè)npm命令。 在這種情況下,我們只是做一個(gè)單一的命令,但可能有更復(fù)雜的配置。 比如像:

    "scripts": {"dev": "lite-server","test": "echo \"Error: no test specified\" && exit 1" },

    這告訴npm在我們從控制臺(tái)執(zhí)行npm run dev的時(shí)候運(yùn)行我們的lite-server的本地安裝。

    使用dapp

  • 啟動(dòng)本地Web服務(wù)器:
  • npm run dev

    開(kāi)發(fā)服務(wù)器將啟動(dòng)并自動(dòng)打開(kāi)一個(gè)新的瀏覽器選項(xiàng)卡,其中包含您的dapp。









    Pete's Pet Shop



  • 要使用dapp,請(qǐng)點(diǎn)擊您選擇的寵物上的?Adopt?按鈕。

  • 系統(tǒng)將自動(dòng)提示您通過(guò)MetaMask批準(zhǔn)交易。 點(diǎn)擊?Submit?以批準(zhǔn)交易。









    Adoption transaction review



  • 就像我們期望的一樣,你會(huì)看到被寵物寵物改變的旁邊的按鈕,說(shuō)“成功”,并被禁用,因?yàn)閷櫸镆呀?jīng)被領(lǐng)養(yǎng)。









    Adoption success



  • 注意:如果按鈕不會(huì)自動(dòng)改變?yōu)?#34;Success",刷新瀏覽器中的應(yīng)用程序應(yīng)該會(huì)觸發(fā)它。








    MetaMask transaction




    恭喜! 你已經(jīng)邁出了一大步,成為一個(gè)成熟的dapp開(kāi)發(fā)者。 為了在本地進(jìn)行開(kāi)發(fā),您可以使用所有工具開(kāi)始制作更高級(jí)的繪圖。 如果您希望讓您的dapp能夠讓其他人使用,請(qǐng)繼續(xù)關(guān)注我們將來(lái)部署到Ropsten測(cè)試網(wǎng)絡(luò)的教程。
    (完)

    總結(jié)

    以上是生活随笔為你收集整理的手把手教创建你的第一个以太智能合约:ETHEREUM PET SHOP(译)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。