web3 技術堆棧丨教你如何利用EVM構建一個全棧dapp

使用 React、Ethers.js、Solidity 和 Hardhat 構建全棧 dApp

在本教程中,您將學習一個 web3 技術堆棧,該堆棧將允許您利用以太坊虛擬機 (EVM) 在包括 Ethereum、Polygon、Avalanche、Celo 和許多其他區塊鏈網絡在內的數十個區塊鏈網絡上構建全棧應用程序。

此項目的代碼位於此處。 本教程的視頻課程位於此處‌。 另請查看定義 web3 堆棧‌

我最近以開發者關係工程師的身份加入了 Edge & Node,並且一直在深入研究以太坊的智能合約開發。 我已經確定了我認為使用 Solidity 構建全棧 dApp 的最佳堆棧:

▶︎ 客戶端框架 – React

▶︎ 以太坊開發環境——Hardhat‌

▶︎ 以太坊網絡客戶端庫 – Ethers.js‌

▶︎ API 層 – The Graph Protocol

雖然我在學習這一點時遇到的問題是,雖然對於這些東西中的每一個都有相當好的文檔,但對於如何將所有這些東西放在一起並理解它們如何相互工作並沒有什麼真正的東西。有一些非常好的模板,例如 scaffold-eth(其中還包括 Ethers、Hardhat 和 The Graph),對於剛入門的人來說可能太多了。

我想要一個端到端的指南,向我展示如何使用最新的資源、庫和工具構建全棧以太坊應用程序。

我感興趣的事情是:

  1. 如何創建、部署和測試以太坊智能合約到本地、測試和主網
  2. 如何在本地、測試和生產環境/網絡之間切換
  3. 如何使用 React、Vue、Svelte 或 Angular 等前端的各種環境連接到合約並與之交互

在花了一些時間弄清楚所有這些並開始使用我感到非常滿意的堆棧之後,我認為寫下如何使用這個堆棧構建和測試一個完整堆棧的以太坊應用程序會很好,不僅適用於其他人有誰可能對這個棧感興趣,也供自己日後參考。本文就是那個參考。

各個部分

讓我們回顧一下我們將使用的主要部分以及它們如何適合堆棧。

1、以太坊開發環境

在構建智能合約時,您將需要一種無需處理實時環境即可部署合約、運行測試和調試 Solidity 代碼的方法。

您還需要一種方法將 Solidity 代碼編譯成可以在客戶端應用程序中運行的代碼——在我們的例子中,是一個 React 應用程序。稍後我們將詳細了解它的工作原理。

Hardhat 是專為全棧開發而設計的以太坊開發環境和框架,也是我將用於本教程的框架。

生態系統中的其他類似工具是 Ganache、Truffle 和 Foundry。

2. 以太坊網絡客戶端庫

在我們的 React 應用程序中,我們需要一種與已部署的智能合約進行交互的方法。我們將需要一種讀取數據以及發送新事務的方法。

ethers.js 旨在成為一個完整而緊湊的庫,用於從 React、Vue、Angular 或 Svelte 等客戶端 JavaScript 應用程序與以太坊區塊鏈及其生態系統進行交互。這是我們將使用的庫。

生態系統中另一個流行的選項是 web3.js

3. Metamask

Metamask 有助於處理帳戶管理並將當前用戶連接到區塊鏈。 MetaMask 使用戶能夠以幾種不同的方式管理他們的帳戶和密鑰,同時將它們與站點上下文隔離。

一旦用戶連接了他們的 MetaMask 錢包,您作為開發人員就可以與全球可用的以太坊 API (window.ethereum) 進行交互,該 API 可以識別 web3 兼容瀏覽器的用戶(如 MetaMask 用戶),並且每當您請求交易簽名時,MetaMask將以儘可能易於理解的方式提示用戶。

4. React

React 是一個前端 JavaScript 庫,用於構建 Web 應用程序、用戶界面和 UI 組件。它由 Facebook 和許多個人開發者和公司維護。

React 及其龐大的元框架生態系統(如 Next.js、Gatsby、Redwood、Blitz.js 等)支持所有類型的部署目標,包括傳統 SPA、靜態站點生成器、服務器端渲染以及這三者的組合。 React 似乎繼續在前端領域佔據主導地位,我認為至少在不久的將來會繼續這樣。

5. The Graph

