區塊鏈研究實驗室 | 如何使用Web3.js構建Dapp

買賣虛擬貨幣

今天將向大家介紹使用web3.js構建去中心化應用程式(Dapp),首先我先向大家介紹我先選擇使用web3.js的原因。




在web3.js出現之前,我們與智慧合約進行互動的唯一方法是透過以太坊節點提供的json-rpc API去充當json-rpc伺服器。那絕非是一件易事!


分散式應用程式具有三個主要元件:
  • 前端:從使用者那裡獲取輸入並構建要傳送到智慧合約的請求。
  • 錢包:簽署交易並將其傳送到網路。
  • 智慧合約:編寫dapp的業務邏輯。

感謝web3.js的出現,讓您可以知道JSON-RPC呼叫的底層細節,因為它提供了以太坊json-rpc介面的抽象。因此,您可以使用JavaScript與以太坊節點進行互動。


web3.js的工作方式

綜上所述,想要和以太坊進行網路互動,需要將json-rpc呼叫傳送到以太坊節點,這就是web3.js在後臺執行的操作。


為了將JavaScript程式碼轉換為json-rpc請求,web3.js使用了 provider 的提供程式,該程式是符合EIP 1193規範的 JavaScript 物件,而且它實現了request負責進行以太坊RPC方法呼叫的方法。


Web3.js提到自己的實施規範,並使其可用web3.providers,其中,您可以訪問以下三個供應商文件:HttpProvider,WebsocketProvider,和IpcProvider。


其他專案也實現了此規範,例如 MetaMask,該提供商將提供者物件注入瀏覽器中的window.ethereum。較舊的Metamask用於注入web3例項 window.web3。


一旦有了提供者,就可以使用new關鍵字獲取web3的例項:
let web3 = new Web3(Web3.givenProvider || 'ws://some.local-or-remote.node:8546');


在這裡您要記住,web3.js需要一個提供程式物件,該物件配置用於簽署交易並將其傳送到網路的錢包資訊。如果您在前端使用web3,則此提供程式將注入到瀏覽器中,或者使用 websocketprovider 或將要構建自己的物件 IpcProvider。


注意:MetaMask 使用 Infura 作為節點提供程式。所以你的電腦無須安裝以太坊客戶端就可以與以太坊網路進行互動。


快速瀏覽API



web3.js不僅允許與以太坊節點通訊,而且還允許與Whisper和Swarm節點通訊。它帶有五個主要軟體包:
  • web3.eth:允許與以太坊區塊鏈和以太坊智慧合約進行互動。
  • web3.bzz:允許與分散檔案儲存Swarm進行互動。
  • web3.shh:允許與Whisper協議進行互動以進行廣播。
  • web3.utils:為以太坊dapp提供實用程式功能,例如將字串轉換為十六進位制文字,將以太值轉換為Wei。
  • web3.*.net:允許與以太坊節點的網路屬性(例如網路ID或對等體計數)進行互動。


使用web3.js構建您的Dapp



現在我們已經掌握了理論,那麼讓我們開始動手製作第一個dapp。
在此示例中,我們將構建一個問候dapp,該dapp儲存一個預設的問候字串並允許使用者對其進行更新。對於錢包,我們將使用 MetaMask。您可以透過單擊網站主頁上的下載連結來新增副檔名。

1.構建合同並將其部署到網路

首先在工作區中建立一個名為的空專案,greeting 然後使用對其進行初始化 truffle init:
> mkdir greeting> cd greeting> truffle init


假設您已經安裝了Truffle。如果還沒有,則可以使用以下命令獲取它:


npm install -g truffle


使用您的編輯器開啟專案(我使用的是VS Code)。接下來,編輯truffle-config.js 檔案並使用以太坊網路的IP和埠更新網路(您可以使用Ganache)。您還需要配置編譯器版本以使用已安裝的版本。

如果您還沒有Solidity編譯器,則可以使用以下命令進行安裝:

> npm install -g solc// check the installed version> solc --version


現在,是時候greeting在專案目錄中建立合同了。輸入以下命令:
> truffle create contract Greeting

複製並貼上以下程式碼:

// SPDX-License-Identifier: MITpragma solidity >=0.4.22 <0.8.0;
contract Greeting { string public greeting = "hello";
function sayHello() external view returns (string memory) { return greeting; }
function updateGreeting(string calldata _greeting) external { greeting = _greeting; }}

我們只需要2_deploy_greeting.js在migrations資料夾下新增一個遷移檔案:

const Greeting = artifacts.require("Greeting");module.exports = function (deployer) { deployer.deploy(Greeting);};


您現在可以使用以下方法編譯智慧合約並將其部署到網路上:

> truffle compile> truffle migrate


2.將前端與智慧合約連線

  • 設定前端


建立一個名為專案中的新資料夾中 client 有package.json和 index.html 檔案:

> mkdir client> cd client> npm init -y> touch index.html

安裝web3.js和lite-server依賴項:

> npm i web3 --save> npm i lite-server --save-dev //for running a development server


建立一個名為的新資料夾,src並新增兩個指令碼:index.js和utils.js。


您還需要使用script標記和web3指令碼在HTML檔案中新增兩個指令碼

<script type="text/javascript" src="node_modules/web3/dist/web3.min.js"></script><script type="text/javascript" src="src/utils.js"></script><script type="text/javascript" src="src/index.js"></script>

  • 獲取一個web3例項

一旦將web3.js作為專案中的依賴項,您所需要做的就是使用提供者的例項例項化web3物件,以便享受web3所提供的一切。

我們將使用window.ethereum注入到瀏覽器中的MetaMask提供程式,並按照MetaMask文件window.ethereum.request中的說明,請求使用者使用來訪問其帳戶。

開啟utils.js檔案並新增以下功能:

const getWeb3 = () => { return new Promise((resolve, reject) => { window.addEventListener("load", async () => { if (window.ethereum) { const web3 = new Web3(window.ethereum); try { // ask user permission to access his accounts await window.ethereum.request({ method: "eth_requestAccounts" }); resolve(web3); } catch (error) { reject(error); } } else { reject("Must install MetaMask"); } }); });};

  • 建立合同例項
要建立合同例項,我們需要合同ABI及其地址。如果您檢視構建目錄中的工件,則會發現一個名為的檔案Greeting.json。開啟它,您會找到許多有關合同的資訊,包括合同名稱,ABI等。


如果滾動到檔案的末尾,則會發現一個網路欄位,其中包含網路ID。合同已部署,我們將使用它透過web3例項化合同例項的相應地址。


contracts在該client資料夾下建立一個名為的新資料夾,然後將其複製貼上Greeting.json。您還需要安裝jQuery才能讀取JSON檔案的內容:

> npm i jquery


首先,我們需要使用來獲取與MetaMask連線的網路的ID web3.eth.net.getId()。

注意:假設您已經配置了MetaMask以使用Ganache。如果不確定如何操作,可以按照本指南進行操作。

接下來,我們將使用返回的ID從Greeting.json檔案中獲取合同的地址,該檔案還將為我們提供合同ABI並使用以下命令建立合同的例項web3.eth.Contract:

3.與智慧合約互動

建立合同例項後,就可以開始使用呼叫文件的方法myContract.methods.myMethod([arguments]),如docs中所述。

如果要呼叫的函式是純函式或只讀函式,則需要使用:

myContract.methods.myMethod([arguments]).call()

如果要呼叫的函式要修改狀態(又稱事務),則需要使用:

myContract.methods.myMethod([arguments]).send()


完整的程式碼
const displayGreeting = async (greeting, contract) => { greeting = await contract.methods.sayHello().call(); $("h2").html(greeting);};
const updateGreeting = (greeting, contract, accounts) => { let input; $("#input").on("change", (e) => { input = e.target.value; }); $("#form").on("submit", async (e) => { e.preventDefault(); await contract.methods .updateGreeting(input) .send({ from: accounts[0], gas: 40000 }); displayGreeting(greeting, contract); });};
async function greetingApp() { const web3 = await getWeb3(); const accounts = await web3.eth.getAccounts(); const contract = await getContract(web3); let greeting;
displayGreeting(greeting, contract); updateGreeting(greeting, contract, accounts);}
greetingApp();

作者:鏈三豐,來源:區塊鏈研究實驗室

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读