Cara Mengambil dan Memperbarui Data Dari Ethereum dengan React dan SWR

blog 1NewsPengembangEnterpriseBlockchain DijelaskanAcara dan KonferensiTekanBuletin

Berlangganan newsletter kami.

Alamat email

Kami menghormati privasi Anda

BerandaBlogPengembangan Blockchain

Cara Mengambil dan Memperbarui Data Dari Ethereum dengan React dan SWR

Berikut cara mengkonfigurasi frontend dapp Anda sehingga saldo token dan transfer dana diperbarui di dompet Ethereum pengguna Anda. Oleh Lorenzo SiciliaJuni 18, 2020Diposting pada 18 Juni 2020

ambil data dengan ethereum hero

Ethereum memungkinkan kita membangun aplikasi terdesentralisasi (dapps). Perbedaan utama antara aplikasi biasa dan dapp adalah Anda tidak perlu menerapkan backend — setidaknya selama Anda memanfaatkan kontrak pintar lain yang diterapkan di mainnet Ethereum.

Karena itu, frontend memainkan peran utama. Ini bertanggung jawab untuk menyusun dan melepaskan data dari kontrak pintar, menangani interaksi dengan dompet (perangkat keras atau perangkat lunak) dan, seperti biasa, mengelola UX. Tidak hanya itu, secara desain, dapp menggunakan panggilan JSON-RPC dan dapat membuka koneksi soket untuk menerima pembaruan.

Seperti yang Anda lihat, ada beberapa hal yang harus diatur, tetapi jangan khawatir, ekosistemnya telah cukup matang dalam beberapa bulan terakhir..

Prasyarat

Selama tutorial ini, saya akan menganggap Anda sudah memiliki yang berikut ini:

Dompet untuk terhubung ke node Geth

Pendekatan paling sederhana adalah menginstal MetaMask agar bisa Anda gunakan Infura infrastruktur di luar kotak.

Beberapa Ether di akun Anda

Saat Anda mengembangkan dengan Ethereum, saya sangat menyarankan Anda untuk beralih ke testnet dan menggunakan uji Ether. Jika Anda membutuhkan dana untuk tujuan pengujian, Anda dapat menggunakan faucet mis. https://faucet.rinkeby.io/


Pemahaman dasar tentang React

Saya akan memandu Anda langkah demi langkah tetapi saya akan menganggap Anda tahu cara kerja React (termasuk hook). Jika ada sesuatu yang tampak asing, berkonsultasilah dengan Dokumentasi React.

Taman bermain React yang berfungsi

Saya menulis tutorial ini dengan Typecript tetapi hanya beberapa hal yang diketik jadi dengan sedikit perubahan Anda dapat menggunakannya seperti di Javascript juga. Saya dulu Parcel.js tapi jangan ragu untuk menggunakannya Buat Aplikasi React juga atau bundler aplikasi web lainnya.

Hubungkan ke Ethereum Mainnet

Setelah Anda menyiapkan MetaMask, kami akan menggunakan web3-react untuk menangani interaksi dengan jaringan. Ini akan memberi Anda hook useWeb3React yang cukup berguna, yang berisi banyak utilitas berguna untuk bermain dengan Ethereum.

benang tambahkan @ web3-react / core @ web3-react / injected-connector Bahasa kode: CSS (css)

Maka Anda membutuhkan Penyedia. Penyedia mengabstraksi koneksi ke blockchain Ethereum, untuk mengeluarkan kueri dan mengirim transaksi perubahan status yang ditandatangani.

Kami akan menggunakan Web3Provider dari Ether.js.

Tampaknya sudah memiliki beberapa pustaka, tetapi ketika berinteraksi dengan Ethereum Anda perlu menerjemahkan tipe data Javascript ke yang Solidity. Dan, Anda juga diharuskan untuk menandatangani transaksi ketika Anda ingin melakukan suatu tindakan. Ether.js dengan elegan menyediakan fungsionalitas ini.

benang tambahkan @ ethersproject / provider Bahasa kode: CSS (css)

pemberitahuan: paket Ether.js di atas adalah v5 yang saat ini ada beta.

Setelah itu kami siap menuliskan halo dunia minimal untuk memeriksa apakah kami memiliki semua yang kami butuhkan:

impor React dari ‘react’ import {Web3ReactProvider} dari ‘@ web3-react / core’ impor {Web3Provider} dari ‘@ ethersproject / provider’ impor {useWeb3React} dari ‘@ web3-react / core’ import {InjectedConnector} dari ‘@ web3-react / injected-connector ‘export const injectedConnector = new InjectedConnector ({supportChainIds: [1, // Mainet 3, // Ropsten 4, // Rinkeby 5, // Goerli 42, // Kovan],}) fungsi getLibrary (provider: any): Web3Provider {const library = new Web3Provider (provider) library.pollingInterval = 12000 return library} ekspor const Wallet = () => {const {chainId, akun, aktifkan, aktif} = useWeb3React () const onClick = () => {aktifkan (injectedConnector)} kembali ( <div> <div>ChainId: {chainId} div> <div>Akun: {account} div> {aktif? ( <div>✅ div> ): ( <jenis tombol ="tombol" onClick = {onClick}> Tombol Hubungkan> )} div> )} ekspor const App = () => {kembali ( <Web3ReactProvider getLibrary = {getLibrary}> <Dompet /> Web3ReactProvider> )} Bahasa kode: JavaScript (javascript)

Jika Anda mengerjakan pekerjaan rumah Anda, Anda harus memiliki sesuatu seperti ini:

Konektor yang disuntikkan.

Inilah yang kami lakukan sejauh ini: GIT – langkah-1

Cara Mengambil Data dari Mainnet

saya akan gunakan SWR untuk mengelola pengambilan data.

Inilah yang ingin saya capai.

const {data: balance} = useSWR (["getBalance", Akun, "terbaru"]) Bahasa kode: JavaScript (javascript)

Cukup keren &# 128578;

Mari kita ungkapkan triknya! SWR berarti Stale-While-Revalidate, strategi pembatalan cache HTTP yang dipopulerkan oleh RFC 5861.

SWR pertama-tama mengembalikan data dari cache (usang), kemudian mengirim permintaan pengambilan (validasi ulang), dan terakhir datang dengan data terbaru lagi.

SWR menerima kunci dan di belakang layar akan berhasil menyelesaikannya

Untuk melakukan itu, SWR memungkinkan penerusan fetcher yang mampu menyelesaikan kunci dengan mengembalikan sebuah promise. Halo dunia SWR didasarkan pada permintaan REST API dengan fetcher berdasarkan fetch API atau Axios.

Hal yang brilian tentang SWR adalah bahwa satu-satunya persyaratan untuk membuat fetcher adalah ia harus mengembalikan janji.

Jadi, inilah implementasi fetcher pertama saya untuk Ethereum:

const fetcher = (perpustakaan) => (… args) => {const [method, … params] = args console.log (method, params) return library [method] (… params)} Bahasa kode: JavaScript (javascript)

Seperti yang Anda lihat, ini adalah fungsi yang diterapkan sebagian. Dengan cara itu, saya dapat memasukkan pustaka (Penyedia Web3 saya) saat saya mengonfigurasi pengambil. Nanti, setiap kali ada perubahan kunci, fungsinya bisa diselesaikan dengan mengembalikan promise yang diperlukan.

Sekarang saya dapat membuat komponen saya

ekspor const Balance = () => {const {account, library} = useWeb3React () const {data: balance} = useSWR ([‘getBalance’, account, ‘latest’], {fetcher: fetcher (library),}) if (! balance) {return <div>…div> } kembali <div>Saldo: div {balance.toString ()}> } Bahasa kode: JavaScript (javascript)

Objek keseimbangan yang dikembalikan adalah BigNumber.

Komponen keseimbangan.

Seperti yang Anda lihat, nomor tersebut tidak diformat dan sangat besar. Ini karena Solidity menggunakan Integer hingga 256 bit.

Untuk menampilkan angka dalam format yang dapat dibaca manusia, solusinya menggunakan salah satu utilitas yang disebutkan di atas dari utilitas Ether.js: formatEther (keseimbangan)

instal benang @ ethersproject / units Bahasa kode: CSS (css)

Sekarang saya dapat mengerjakan ulang komponen saya untuk menangani dan memformat BitInt dalam bentuk yang dapat dibaca manusia:

ekspor const Balance = () => {const {account, library} = useWeb3React () const {data: balance} = useSWR ([‘getBalance’, account, ‘latest’], {fetcher: fetcher (library),}) if (! balance) {return <div>…div> } kembali <div>Ξ div {parseFloat (formatEther (balance)). ToPrecision (4)}> } Bahasa kode: JavaScript (javascript) BitInt dalam bentuk yang dapat dibaca manusia.

ini yang kami lakukan sejauh ini: GIT langkah-2

Cara Memperbarui Data Secara Real-Time

SWR memperlihatkan fungsi mutasi untuk memperbarui cache internalnya.

const {data: balance, mutate} = useSWR ([‘getBalance’, account, ‘latest’], {fetcher: fetcher (library),}) const onClick = () => {mutate (new BigNumber (10), false)} Bahasa kode: JavaScript (javascript)

Fungsi mutasi secara otomatis terikat ke kunci (misalnya [‘getBalance’, akun, ‘terbaru’] dari mana ia telah dibuat. Ia menerima dua parameter. Data baru dan jika validasi harus dipicu. Jika diperlukan, SWR akan secara otomatis menggunakan pengambil untuk memperbarui cache &# 128165;

Seperti yang diantisipasi, acara Solidity memberikan abstraksi kecil di atas fungsi logging EVM. Aplikasi dapat berlangganan dan mendengarkan acara ini melalui antarmuka RPC klien Ethereum.

Ether.js memiliki API sederhana untuk berlangganan sebuah acara:

const {akun, perpustakaan} = useWeb3React () library.on ("blockNumber", (blockNumber) => {console.log ({blockNumber})}) Bahasa kode: JavaScript (javascript)

Sekarang mari kita gabungkan kedua pendekatan dalam komponen baru

ekspor const Balance = () => {const {account, library} = useWeb3React () const {data: balance, mutate} = useSWR ([‘getBalance’, account, ‘latest’], {fetcher: fetcher (library),}) useEffect (() => {// dengarkan perubahan pada konsol alamat Ethereum.log (`mendengarkan blok …`) library.on (‘block’, () => {console.log (‘update balance …’) mutate (undefined, true)}) // hapus listener saat komponen dilepas return () => {library.removeAllListeners (‘block’)} // picu efek hanya pada pemasangan komponen}, []) if (! balance) {return <div>…div> } kembali <div>Ξ div {parseFloat (formatEther (balance)). ToPrecision (4)}> } Bahasa kode: JavaScript (javascript)

Awalnya, SWR akan mengambil saldo akun, dan kemudian setiap kali menerima peristiwa pemblokiran, SWR akan menggunakan mutate untuk memicu pengambilan ulang.

pemberitahuan: Kami menggunakan mutate (undefined, true) karena kami tidak dapat mengambil saldo aktual dari peristiwa saat ini, kami baru saja memicu pengambilan ulang saldo.

Di bawah ini adalah demo singkat dengan dua dompet Ethereum yang menukar beberapa ETH.

Demo dua dompet Ethereum yang bertukar ETH.

Inilah yang kami lakukan sejauh ini: GIT langkah-3

Bagaimana Berinteraksi dengan Kontrak Cerdas

Sejauh ini kami mengilustrasikan dasar-dasar penggunaan SWR dan cara melakukan panggilan dasar melalui Web3Provider. Sekarang mari kita temukan cara berinteraksi dengan kontrak pintar.

Ether.js menangani interaksi kontrak pintar menggunakan Contract Application Binary Interface (ABI) ABI yang dihasilkan oleh Solidity Compiler.

Contract Application Binary Interface (ABI) adalah cara standar untuk berinteraksi dengan kontrak di ekosistem Ethereum, baik dari luar blockchain maupun untuk interaksi kontrak ke kontrak..

Misalnya, diberikan kontrak pintar sederhana di bawah ini:

soliditas pragma ^ 0.5.0; Uji kontrak {konstruktor () publik {b = hex"12345678901234567890123456789012"; } Acara acara (uint diindeks a, bytes32 b); event Event2 (uint mengindeks a, bytes32 b); function foo (uint a) public {emit Event (a, b); } byte32 b; } Bahasa kode: JavaScript (javascript)

ini adalah ABI yang dihasilkan

[{ "Tipe": "peristiwa", "masukan": [{ "nama": "Sebuah", "Tipe": "uint256", "diindeks": true}, { "nama": "b", "Tipe": "byte32", "diindeks": Salah } ], "nama": "Peristiwa" }, { "Tipe": "peristiwa", "masukan": [{ "nama": "Sebuah", "Tipe": "uint256", "diindeks": true}, { "nama": "b", "Tipe": "byte32", "diindeks": Salah } ], "nama": "Acara2" }, { "Tipe": "fungsi", "masukan": [{ "nama": "Sebuah", "Tipe": "uint256" }], "nama": "foo", "keluaran": []}] Bahasa kode: JSON / JSON dengan Komentar (json)

Untuk menggunakan ABI, kita cukup menyalinnya langsung ke kode Anda dan mengimpornya di tempat yang diperlukan. Dalam demo ini, kami akan menggunakan standar ERC20 ABI karena kami ingin mengambil saldo dua token: DAI dan MKR.

Langkah selanjutnya adalah membuat komponen

ekspor const TokenBalance = ({simbol, alamat, desimal}) => {const {account, library} = useWeb3React () const {data: balance, mutate} = useSWR ([alamat, ‘balanceOf’, akun], {fetcher: fetcher (library, ERC20ABI),}) useEffect (() => {// dengarkan perubahan pada alamat Ethereum console.log (`listening for Transfer …`) const contract = new Contract (address, ERC20ABI, library.getSigner ()) const fromMe = contract.filters.Transfer (akun, null) library.on (fromMe, (from, to, number, event) => {console.log (‘Transfer | sent’, {from, to, number, event}) mutate (undefined, true)}) const toMe = contract.filters.Transfer (null, account) library.on (toMe, (from , kepada, jumlah, peristiwa) => {console.log (‘Transfer | accept’, {from, to, number, event}) mutate (undefined, true)}) // hapus listener saat komponen dilepas return () => {library.removeAllListeners (toMe) library.removeAllListeners (fromMe)} // picu efek hanya pada pemasangan komponen}, []) if (! balance) {return <div>…div> } kembali ( <div> {parseFloat (formatUnits (balance, decimals)). toPrecision (4)} div {symbol}> )} Bahasa kode: JavaScript (javascript)

Mari perbesar. Ada dua perbedaan utama:

Definisi kunci

Kuncinya, yang digunakan oleh useSWR ([address, ‘balanceOf’, account])), harus dimulai dengan alamat Ethereum daripada metode. Karena itu, pengambil dapat mengenali apa yang ingin kita capai dan menggunakan ABI.

Mari kita lakukan refaktorisasi pengambilan sesuai:

const fetcher = (perpustakaan: Web3Provider, abi ?: any) => (… args) => {const [arg1, arg2, … params] = args // itu adalah kontrak jika (isAddress (arg1)) {const address = arg1 metode const = arg2 const kontrak = Kontrak baru (alamat, abi, library.getSigner () ) return contract [metode] (… params)} // ini adalah eth call const method = arg1 return library [metode] (arg2, … params)} Bahasa kode: JavaScript (javascript)

Sekarang kami memiliki pengambil tujuan umum yang mampu berinteraksi dengan panggilan JSON-RPC Ethereum. &# 128588;

Filter log

Aspek lainnya adalah cara mendengarkan peristiwa ERC20. Ether.js menyediakan cara praktis untuk mengonfigurasi filter berdasarkan topik dan nama acara. Info lebih lanjut tentang apa itu topik dapat ditemukan di Dokumen soliditas.

const contract = kontrak baru (alamat, ERC20ABI, library.getSigner ()) const fromMe = contract.filters.Transfer (akun, null) Bahasa kode: JavaScript (javascript)

Setelah Anda membuat instance kontrak dengan ABI, Anda dapat meneruskan filter ke instance library.

Peringatan:

Anda bisa tergoda untuk menggunakan jumlah di acara ERC20 secara langsung untuk menambah atau mengurangi saldo.

Waspadai naga itu. Saat menyiapkan fetcher, Anda meneruskan clojure sebagai callback ke fungsi on, yang berisi nilai saldo pada saat itu..

Ini bisa diperbaiki menggunakan useRef tetapi demi kesederhanaan, mari kita validasi ulang cache untuk memastikan saldo segar: mutate (undefined, true)

Kami sekarang memiliki semua bagian yang dibutuhkan. Bagian terakhir adalah sedikit lem.

Saya mengonfigurasi beberapa konstanta untuk mendapatkan cara yang bagus untuk memetakan komponen TokenBalance saya ke daftar token tergantung pada jaringan tempat kami bekerja:

ekspor const Jaringan = {MainNet: 1, Rinkeby: 4, Ropsten: 3, Kovan: 42,} ekspor antarmuka IERC20 {simbol: alamat string: desimal string: nama nomor: string} ekspor const TOKENS_BY_NETWORK: {[key: nomor]: IERC20 []} = {[Networks.Rinkeby]: [{alamat: "0x5592EC0cfb4dbc12D3aB100b257153436a1f0FEa", simbol: "DAI", nama: "Dai", desimal: 18,}, {alamat: "0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85", simbol: "MKR", nama: "Pembuat", desimal: 18,},],} Bahasa kode: JavaScript (javascript)

Setelah kami memiliki konstanta, mudah untuk memetakan token yang dikonfigurasi ke komponen saya:

ekspor const TokenList = ({chainId}) => {kembali ( <> {TOKENS_BY_NETWORK [chainId] .map ((token) => ( <TokenBalance key = {token.address} {… token} /> ))})} Bahasa kode: JavaScript (javascript)

Siap! Sekarang kami memiliki dompet Ethereum yang memuat saldo eter dan token. Dan jika pengguna mengirim atau menerima dana, UI dompet diperbarui.

Dompet Ethereum yang memuat saldo eter dan token.

Inilah yang kami lakukan sejauh ini: GIT langkah-4

Refactoring

Mari kita pindahkan setiap komponen dalam file terpisah dan jadikan fetcher tersedia secara global menggunakan penyedia SWRConfig.

<Nilai SWRConfig = {{fetcher: fetcher (library, ERC20ABI)}}> <EthBalance /> <TokenList chainId = {chainId} /> <SWRConfig />Bahasa kode: HTML, XML (xml)

Dengan SWRConfig kita dapat mengkonfigurasi beberapa opsi seperti yang selalu tersedia, sehingga kita dapat menggunakan SWR dengan lebih nyaman.

const {data: balance, mutate} = useSWR ([address, ‘balanceOf’, akun]) Bahasa kode: JavaScript (javascript)

Ini semuanya setelah pemfaktoran ulang: GIT langkah-5

Bungkus

SWR dan Ether.js adalah dua perpustakaan yang bagus untuk digunakan jika Anda ingin menyederhanakan strategi pengambilan data Anda dengan Ethereum dapp.

Keuntungan utama
  • Pendekatan deklaratif
  • Data selalu segar melalui soket web atau opsi SWR
  • Hindari menciptakan kembali roda untuk manajemen negara dengan konteks React kustom

Jika Anda menggunakan beberapa kontrak pintar di dapp Anda dan Anda menyukai tutorial ini, saya menggeneralisasi web3 fetcher menjadi sebuah kegunaan kecil: swr-eth (Bintang dihargai &# 128123;)

Dan terakhir, inilah repo GIT lengkapnya: (https://github.com/aboutlo/swr-eth-tutorial).

Dapatkan Lebih Banyak Tutorial Ethereum Langsung ke Kotak Masuk Anda

Berlangganan buletin kami untuk kursus pengembang Ethereum terbaru, alat, kiat pro, dan banyak lagi. InfuraMetaMaskNewsletterBerlangganan buletin kami untuk berita Ethereum terbaru, solusi perusahaan, sumber daya pengembang, dan banyak lagi Alamat emailKonten EksklusifCara Membangun Produk Blockchain yang BerhasilWebinar

Cara Membangun Produk Blockchain yang Berhasil

Cara Mengatur dan Menjalankan Node EthereumWebinar

Cara Mengatur dan Menjalankan Node Ethereum

Cara Membangun API Ethereum Anda SendiriWebinar

Cara Membangun API Ethereum Anda Sendiri

Cara Membuat Token SosialWebinar

Cara Membuat Token Sosial

Menggunakan Alat Keamanan dalam Pengembangan Kontrak CerdasWebinar

Menggunakan Alat Keamanan dalam Pengembangan Kontrak Cerdas

Masa Depan Keuangan Aset Digital dan DeFiWebinar

Masa Depan Keuangan: Aset Digital dan 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