對於大多數建立在以太坊等區塊鏈上的應用程序,直接從鏈中讀取數據既困難又耗時,因此您過去常常看到人們和公司構建自己的集中式索引服務器並為來自這些服務器的 API 請求提供服務。 這需要大量的工程和硬件資源,並破壞了去中心化所需的安全屬性。

The Graph 是一種用於查詢區塊鏈數據的索引協議,它可以創建完全去中心化的應用程序並解決這個問題,並提供應用程序可以使用的豐富的 GraphQL 查詢層。 在本指南中,我們不會為我們的應用程序構建子圖,但會在以後的教程中這樣做。

要了解如何使用 The Graph 構建區塊鏈 API,請查看在 Ethereum 上構建 GraphQL API‌。

我們將建造什麼

在本教程中,我們將構建、部署和連接幾個基本的智能合約:

  1. 在以太坊區塊鏈上創建和更新消息的合約
  2. 用於鑄造代幣的合約,然後允許合約的所有者將代幣發送給其他人並讀取代幣餘額,並允許新代幣的所有者也將它們發送給其他人。

我們還將構建一個 React 前端,允許用戶:

  1. 從部署到區塊鏈的合約中讀取問候語
  2. 更新問候語
  3. 將新鑄造的代幣從他們的地址發送到另一個地址
  4. 一旦有人收到代幣,允許他們也將他們的代幣發送給其他人
  5. 從部署到區塊鏈的合約中讀取代幣餘額

先決條件

  • 安裝在本地機器上的 Node.js
  • MetaMask,瀏覽器中安裝的 Chrome 擴展程序

對於本指南,您不需要擁有任何以太坊,因為我們將在整個教程的測試網絡上使用假 / 測試 Ether。

開始

首先,我們將創建一個新的 React 應用程序:

npx create-react-app react-dapp

接下來,進入新目錄並使用 NPM 或 Yarn 安裝 ethers.js 和 hardhat:

npm install ethers hardhat @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers

安裝和配置以太坊開發環境

接下來,使用 Hardhat 初始化一個新的以太坊開發環境:

npx hardhat

? What do you want to do? Create a sample project
? Hardhat project root:

現在,您應該會在根目錄中看到為您創建的以下部分:

  • hardhat.config.js – 您的全部 Hardhat 設置(即您的配置、插件和自定義任務)都包含在此文件中。
  • scrips – 包含名為 sample-script.js 的腳本的文件夾,該腳本將在執行時部署您的智能合約
  • test – 包含示例測試腳本合同的文件夾 – 包含示例 Solidity 智能合約的文件夾

由於一個MetaMask 配置問題,我們需要將 HardHat 配置上的鏈 ID 更新為 1337。我們還需要將已編譯合約的工件位置更新為位於 React 應用程序的 src 目錄中。

要進行這些更新,請打開 hardhat.config.js 並將 module.exports 更新為如下所示:

module.exports = {
solidity: "0.8.4",
paths: {
artifacts: './src/artifacts',
},
networks: {
hardhat: {
chainId: 1337
}
}
};

我們的智能合約

接下來,讓我們看一下在contracts/Greeter.sol 中提供給我們的示例合約:

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "hardhat/console.sol";

contract Greeter {
string greeting;

constructor(string memory _greeting) {
console.log("Deploying a Greeter with greeting:", _greeting);
greeting = _greeting;
}

function greet() public view returns (string memory) {
return greeting;
}

function setGreeting(string memory _greeting) public {
console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
greeting = _greeting;
}
}

這是一個非常基本的智能合約。部署后,它會設置一個 Greeting 變量並公開一個可以調用以返回問候語的函數 (greet)。

它還公開了一個允許用戶更新問候語的函數(setGreeting)。當部署到以太坊區塊鏈時,這些方法將可供用戶交互。

讀寫以太坊區塊鏈

與智能合約交互的方式有兩種,讀取或寫入/交易。在我們的合同中,greet 可以被認為是閱讀,而 setGreeting 可以被認為是寫作/事務性的。

在寫入或初始化交易時,您必須為要寫入區塊鏈的交易付費。要完成這項工作,您需要支付 Gas,這是在以太坊區塊鏈上成功進行交易和執行合約所需的費用或價格。

只要您只是從區塊鏈中讀取數據而不更改或更新任何內容,您就不需要執行交易,並且這樣做不會產生任何gas或成本。然後,您調用的功能僅由您連接的節點執行,因此您無需支付任何費用,並且讀取是免費的。

