去中心化應用,或者叫dApp,是一種不依賴於中心化服務器的應用。相反,dApp使用就像區塊鏈和指針機這些Web3 技術,來了自己的邏輯和後台功能,具備不可篡改和實現的安全特性。
在這個技術教程中,你會學習到如何開發一個端到端的dApp。在dApp 中,用戶可以通過一個智能,獲取和存儲ETH 合約的當前價格。這個教程 演示代碼存儲在Github 中。
要求
您需要先安裝以下軟件:
去中心化應用是什麼?
dApp應用程序的代碼是在區塊鏈上的應用程序的代碼中心,是在區塊鏈上的應用程序的典型應用程序和應用程序的代碼運行不同,通常與應用程序運行不同的語言和運行不同的應用程序的代碼中心。與之對應的標籤。
由於將其後端邏輯置於高度安全、防篡改的環境中 智能合約dApps 享有許多傳統Web2 系統無法獲得的好處:
因為d Web2 App 的智能合約來使用系統可以通過有很多安全性使用,並且沒有因此的安全性且不可篡改的應用程序
- 不會停機機
- 隱私性
- 抗性
- 在最小的信任環境下執行邏輯
然而,這些優勢代碼帶來的優勢也是部署在區塊鏈上,默認是無法修改的,dApp 的維護意義比較高。中,而不是中心化服務器,所以性能會比較低。
dApp 組件
dApp 的組件會有三種不同的類型:智能合約,前端邏輯(UI)和數據存儲。
智能合約
智能合約存儲dApp 的業務邏輯和當前的狀態,這是dApp 和傳統應用程序的最大區別,也正是因為網絡點讓dApp 具備了以上提到過的優勢。
前端/UI
開發者的開發者,需要開發者完成智能合約,並把它部署在區塊鏈上但是在前端,因此網絡技術,例如使用自己的工具庫和框架。客戶端的UI通常通過 Web3.js 和 以太坊.js 與這些智能合約,通常是通過網絡對信息進行傳遞的3個智能合約。 元掩碼 完成。
數據存儲
應用存儲鏈需要同時使用多個數據鏈的特性,因為在上存儲大量的數據鏈,而且需要非常昂貴的數據鏈。 IPFS 或者 文件幣 這樣的鏈下存儲服務來存儲數據,只讓鏈存儲重要的業務邏輯和狀態。
當然你也可以選擇的雲存儲服務,然而有很多開發者可以選擇傳統的存儲方式,因為區塊鏈應用可以提供最小的信任特性。
現在我們知道了dApp 的組件,讓我們開發一個簡單的dApp。
第一步:創建智能合約
dApp 中的智能合約是一個例子,它可以查看簡單的數據並出塊鏈上的變化。在這個例子中,我們會反應 Chainlink ETH/USD 餵價對查看ETH/USD 的價格,然後將結果永久存儲在智能合約上。
文檔的第一步是打開Chainlink的,然後導航到 使用數據饋送 從這裡將源代碼複製進你的IDE 中的一個新文件裡(比如Visual Code),或者你可以點擊“Open In Remix”按鈕,然後使用在線IDE Remix。
在這個例子中,我們會使用Visual Studio Code 和 安全帽(一個EVM 開發者框架)。
首先,為我們創建一個代碼的文件夾,在這個文件夾中創建一個新的應用程序,並在這個應用程序中使用:
mkdir chainlink-dapp-example cd chainlink-dapp-example mkdir backend cd backend
,通過VS Code打開創建好的文件夾,然後播放安裝Hardhat
npm init -y npm install --save-dev hardhat npx hardhat (choose create javascript project, choose default parameters)
當安裝完成後,在“contracts”文件夾中刪除Touch.sol,然後在這個文件夾中創建一個PriceConsumerV3.sol的。在文件存儲的合約中,所以將Chainlink文件中的代碼複製到這個文件中,然後保存。
在樣例代碼中,你會看到演示合約已經有一個getLatestPrice 的功能通過Rinkeby 上的ETH/USD 餵價對查看Ethereum 的當前價格。
function getLatestPrice() public view returns (int) { ( /*uint80 roundID*/, int price, /*uint startedAt*/, /*uint timeStamp*/, /*uint80 answeredInRound*/ ) = priceFeed.latestRoundData(); return price;
創建一個新的變量和函數,在智能合約上存儲這個值。
int public storedPrice;
然後,創建一個新的函數,它會被dApp 的前端調用。這個函數會通過調用getLatestPrice 函數查看以太坊的最新價格,然後將這個值存儲在storedPrice 這個參數中:
function storeLatestPrice() external { storedPrice = getLatestPrice(); }
你的新合同應該和下面的一樣:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; contract PriceConsumerV3 { AggregatorV3Interface internal priceFeed; int public storedPrice; /** * Network: Rinkeby * Aggregator: ETH/USD * Address: 0x8A753747A1Fa494EC906cE90E9f37563A8AF630e */ constructor() { priceFeed = AggregatorV3Interface(0x8A753747A1Fa494EC906cE90E9f37563A8AF630e); } /** * Returns the latest price */ function getLatestPrice() public view returns (int) { ( /*uint80 roundID*/, int price, /*uint startedAt*/, /*uint timeStamp*/, /*uint80 answeredInRound*/ ) = priceFeed.latestRoundData(); return price; } function storeLatestPrice() external { storedPrice = getLatestPrice(); } }
第二步:部署智能合約
現在你已經可以在Rinkeby 測試網中編譯和部署你的合同了,如果沒有測試網的通證的話,可以在 鏈環水龍頭 獲得一些。
如果你使用的是Remix 的話,你可以通過Remix 編譯和部署你的合約。如果你使用的是像Visual Studio Code 這樣的話,我們推薦使用Hardhat 來管理你的合約。
在部署合同之前,可以將安裝安全帽存儲包,Chainlink合同庫和dotenv庫。 dotenv文件中的密碼和敏感信息放在一個單獨的.env文件中:
npm install --save-dev @nomicfoundation/hardhat-toolbox npm install @chainlink/contracts --save npm install dotenv
然後,將hardhat-config.js 文件中的內容轉換成下面的內容:
require("@nomicfoundation/hardhat-toolbox"); //require("@nomiclabs/hardhat-ethers") require('dotenv').config() const RINKEBY_RPC_URL = process.env.RINKEBY_RPC_URL || "https://eth-rinkeby.alchemyapi.io/v2/your-api-key" const PRIVATE_KEY = process.env.PRIVATE_KEY || "abcdef" module.exports = { defaultNetwork: "rinkeby", networks: { hardhat: { // // If you want to do some forking, uncomment this // forking: { // url: MAINNET_RPC_URL // } }, localhost: { }, rinkeby: { url: RINKEBY_RPC_URL, accounts: [PRIVATE_KEY], saveDeployments: true, }, }, solidity: "0.8.9", };
下一步是在後台文件夾中創建一個.env文件。然後你需要從 Web3錢包中獲取你的錢包確定粘貼最好的PRIVATE_KEY 這個行。
當這些做完以後,你需要一個RPC 端點來訪問Rinkeby 網絡。你可以將它粘貼到.env 文件的RINKEBY_RPC_URL 中的RPC URL 中。我們推薦註冊一個免費的 英富拉 或者 煉金術 賬戶以獲取一個RPC URL。
創建.env 文件
下一步是修改文件夾中部署文件中的內容。將其他腳本將其部署為你的新代碼。打開文件,然後代碼替換為以下。
// We require the Hardhat Runtime Environment explicitly here. This is optional // but useful for running the script in a standalone fashion through `node <script>`. // // You can also run a script with `npx hardhat run <script>`. If you do that, Hardhat // will compile your contracts, add the Hardhat Runtime Environment's members to the // global scope, and execute the script. const hre = require("hardhat"); async function main() { const PriceConsumer = await hre.ethers.getContractFactory("PriceConsumerV3"); const priceConsumer = await PriceConsumer.deploy(); await priceConsumer.deployed(); console.log("Contract deployed to:", priceConsumer.address); } // We recommend this pattern to be able to use async/await everywhere // and properly handle errors. main().catch((error) => { console.error(error); process.exitCode = 1; });
並且現在你已經可以通過安全帽來編譯你的智能合約,把它部署在Rinkeby 網絡中:
npx hardhat compile
npx hardhat run --network rinkeby scripts/deploy.js
你應該看到下麵類似的信息,會現在你在Rinke 通過網絡上的智能合約在我們的智能合約上看到這個地址,在後面的步驟中需要部署這個地址。
部署的智能合約
恭喜,你已經完成了dApp的合約部分!
第三步:創建前端應用
dApp 的前端邏輯和UI 可以通過各種框架完成。
反應 是<<的Javascript代碼庫之一,它也可以使用被豐富的網頁功能開發,因此,許多Web3 dApp所使用的。除此之外,以太坊.js 是一個Javascript,它是用來連接EVM 區塊鏈連接和開發你的庫。
在這部分,我們將使用 創建反應應用 創建一個新的React 應用程序。然後我會介紹如何通過Ether.js 來將UI 和已經部署的智能合約連接起來,完成一個端到端的dApp。
創建React 應用
前端先安裝和開發庫初始化-react-react項目,然後將它修改到我們的應用程序前端的“前端”文件夾中。
cd ..
npx create-react-app frontend
這下面完成後,你應該可以在“一步前端”文件夾中看到所有相關的React 了。 “前端”文件夾代碼然後執行操作:
- 刪除/src/setupTests.js
- 刪除/src/ReportWebVitals.js
- 刪除/src/logo.svg
- 刪除/src/App.test.js
- 刪除/src/App.css
目錄結構應如下所示:
React 前端文件夾結構
在修改React 應用代碼之前,我們需要先安裝 引導程序 和 以太坊.js。 Bootstrap 是一個很流行的前端CSS 框架,有很多React 可以使用的UI 小部件和CSS 樣式。 Ether.js 可以將前端代碼與區塊鏈上已經部署的智能合約相連接。在“前端”文件夾中輸入以下命令:
cd frontend npm install bootstrap npm install ethers
現在可以開始修改這些React 應用程序的,在/src/我們文件夾的內容中打開App.js 文件,然後去掉刪掉。我們從0 開始編寫。
第一步是告訴app 我們想要使用React(包括useEffect 和useState 庫)和Ether.js:
import React, { useEffect, useState } from 'react';
import { ethers } from "ethers";
下一步,創建一個叫“App”的函數然後導出它:
function App() { } export default App;
現在將開始完成“App”函數我們的代碼。加入下面的代碼,這些代碼會執行以下操作:
- 建立storePrice 和setStoresPrice 的react hook。
- 連接你的Metamask Web3 錢包。
- 設置部署的智能合約地址和已經部署的智能合約地址。
- 智能把合約地址這個值(可以在部署的時候獲得)到插件 REPLACE_WITH_DEPLOYED_CONTRACT_ADDRESS 這裡。
- 智能合約的A BI 可以從文件/backend/artifacts/contracts/PriceConsumerV3.json 中獲得,你還可以使用code minifier 對其進行更好的處理,存儲在你的應用程序中。
const [storedPrice, setStoredPrice] = useState(''); const provider = new ethers.providers.Web3Provider(window.ethereum) const signer = provider.getSigner() const contractAddress = <REPLACE_WITH_DEPLOYED_CONTRACT_ADDRESS>’'; const ABI = '[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"getLatestPrice","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"storeLatestPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"storedPrice","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"}]' const contract = new ethers.Contract(contractAddress, ABI, signer);
現在我們在應用中創建兩個函數:
- getStoredPrice 會連接部署的合約,並通過storedPrice()獲取當前價格。
- setNewPrice 會調用已部署合約的storeLatestPrice 函數,然後等到交易完成,調用getStoredPrice 函數來獲取存儲在智能合約中的價格。
我們會在應用中加入getStoredPrice函數,它會在加載頁面的時候調用getter函數:
const getStoredPrice = async () => { try { const contractPrice = await contract.storedPrice(); setStoredPrice(parseInt(contractPrice) / 100000000); } catch (error) { console.log("getStoredPrice Error: ", error); } } async function updateNewPrice() { try { const transaction = await contract.storeLatestPrice(); await transaction.wait(); await getStoredPrice(); } catch (error) { console.log("updateNewPrice Error: ", error); } } getStoredPrice() .catch(console.error)
前端代碼的這些最後是返回JSX 代碼一步,讓瀏覽器渲染。將下面的代碼複製進App 的函數中,在getStorePrice() 的下面。代碼會執行下面的操作:
- 返回一個簡單的2列網格佈局。
- 第一列包含了智能合約中存儲的ETH/USD 價格。
- 第二列包含一個使用這個按鈕來與智能合約的用戶,可以在下面設置一個按鈕,更新存儲按鈕調用的函數點擊下面的NewPrice。
return ( <div className="container"> <div className="row mt-5"> <div className="col"> <h3>Stored Price</h3> <p>Stored ETH/USD Price: {storedPrice}</p> </div> <div className="col"> <h3>Update Price</h3> <button type="submit" className="btn btn-dark" onClick={updateNewPrice}>Update</button> </div> </div> </div> );
你的應用現在已經完成了。如果需要,你可以和這裡完整代碼,比較一下,保證你的代碼中沒有錯誤。你可以運行你的dApp了。
運行你的dApp
在確認你所有的文件都存儲之後,在前端文件夾中運行以下命令來啟動你的dApp:
npm run start
在應用程序被加載,以後設備中會有一個新的窗口,展示dApp 的UI,你應該從Metamask 連接新聞的通知,請求將錢包到應用程序上。
React 前端
在你的合約好的合約賬戶中,Metainkeby 以後,點擊“更新按鈕,就可以部署你的智能檢查並在其中進行一些以太坊通知”。你應該會收到Metamask 的通知,並在你完成交易。在你完成交易。這些以後,你的dApp會秒過幾秒,然後當前的以太坊會出現在“Stored Price”區域:
React 前端展示Data Feed 結果
恭恭敬敬地創建一個成功的應用程序,部署在你的本地應用程序中,或者你在這個應用程序中使用一個簡單的教程,同時你也可以把它部署到雲中心使用版本的前端也可以修改,可以將其部署在IPFS 中,可以應用的CSS 來改變UI 也可以更符合你的使用場景。
總結
可以用看似區塊鍊和科技應用的這些公益性和非智能應用的匿名性應用中心化而不是應用公益性的傳統抗拒性質。
在演示中,我們創建了一個簡單的dApp,dApp 中包含了一個智能合約,這個智能合約然後可以從Chainlink ETH/USD 餵價對中獲得最新的價格,然後存儲在這個智能合約當中。有一個簡單的用戶界面,使用了一個簡單的用戶界面,使用了Ether.js 並且使用了良好的連接行為。
您可以關注鏈家禽機資料和私信加入者社區,有大量關於智能合約開發的學習以及關於區塊鏈的話題!