Cách tìm nạp và cập nhật dữ liệu từ Ethereum với React và SWR

blog 1Tin tứcDevelopersEnterpriseBlockchain ExplainedEvents and ConferencePressBản tin

Theo dõi bản tin của chúng tôi.

Địa chỉ email

Chúng tôi tôn trọng quyền riêng tư của bạn

Trang chủBlogBlockchain phát triển

Cách tìm nạp và cập nhật dữ liệu từ Ethereum với React và SWR

Dưới đây là cách định cấu hình giao diện người dùng của dapp để cập nhật số dư mã thông báo và chuyển tiền trong ví Ethereum của người dùng. Bởi Lorenzo Sicilia ngày 18 tháng 6 năm 2020Đăng vào ngày 18 tháng 6 năm 2020

tìm nạp dữ liệu với ethereum hero

Ethereum cho phép chúng tôi xây dựng các ứng dụng phi tập trung (dapps). Sự khác biệt chính giữa ứng dụng thông thường và dapp là bạn không cần phải triển khai phụ trợ — ít nhất là miễn là bạn tận dụng được các hợp đồng thông minh khác được triển khai trên mạng chính Ethereum.

Do đó, frontend đóng một vai trò quan trọng. Nó chịu trách nhiệm sắp xếp và quản lý dữ liệu từ các hợp đồng thông minh, xử lý các tương tác với ví (phần cứng hoặc phần mềm) và như thường lệ, quản lý UX. Không chỉ vậy, theo thiết kế, một dapp sử dụng các cuộc gọi JSON-RPC và nó có thể mở một kết nối socket để nhận các bản cập nhật.

Như bạn có thể thấy có một số điều cần sắp xếp nhưng đừng lo lắng, hệ sinh thái đã trưởng thành khá nhiều trong vài tháng qua.

Điều kiện tiên quyết

Trong hướng dẫn này, tôi sẽ cho rằng bạn đã có những thứ sau:

Một ví để kết nối với một nút Geth

Cách tiếp cận đơn giản nhất là cài đặt MetaMask để bạn có thể sử dụng Infura cơ sở hạ tầng ra khỏi hộp.

Một số Ether trong tài khoản của bạn

Khi bạn đang phát triển với Ethereum, tôi thực sự khuyên bạn nên chuyển sang testnet và sử dụng Ether thử nghiệm. Nếu bạn cần tiền cho mục đích thử nghiệm, bạn có thể sử dụng vòi, ví dụ:. https://faucet.rinkeby.io/


Hiểu biết cơ bản về React

Tôi sẽ hướng dẫn bạn từng bước nhưng tôi sẽ cho rằng bạn biết cách hoạt động của React (bao gồm cả hook). Nếu điều gì đó có vẻ không quen thuộc, hãy tham khảo Tài liệu phản ứng.

Một sân chơi React hoạt động

Tôi đã viết hướng dẫn này với Typescript nhưng chỉ có một số thứ được nhập nên với những thay đổi tối thiểu, bạn có thể sử dụng nó như trong Javascript. Tôi đã sử dụng Parcel.js nhưng hãy thoải mái sử dụng Tạo ứng dụng React quá hoặc gói ứng dụng web khác.

Kết nối với Ethereum Mainnet

Khi bạn đã sẵn sàng MetaMask, chúng tôi sẽ sử dụng web3-react để xử lý tương tác với mạng. Nó sẽ cung cấp cho bạn một cách sử dụng hook khá tiện dụngWeb3React, chứa nhiều tiện ích hữu ích để chơi với Ethereum.

Sợi add @ web3-react / core @ web3-react / injection-connector Ngôn ngữ mã: CSS (css)

Sau đó, bạn cần một Nhà cung cấp. Nhà cung cấp tóm tắt kết nối với chuỗi khối Ethereum, để đưa ra các truy vấn và gửi các giao dịch thay đổi trạng thái đã ký.

Chúng tôi sẽ sử dụng Web3Provider từ Ether.js.