在我們的 React 應用程序中,我們與智能合約交互的方式是使用 ethers.js 庫、合約地址和將由 hardhat 從合約創建的 ABI 的組合。

什麼是 ABI? ABI 代表應用程序二進制接口。您可以將其視為客戶端應用程序與您將與之交互的智能合約部署的以太坊區塊鏈之間的接口。

ABI 通常由 HardHat 等開發框架從 Solidity 智能合約編譯而來。您還可以經常在 Etherscan 上找到智能合約的 ABI。

編譯 ABI

現在我們已經了解了基本的智能合約並知道了 ABI 是什麼,讓我們為我們的項目編譯一個 ABI。

為此,請轉到命令行並運行以下命令:

npx hardhat compile

現在,您應該會在 src 目錄中看到一個名為 artifacts 的新文件夾。

artifacts/contracts/Greeter.json 文件包含 ABI 作為屬性之一。 當我們需要使用 ABI 時,我們可以從我們的 JavaScript 文件中導入它:

import Greeter from './artifacts/contracts/Greeter.sol/Greeter.json'

然後我們可以像這樣引用 ABI:

console.log("Greeter ABI: ", Greeter.abi)

請注意,Ethers.js 還啟用了人類可讀的 ABI,但在本教程中不會涉及到這一點。

部署和使用本地網絡/區塊鏈

接下來,讓我們將我們的智能合約部署到本地區塊鏈,以便我們對其進行測試。

要部署到本地網絡,首先需要啟動本地測試節點。 為此,請打開 CLI 並運行以下命令:

npx hardhat node

當我們運行此命令時,您應該會看到地址和私鑰列表。

web3 技術堆棧丨教你如何利用EVM構建一個全棧dapp

這些是為我們創建的 20 個測試賬戶和地址,我們可以使用它們來部署和測試我們的智能合約。 每個帳戶還加載了 10,000 個測試以太幣。 稍後,我們將學習如何將測試帳戶導入 MetaMask 以便我們可以使用它。

接下來,我們需要將合約部署到測試網絡。 首先將scripts/sample-script.js 的名稱更新為scripts/deploy.js。

現在我們可以運行部署腳本並為我們想要部署到本地網絡的 CLI 提供一個標誌:

npx hardhat run scripts/deploy.js --network localhost

執行此腳本后,智能合約應部署到本地測試網絡,然後我們應該能夠開始與之交互。

部署合約時,它使用了我們啟動本地網絡時創建的第一個帳戶。

如果您查看 CLI 的輸出,您應該能夠看到如下內容:

Greeter deployed to: 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0

這個地址是我們將在我們的客戶端應用程序中用來與智能合約對話的地址。 保持此地址可用,因為我們在從客戶端應用程序連接到它時需要使用它。

要將交易發送到智能合約,我們需要使用我們在運行 npx hardhat node時創建的帳戶之一連接我們的 MetaMask 錢包。 在 CLI 註銷的合同列表中,您應該會看到Account numberPrivate Key

➜ react-dapp git:(main) npx hardhat node
Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/

Accounts
========
Account #0: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 (10000 ETH)
Private Key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

...

我們可以將此帳戶導入 MetaMask,以便開始使用那裡可用的一些Eth測試幣。

為此,首先打開 MetaMask 並啟用測試網絡:

web3 技術堆棧丨教你如何利用EVM構建一個全棧dapp

接下來,將網絡更新為 Localhost 8545:

web3 技術堆棧丨教你如何利用EVM構建一個全棧dapp

接下來,在 MetaMask 中,從帳戶菜單中單擊“導入帳戶”:

web3 技術堆棧丨教你如何利用EVM構建一個全棧dapp

複製並粘貼通過 CLI 註銷的Private Keys之一,然後單擊導入。 導入帳戶后,您應該會看到帳戶中的 Eth:

web3 技術堆棧丨教你如何利用EVM構建一個全棧dapp

現在我們已經部署了一個智能合約和一個可以使用的帳戶,我們可以開始從 React 應用程序與它進行交互。

連接 React 客戶端

在本教程中,我們不會擔心使用 CSS 構建漂亮的 UI 以及所有這些,我們將 100% 專註於核心功能,以幫助您啟動和運行。 如果你願意,你可以從那裡拿走它,讓它看起來不錯。

話雖如此,讓我們回顧一下我們希望從 React 應用程序中實現的兩個目標:

  1. 從智能合約中獲取當前的greeting值
  2. 允許用戶更新greeting的值

了解了這些東西,我們如何做到這一點? 為了實現這一點,我們需要做以下事情:

  1. 創建一個輸入字段和一些本地狀態來管理輸入的值(更新greeting)
  2. 允許應用程序連接到用戶的 MetaMask 帳戶以簽署交易
  3. 創建用於讀取和寫入智能合約的函數

為此,請打開 src/App.js 並使用以下代碼對其進行更新,將 greeterAddress 的值設置為您的智能合約的地址。

import './App.css';
import { useState } from 'react';
import { ethers } from 'ethers'
import Greeter from './artifacts/contracts/Greeter.sol/Greeter.json'

// Update with the contract address logged out to the CLI when it was deployed
const greeterAddress = "your-contract-address"

function App() {
// store greeting in local state
const [greeting, setGreetingValue] = useState()

// request access to the user's MetaMask account
async function requestAccount() {
await window.ethereum.request({ method: 'eth_requestAccounts' });
}

// call the smart contract, read the current greeting value
async function fetchGreeting() {
if (typeof window.ethereum !== 'undefined') {
const provider = new ethers.providers.Web3Provider(window.ethereum)
const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider)
try {
const data = await contract.greet()
console.log('data: ', data)
} catch (err) {
console.log("Error: ", err)
}
}
}

// call the smart contract, send an update
async function setGreeting() {
if (!greeting) return
if (typeof window.ethereum !== 'undefined') {
await requestAccount()
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner()
const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer)
const transaction = await contract.setGreeting(greeting)
await transaction.wait()
fetchGreeting()
}
}

return (
<div className="App">
<header className="App-header">
<button onClick={fetchGreeting}>Fetch Greeting</button>
<button onClick={setGreeting}>Set Greeting</button>
<input onChange={e => setGreetingValue(e.target.value)} placeholder="Set greeting" />
</header>
</div>
);
}

export default App;

要對其進行測試,請啟動 React 服務器:

npm start

當應用程序加載時,您應該能夠獲取當前問候語並將其註銷到控制台。您還應該能夠通過與您的 MetaMask 錢包簽署合約並使用Ether測試幣來更新greeting。

web3 技術堆棧丨教你如何利用EVM構建一個全棧dapp

部署和使用實時測試網絡

有幾個以太坊測試網絡,如 Ropsten、Rinkeby 或 Kovan,我們也可以部署到這些網絡,以便在無需將其部署到主網的情況下獲得可公開訪問的合約版本。在本教程中,我們將部署到 Ropsten 測試網絡。

首先,首先更新您的 MetaMask 錢包以連接到 Ropsten 網絡。

web3 技術堆棧丨教你如何利用EVM構建一個全棧dapp

接下來,通過訪問此測試水龍頭,向自己發送一些測試 Ether 以在本教程的其餘部分使用。

我們可以通過註冊 Infura 或 Alchemy 之類的服務(我在本教程中使用 Infura)來訪問 Ropsten(或任何其他測試網絡)。

在 Infura 或 Alchemy 中創建應用程序后,您將獲得一個如下所示的端點:

https://ropsten.infura.io/v3/your-project-id

請務必在 Infura 或 Alchemy 應用程序配置中設置 ALLOWLIST ETHEREUM ADDRESSES,以包含您將用於部署的帳戶的錢包地址。

要部署到測試網絡,我們需要使用一些額外的網絡信息更新我們的安全帽配置。 我們需要設置的一件事是我們將從中部署的錢包的私鑰。

要獲取私鑰,您可以從 MetaMask 中導出它。

web3 技術堆棧丨教你如何利用EVM構建一個全棧dapp

我建議不要在您的應用程序中硬編碼此值,而是將其設置為環境變量之類的東西。

接下來,使用以下配置添加網絡屬性:

module.exports = {
defaultNetwork: "hardhat",
paths: {
artifacts: './src/artifacts',
},
networks: {
hardhat: {},
ropsten: {
url: "https://ropsten.infura.io/v3/your-project-id",
accounts: [`0x${your-private-key}`]
}
},
solidity: "0.8.4",
};

要部署,請運行以下腳本:

npx hardhat run scripts/deploy.js --network ropsten