Dường như nó đã có một vài thư viện, nhưng khi tương tác với Ethereum, bạn cần phải dịch các loại dữ liệu Javascript sang các loại dữ liệu Solidity. Và, bạn cũng được yêu cầu ký các giao dịch khi bạn muốn thực hiện một hành động. Ether.js cung cấp các chức năng này một cách trang nhã.

Sợi add @ ethersproject / nhà cung cấp Ngôn ngữ mã: CSS (css)

thông báo: gói Ether.js ở trên là phiên bản v5 hiện tại bản beta.

Sau đó, chúng tôi đã sẵn sàng ghi lại một chút hello world để kiểm tra xem chúng tôi có mọi thứ chúng tôi cần hay không:

import React từ ‘react’ import {Web3ReactProvider} từ ‘@ web3-react / core’ import {Web3Provider} từ ‘@ ethersproject / Investors’ import {useWeb3React} từ ‘@ web3-react / core’ import {InjectedConnector} từ ‘@ web3-react / injection-connector ‘export const injectionConnector = new InjectedConnector ({supportChainIds: [1, // Mainet 3, // Ropsten 4, // Rinkeby 5, // Goerli 42, // Kovan],}) hàm getLibrary (nhà cung cấp: bất kỳ): Web3Provider {const library = new Web3Provider (nhà cung cấp) library.pollingInterval = 12000 return library} export const Wallet = () => {const {chainId, account, active, active} = useWeb3React () const onClick = () => Trả về {kích hoạt (injectionConnector)} ( <div> <div>ChainId: {chainId} div> <div>Tài khoản: {account} div> {hoạt động? ( <div>✅ div> ): ( <loại nút ="cái nút" onClick = {onClick}> Nút kết nối> )} div> )} export const App = () => { trở về ( <Web3ReactProvider getLibrary = {getLibrary}> <Ví tiền /> Web3ReactProvider> )} Ngôn ngữ mã: JavaScript (javascript)

Nếu bạn đã làm bài tập về nhà của mình, bạn sẽ có một cái gì đó như sau:

Đầu nối được tiêm.

Đây là những gì chúng tôi đã làm cho đến nay: GIT – bước 1

Cách tìm nạp dữ liệu từ Mainnet

tôi sẽ sử dụng SWR để quản lý việc tìm nạp dữ liệu.

Đây là những gì tôi muốn đạt được.

const {data: balance} = useSWR (["getBalance", tài khoản, "muộn nhất"]) Ngôn ngữ mã: JavaScript (javascript)

Khá mát mẻ &# 128578;

Hãy cùng bật mí thủ thuật! SWR có nghĩa là Stale-While-Revalidate, một chiến lược vô hiệu hóa bộ nhớ cache HTTP được phổ biến bởi RFC 5861.

Đầu tiên SWR trả về dữ liệu từ bộ nhớ cache (cũ), sau đó gửi yêu cầu tìm nạp (xác thực lại) và cuối cùng đi kèm với dữ liệu cập nhật một lần nữa.

SWR chấp nhận một khóa và đằng sau hậu trường sẽ quản lý để giải quyết

Để làm điều đó, SWR cho phép truyền một trình tìm nạp có khả năng giải quyết khóa bằng cách trả về một lời hứa. Hello world của SWR dựa trên các yêu cầu API REST với trình tìm nạp dựa trên API tìm nạp hoặc Axios.

Điều tuyệt vời về SWR là yêu cầu duy nhất để tạo trình tìm nạp là nó phải trả về một lời hứa.

Vì vậy, đây là lần triển khai đầu tiên của tôi về trình tìm nạp cho Ethereum:

const fetcher = (thư viện) => (… args) => {const [method, … params] = args console.log (method, params) return library [method] (… params)} Ngôn ngữ mã: JavaScript (javascript)

Như bạn có thể thấy, nó là một chức năng được áp dụng một phần. Bằng cách đó, tôi có thể đưa vào thư viện (Web3Provider của tôi) khi tôi định cấu hình trình tìm nạp. Sau đó, mỗi khi một khóa thay đổi, chức năng có thể được giải quyết bằng cách trả về lời hứa được yêu cầu.

Bây giờ tôi có thể tạo thành phần của mình

xuất const Số dư = () => {const {account, library} = useWeb3React () const {data: balance} = useSWR ([‘getBalance’, account, ‘new’], {fetcher: fetcher (library),}) if (! balance) {return <div>…div> } trở về <div>Số dư: {balance.toString ()} div> } Ngôn ngữ mã: JavaScript (javascript)

Đối tượng số dư được trả về là BigNumber.

Thành phần cân bằng.

Như bạn có thể thấy, số lượng không được định hình và cực kỳ lớn. Điều này là do Solidity sử dụng Số nguyên lên đến 256 bit.

Để hiển thị số ở định dạng con người có thể đọc được, giải pháp là sử dụng một trong những tiện ích đã nói ở trên từ các tiện ích của Ether.js: formatEther (balance)

sợi install @ ethersproject / unit Ngôn ngữ mã: CSS (css)

Bây giờ tôi có thể làm lại thành phần của mình để xử lý và định dạng BitInt ở dạng con người có thể đọc được:

xuất const Số dư = () => {const {account, library} = useWeb3React () const {data: balance} = useSWR ([‘getBalance’, account, ‘new’], {fetcher: fetcher (library),}) if (! balance) {return <div>…div> } trở về <div>Ξ {parseFloat (formatEther (balance)). ToPre precision (4)} div> } Ngôn ngữ mã: JavaScript (javascript) BitInt ở dạng con người có thể đọc được.

đây là những gì chúng tôi đã làm cho đến nay: GIT bước 2

Cách cập nhật dữ liệu trong thời gian thực

SWR cho thấy một hàm đột biến để cập nhật bộ nhớ cache bên trong của nó.

const {data: balance, mutate} = useSWR ([‘getBalance’, account, ‘new’], {fetcher: fetcher (library),}) const onClick = () => {mutate (new BigNumber (10), false)} Ngôn ngữ mã: JavaScript (javascript)

Hàm đột biến được tự động liên kết với khóa (ví dụ: [‘getBalance’, tài khoản, ‘mới nhất’] mà từ đó nó đã được tạo. Nó chấp nhận hai tham số. Dữ liệu mới và nếu quy trình xác thực sẽ được kích hoạt. Nếu cần, SWR sẽ tự động sử dụng trình tìm nạp để cập nhật bộ đệm &# 128165;

Như dự đoán, các sự kiện Solidity đưa ra một phần tóm tắt nhỏ về chức năng ghi nhật ký của EVM. Các ứng dụng có thể đăng ký và lắng nghe các sự kiện này thông qua giao diện RPC của ứng dụng khách Ethereum.

Ether.js có một API đơn giản để đăng ký một sự kiện:

const {account, library} = useWeb3React () library.on ("chặn số", (blockNumber) => {console.log ({blockNumber})}) Ngôn ngữ mã: JavaScript (javascript)

Bây giờ, hãy kết hợp cả hai phương pháp tiếp cận trong thành phần mới

xuất const Số dư = () => {const {account, library} = useWeb3React () const {data: balance, mutate} = useSWR ([‘getBalance’, account, ‘new’], {fetcher: fetcher (library),}) useEffect (() => {// lắng nghe các thay đổi trên console.log địa chỉ Ethereum (`đang nghe các khối … ‘) library.on (‘ block ‘, () => {console.log (‘update balance …’) mutate (undefined, true)}) // xóa trình lắng nghe khi thành phần không được gắn kết return () => {library.removeAllListaries (‘block’)} // chỉ kích hoạt hiệu ứng trên component mount}, []) if (! balance) {return <div>…div> } trở về <div>Ξ {parseFloat (formatEther (balance)). ToPre precision (4)} div> } Ngôn ngữ mã: JavaScript (javascript)

Ban đầu, SWR sẽ tìm nạp số dư tài khoản và sau đó mỗi khi nhận được sự kiện khối, nó sẽ sử dụng biến đổi để kích hoạt tìm nạp lại.

lưu ý: Chúng tôi đã sử dụng biến đổi (không xác định, đúng) vì chúng tôi không thể truy xuất từ ​​sự kiện hiện tại số dư thực tế mà chúng tôi chỉ kích hoạt tìm nạp lại số dư.

Dưới đây là bản demo nhanh với hai ví Ethereum đang trao đổi một số ETH.

Demo hai ví Ethereum trao đổi ETH.

Đây là những gì chúng tôi đã làm cho đến nay: GIT bước-3

Cách tương tác với hợp đồng thông minh

Cho đến nay, chúng tôi đã minh họa những điều cơ bản của việc sử dụng SWR và cách thực hiện cuộc gọi cơ bản qua Web3Provider. Bây giờ chúng ta hãy khám phá cách tương tác với hợp đồng thông minh.

Ether.js xử lý tương tác hợp đồng thông minh bằng cách sử dụng Giao diện nhị phân ứng dụng hợp đồng (ABI) ABI được tạo bởi Trình biên dịch Solidity.

Giao diện nhị phân ứng dụng hợp đồng (ABI) là cách tiêu chuẩn để tương tác với các hợp đồng trong hệ sinh thái Ethereum, cả từ bên ngoài blockchain và để tương tác hợp đồng với hợp đồng.

Ví dụ: với hợp đồng thông minh đơn giản dưới đây:

độ rắn pragma ^ 0,5,0; hợp đồng Kiểm tra {constructor () public {b = hex"12345678901234567890123456789012"; } event Event (uint được lập chỉ mục a, byte32 b); sự kiện Event2 (uint được lập chỉ mục a, byte32 b); function foo (uint a) public {release Event (a, b); } byte32 b; } Ngôn ngữ mã: JavaScript (javascript)

đây là ABI được tạo ra

[{ "kiểu": "biến cố", "đầu vào": [{ "Tên": "a", "kiểu": "uint256", "lập chỉ mục": thật }, { "Tên": "b", "kiểu": "byte32", "lập chỉ mục": sai } ], "Tên": "Biến cố" }, { "kiểu": "biến cố", "đầu vào": [{ "Tên": "a", "kiểu": "uint256", "lập chỉ mục": thật }, { "Tên": "b", "kiểu": "byte32", "lập chỉ mục": sai } ], "Tên": "Event2" }, { "kiểu": "chức năng", "đầu vào": [{ "Tên": "a", "kiểu": "uint256" }], "Tên": "foo", "đầu ra": []}] Ngôn ngữ mã: JSON / JSON có nhận xét (json)

Để sử dụng ABI, chúng tôi có thể chỉ cần sao chép chúng trực tiếp vào mã của bạn và nhập chúng khi cần thiết. Trong bản demo này, chúng tôi sẽ sử dụng một tiêu chuẩn ERC20 ABI vì chúng tôi muốn lấy số dư của hai mã thông báo: DAI và MKR.

Bước tiếp theo là tạo thành phần

export const TokenBalance = ({ký hiệu, địa chỉ, số thập phân}) => {const {account, library} = useWeb3React () const {data: balance, mutate} = useSWR ([address, ‘balanceOf’, account], {fetcher: fetcher (library, ERC20ABI),}) useEffect (() => {// lắng nghe các thay đổi trên console.log địa chỉ Ethereum (`đang nghe để chuyển … ‘) const contract = new Contract (address, ERC20ABI, library.getSigner ()) const fromMe = contract.filters.Transfer (tài khoản, null) library.on (fromMe, (from, to, amount, event) => {console.log (‘Transfer | sent’, {from, to, amount, event}) mutate (undefined, true)}) const toMe = contract.filters.Transfer (null, account) library.on (toMe, (from , đến, số tiền, sự kiện) => {console.log (‘Chuyển | nhận’, {từ, đến, số tiền, sự kiện}) mutate (không xác định, đúng)}) // loại bỏ trình nghe khi thành phần được ngắt kết nối return () => {library.removeAllListaries (toMe) library.removeAllListaries (fromMe)} // chỉ kích hoạt hiệu ứng trên component mount}, []) if (! balance) {return <div>…div> } trở về ( <div> {parseFloat (formatUnits (balance, decimals)). toPre precision (4)} {Symbol} div> )} Ngôn ngữ mã: JavaScript (javascript)

Hãy phóng to. Có hai điểm khác biệt chính:

Định nghĩa chính

Khóa, được sử dụng bởi useSWR ([address, ‘balanceOf’, account])), cần bắt đầu bằng địa chỉ Ethereum chứ không phải là một phương thức. Do đó, trình tìm nạp có thể nhận ra những gì chúng ta muốn đạt được và sử dụng ABI.

Hãy cấu trúc lại trình tìm nạp cho phù hợp:

const fetcher = (thư viện: Web3Provider, abi ?: any) => (… args) => {const [arg1, arg2, … params] = args // đó là một hợp đồng if (isAddress (arg1)) {const address = arg1 const method = arg2 const contract = new Contract (address, abi, library.getSigner () ) return contract [method] (… params)} // đó là một cuộc gọi eth const method = arg1 return library [method] (arg2, … params)} Ngôn ngữ mã: JavaScript (javascript)

Bây giờ chúng ta có một trình tìm nạp có mục đích chung có khả năng tương tác với các lệnh gọi JSON-RPC của Ethereum. &# 128588;

Bộ lọc nhật ký

Một khía cạnh khác là cách lắng nghe các sự kiện ERC20. Ether.js cung cấp một cách tiện dụng để định cấu hình bộ lọc dựa trên các chủ đề và tên của sự kiện. Thông tin thêm về chủ đề là gì có thể được tìm thấy trong Tài liệu về độ vững chắc.

const contract = new Contract (address, ERC20ABI, library.getSigner ()) const fromMe = contract.filters.Transfer (account, null) Ngôn ngữ mã: JavaScript (javascript)

Khi bạn đã tạo một phiên bản hợp đồng với ABI, thì bạn có thể chuyển bộ lọc đến phiên bản thư viện.

Cảnh báo:

Bạn có thể bị dụ sử dụng trực tiếp số tiền trong sự kiện ERC20 để tăng hoặc giảm số dư.

Hãy nhận biết về con rồng. Khi bạn thiết lập trình tìm nạp, bạn đã chuyển một áo choàng dưới dạng gọi lại cho hàm on, có chứa giá trị số dư tại thời điểm.

Điều này có thể được khắc phục bằng cách sử dụng useRef nhưng để đơn giản, hãy xác thực lại bộ nhớ cache để đảm bảo số dư luôn mới: mutate (không xác định, đúng)

Bây giờ chúng tôi có tất cả các phần được yêu cầu. Chút cuối cùng là một chút keo.

Tôi đã định cấu hình một vài hằng số để có một cách tốt để ánh xạ thành phần TokenBalance của tôi với danh sách các mã thông báo tùy thuộc vào mạng nơi chúng tôi đang làm việc:

export const Networks = {MainNet: 1, Rinkeby: 4, Ropsten: 3, Kovan: 42,} export interface IERC20 {symbol: string address: string decimals: number name: string} export const TOKENS_BY_NETWORK: {[key: number]: IERC20 []} = {[Networks.Rinkeby]: [{địa chỉ: "0x5592EC0cfb4dbc12D3aB100b257153436a1f0FEa", Biểu tượng: "DAI", Tên: "Dai", số thập phân: 18,}, {địa chỉ: "0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85", Biểu tượng: "MKR", Tên: "Nhà sản xuất", số thập phân: 18,},],} Ngôn ngữ mã: JavaScript (javascript)

Khi chúng tôi có các hằng số, thật dễ dàng để ánh xạ các mã thông báo đã định cấu hình với thành phần của tôi:

xuất const TokenList = ({chainId}) => { trở về ( <> {TOKENS_BY_NETWORK [chainId] .map ((token) => ( <TokenBalance key = {token.address} {… token} /> ))})} Ngôn ngữ mã: JavaScript (javascript)

Tất cả các thiết lập! Bây giờ chúng tôi có một ví Ethereum để tải số dư ether và token. Và nếu người dùng gửi hoặc nhận tiền, giao diện người dùng của ví sẽ được cập nhật.

Một ví Ethereum tải số dư ether và token.

Đây là những gì chúng tôi đã làm cho đến nay: GIT bước-4

Tái cấu trúc

Hãy di chuyển mọi thành phần trong một tệp riêng biệt và làm cho trình tìm nạp khả dụng trên toàn cầu bằng cách sử dụng nhà cung cấp SWRConfig.

<Giá trị SWRConfig = {{fetcher: fetcher (thư viện, ERC20ABI)}}> <EthBalance /> <TokenList chainId = {chainId} /> <SWRConfig />Ngôn ngữ mã: HTML, XML (xml)

Với SWRConfig, chúng tôi có thể định cấu hình một số tùy chọn luôn có sẵn, để chúng tôi có thể sử dụng SWR thuận tiện hơn.

const {data: balance, mutate} = useSWR ([address, ‘balanceOf’, account]) Ngôn ngữ mã: JavaScript (javascript)

Đây là mọi thứ sau khi tái cấu trúc: GIT bước-5

Gói (lại

SWR và Ether.js là hai thư viện tốt để làm việc nếu bạn muốn hợp lý hóa chiến lược tìm nạp dữ liệu của mình với Ethereum dapp.

Ưu điểm chính
  • Cách tiếp cận so sánh
  • Dữ liệu luôn mới thông qua các ổ cắm web hoặc tùy chọn SWR
  • Tránh phát minh lại bánh xe để quản lý trạng thái với ngữ cảnh React tùy chỉnh

Nếu bạn sử dụng nhiều hợp đồng thông minh trong dapp của mình và bạn thích hướng dẫn này, tôi đã tổng hợp trình tìm nạp web3 thành một ứng dụng nhỏ: swr-eth (Các ngôi sao được đánh giá cao &# 128123;)

Và cuối cùng, đây là repo GIT đầy đủ: (https://github.com/aboutlo/swr-eth-tutorial).

Nhận thêm hướng dẫn về Ethereum trực tiếp đến Hộp thư đến của bạn

Đăng ký bản tin của chúng tôi để biết các khóa học, công cụ, mẹo chuyên nghiệp mới nhất dành cho nhà phát triển Ethereum, v.v.. InfuraMetaMaskNewsletterĐăng ký nhận bản tin của chúng tôi để nhận tin tức mới nhất về Ethereum, các giải pháp doanh nghiệp, tài nguyên dành cho nhà phát triển và hơn thế nữa.Cách xây dựng một sản phẩm chuỗi khối thành côngHội thảo trên web

Cách xây dựng một sản phẩm chuỗi khối thành công

Cách thiết lập và chạy Ethereum NodeHội thảo trên web

Cách thiết lập và chạy Ethereum Node

Cách xây dựng API Ethereum của riêng bạnHội thảo trên web

Cách xây dựng API Ethereum của riêng bạn

Cách tạo mã thông báo xã hộiHội thảo trên web

Cách tạo mã thông báo xã hội

Sử dụng các công cụ bảo mật trong phát triển hợp đồng thông minhHội thảo trên web

Sử dụng các công cụ bảo mật trong phát triển hợp đồng thông minh

Tương lai của tài sản kỹ thuật số tài chính và DeFiHội thảo trên web

Tương lai của tài chính: Tài sản kỹ thuật số và DeFi

Mike Owergreen Administrator
Sorry! The Author has not filled his profile.
follow me
Like this post? Please share to your friends:
Adblock
detector
map