部署合約后,您應該能夠開始與之交互。 您現在應該可以在 Etherscan Ropsten測試網瀏覽器上查看實時合約

鑄造代幣

智能合約最常見的用例之一是創建代幣,讓我們看看我們如何做到這一點。 由於我們對所有這些是如何工作的有了更多的了解,所以我們會走得更快一點。

在主合約目錄中創建一個名為 Token.sol 的新文件。

接下來,使用以下智能合約更新 Token.sol:

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "hardhat/console.sol";

contract Token {
string public name = "Nader Dabit Token";
string public symbol = "NDT";
uint public totalSupply = 1000000;
mapping(address => uint) balances;

constructor() {
balances[msg.sender] = totalSupply;
}

function transfer(address to, uint amount) external {
require(balances[msg.sender] >= amount, "Not enough tokens");
balances[msg.sender] -= amount;
balances[to] += amount;
}

function balanceOf(address account) external view returns (uint) {
return balances[account];
}
}

請注意,此代幣合約僅用於演示目的,不符合 ERC20。 我們將在這裡介紹 ERC20 代幣

該合約將創建一個名為“Nader Dabit Token”的新代幣,並將供應量設置為 1000000。

接下來,編譯這個合約:

npx hardhat compile

現在,更新腳本/deploy.js 中的部署腳本以包含這個新的代幣合約:

const hre = require("hardhat");

async function main() {
const [deployer] = await hre.ethers.getSigners();

console.log(
"Deploying contracts with the account:",
deployer.address
);

const Greeter = await hre.ethers.getContractFactory("Greeter");
const greeter = await Greeter.deploy("Hello, World!");

const Token = await hre.ethers.getContractFactory("Token");
const token = await Token.deploy();

await greeter.deployed();
await token.deployed();

console.log("Greeter deployed to:", greeter.address);
console.log("Token deployed to:", token.address);
}

main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});

現在,我們可以將這個新合約部署到本地或 Ropsten 網絡:

npx hardhat run scripts/deploy.js --network localhost

部署合約后,您可以開始將這些代幣發送到其他地址。

為此,讓我們更新我們需要的客戶端代碼以使其工作:

import './App.css';
import { useState } from 'react';
import { ethers } from 'ethers'
import Greeter from './artifacts/contracts/Greeter.sol/Greeter.json'
import Token from './artifacts/contracts/Token.sol/Token.json'

const greeterAddress = "your-contract-address"
const tokenAddress = "your-contract-address"

function App() {
const [greeting, setGreetingValue] = useState()
const [userAccount, setUserAccount] = useState()
const [amount, setAmount] = useState()

async function requestAccount() {
await window.ethereum.request({ method: 'eth_requestAccounts' });
}

async function fetchGreeting() {
if (typeof window.ethereum !== 'undefined') {
const provider = new ethers.providers.Web3Provider(window.ethereum)
console.log({ provider })
const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider)
try {
const data = await contract.greet()
console.log('data: ', data)
} catch (err) {
console.log("Error: ", err)
}
}
}

async function getBalance() {
if (typeof window.ethereum !== 'undefined') {
const [account] = await window.ethereum.request({ method: 'eth_requestAccounts' })
const provider = new ethers.providers.Web3Provider(window.ethereum);
const contract = new ethers.Contract(tokenAddress, Token.abi, provider)
const balance = await contract.balanceOf(account);
console.log("Balance: ", balance.toString());
}
}

async function setGreeting() {
if (!greeting) return
if (typeof window.ethereum !== 'undefined') {
await requestAccount()
const provider = new ethers.providers.Web3Provider(window.ethereum);
console.log({ provider })
const signer = provider.getSigner()
const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer)
const transaction = await contract.setGreeting(greeting)
await transaction.wait()
fetchGreeting()
}
}

async function sendCoins() {
if (typeof window.ethereum !== 'undefined') {
await requestAccount()
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const contract = new ethers.Contract(tokenAddress, Token.abi, signer);
const transation = await contract.transfer(userAccount, amount);
await transation.wait();
console.log(`${amount} Coins successfully sent to ${userAccount}`);
}
}

return (
<div className="App">
<header className="App-header">
<button onClick={fetchGreeting}>Fetch Greeting</button>
<button onClick={setGreeting}>Set Greeting</button>
<input onChange={e => setGreetingValue(e.target.value)} placeholder="Set greeting" />

<br />
<button onClick={getBalance}>Get Balance</button>
<button onClick={sendCoins}>Send Coins</button>
<input onChange={e => setUserAccount(e.target.value)} placeholder="Account ID" />
<input onChange={e => setAmount(e.target.value)} placeholder="Amount" />
</header>
</div>
);
}

export default App;

接下來,運行應用程序:

npm start

我們應該能夠單擊“獲取餘額”並看到我們的帳戶中有 1,000,000 個幣已登出到控制台。

您還應該能夠通過單擊導入代幣在 MetaMask 中查看它們:

web3 技術堆棧丨教你如何利用EVM構建一個全棧dapp

接下來點擊自定義代幣並輸入代幣合約地址,然後添加自定義代幣。 (如果詢問代幣小數,請選擇 0)現在代幣應該在您的錢包中可用:

web3 技術堆棧丨教你如何利用EVM構建一個全棧dapp

接下來,讓我們嘗試將這些幣發送到另一個地址。

為此,請複製另一個帳戶的地址,然後使用更新的 React UI 將它們發送到該地址。當您檢查代幣金額時,它應該等於原始金額減去您發送到地址的金額。

ERC20 代幣

ERC20 代幣標準定義了一組適用於所有 ERC20 代幣的規則,使它們能夠輕鬆地相互交互。 ERC20 讓人們可以很容易地鑄造自己的代幣,這些代幣將與以太坊區塊鏈上的其他人具有互操作性。

讓我們看看如何使用 ERC20 標準構建我們自己的代幣。

首先,安裝 OpenZepplin 智能合約庫,我們將在其中導入基礎 ERC20 代幣:

npm install @openzeppelin/contracts

接下來,我們將通過擴展(或繼承自)ERC20 合約來創建我們的代幣:

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract NDToken is ERC20 {
constructor(string memory name, string memory symbol) ERC20(name, symbol) {
_mint(msg.sender, 100000 * (10 ** 18));
}
}

構造函數允許您設置代幣名稱和符號,_mint 函數允許您鑄造代幣並設置數量。

默認情況下,ERC20 將小數位數設置為 18,因此在我們的 _mint 函數中,我們將 100,000 乘以 10 的 18 次方來鑄造總共 100,000 個代幣,每個代幣有 18 個小數位(類似於 1 Eth 由 10 到 18 wei構成。)

要進行部署,我們需要傳入構造函數值(name和symbol),因此我們可以在部署腳本中執行以下操作:

const NDToken = await hre.ethers.getContractFactory("NDToken");
const ndToken = await NDToken.deploy("Nader Dabit Token", "NDT");

通過擴展原始 ERC20 代幣,您的代幣將繼承以下所有功能和功能:

function name() public view returns (string)
function symbol() public view returns (string)
function decimals() public view returns (uint8)
function totalSupply() public view returns (uint256)
function balanceOf(address _owner) public view returns (uint256 balance)
function transfer(address _to, uint256 _value) public returns (bool success)
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
function approve(address _spender, uint256 _value) public returns (bool success)
function allowance(address _owner, address _spender) public view returns (uint256 remaining)

部署后,您可以使用這些功能中的任何一個與新的智能合約進行交互。 有關 ERC20 代幣的另一個示例,請查看 [Solidity by example)(https://solidity-by-example.org/app/erc20/)

結論

好的,我們在這裡涵蓋了很多內容,但對我來說,這是開始使用這個堆棧的基本知識/核心,這也是我想要擁有的東西,不僅作為一個正在學習所有這些東西的人,而且在未來,如果我需要參考我將來可能需要的任何東西。我希望你學到了很多。

如果您想在 MetaMask 之外支持多個錢包,請查看 Web3Modal,它可以通過相當簡單且可自定義的配置輕鬆地在您的應用中實現對多個提供商的支持。

在我未來的教程和指南中,我將深入研究更複雜的智能合約開發,以及如何將它們部署為子圖以在它們之上公開 GraphQL API 並實現分頁和全文搜索等功能。

我還將介紹如何使用 IPFS 和 Web3 數據庫等技術以去中心化的方式存儲數據。

如果您對未來的教程有任何問題或建議,請在此處發表評論並告訴我。

本文鏈接:https://www.8btc.com/article/6723454

轉載請註明文章出處

(0)
上一篇 2022-01-20 10:35
下一篇 2022-01-20 10:55

相关推荐