1. Xử lý vòng đời giao dịch
1.1. Tại sao điều đó lại quan trọng?
Điểm yếu nhất khi tương tác với hợp đồng thông minh là tốc độ gửi giao dịch và chờ nhận kết quả từ node. Đây là đặc điểm ảnh hưởng rất lớn đến trải nghiệm người dùng (UX). Giao dịch có thể gặp các vấn đề như lỗi, hoàn tác, thiếu gas, v.v., vì vậy khi thiết kế giao diện người dùng, chúng ta phải chú ý xử lý toàn bộ vòng đời giao dịch để người dùng có thể biết rõ trạng thái hiện tại.
1.2. Wagmi làm gì?
React Hooks trong Wagmi có nhiều tính năng giúp bạn quản lý vòng đời giao dịch. Ví dụ:
useReadContract
Wagmi's useReadContract Hook trả về dữ liệu cho chúng ta khi gọi chức năng không thay đổi tình trạngNgoài ra, hook cũng trả về một đối tượng trạng thái (ví dụ: lỗi, đang chờ xử lý) để chúng ta có thể hiển thị cho người dùng trạng thái giao dịch tương ứng.
// import BaseError and hook useReadContract
import { type BaseError, useReadContract } from 'wagmi'
// import the smart contract's abi file to get the function's interface
import { abi } from './abi'
function ReadContract() {
const {
data: balance, // assign the returned data to the balance variable
error, // initialize error variable
isPending // initialize the isPending variable
} = useReadContract({
abi, // abi của function
functionName: 'balanceOf', // function name you want to call
args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], // Pass variables to the function
})
// If isPending is true, the text "Loading..." is displayed, otherwise it disappears
if (isPending) return <div>Loading...</div>
// If there is an error, display the div with error message
if (error)
return (
<div>
Error: {(error as BaseError).shortMessage || error.message}
</div>
)
return (
// Displays the balance (if any) after converting to string format
<div>Balance: {balance?.toString()}</div>
)
}useWriteContract
Wagmi's useWriteContract móc trả lại cho chúng ta một dữ liệu đối tượng chứa băm của giao dịch sau khi gọi chức năng điều đó thay đổi tình trạng của hợp đồng thông minh.
dữ liệu `WriteContractReturnType | undefined`
Mặc định là `undefined`
Dữ liệu cuối cùng được giải quyết thành công cho đột biến này.Ngoài ra, đoạn mã này cũng trả về cho chúng ta một đang chờ xử lý Đối tượng mà chúng ta có thể sử dụng để hiển thị trạng thái chờ xử lý của giao dịch.
Ngoài ra, Wagmi cũng cung cấp useWaitForTransactionReceipt Móc nối cho phép chúng ta chờ kết quả giao dịch với 2 biến trả về: đang tải, isSuccess.
Dưới đây là một ví dụ từ tài liệu hướng dẫn của Wagmi v2:
import * as React from 'react' // import react into file
// import BaseError, and 2 hooks useWaitForTransactionReceipt, useWriteContract from wagmi library
import {
type BaseError,
useWaitForTransactionReceipt,
useWriteContract
} from 'wagmi'
// import the smart contract's abi file to get the function's interface
import { abi } from './abi'
export function MintNFT() {
const {
data: hash, // assign the returned data to a variable named hash
error, // assign error object to error variable
isPending, // assign the isPending object to the isPending variable
writeContract // initialize the writeContract function for use
} = useWriteContract()
// function dùng để submit form
async function submit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault()
const formData = new FormData(e.target as HTMLFormElement)
const tokenId = formData.get('tokenId') as string
writeContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // contract address
abi, // abi of contract
functionName: 'mint', // function name you want to call
args: [BigInt(tokenId)], // pass input to function
})
}
// Call the useWaitForTransactionReceipt hook to initialize the isConfirming and isConfirmed states
const { isLoading: isConfirming, isSuccess: isConfirmed } =
useWaitForTransactionReceipt({
hash,
})
// Return format of React
return (
<form onSubmit={submit}>
<input name="address" placeholder="0xA0Cf…251e" required />
<input name="value" placeholder="0.05" required />
// If isPending is true, the button will be disabled
<button
disabled={isPending}
type="submit"
>
{isPending ? 'Confirming...' : 'Mint'}
// If isPending is true, display the word "Confirming...", otherwise display the word "Mint"
</button>
// If hash is true, the div containing the transaction hash is displayed, otherwise it disappears
{hash && <div>Transaction Hash: {hash}</div>}
// If isConfirming is true then display the div with the text "Waiting for confirmation..."
{isConfirming && <div>Waiting for confirmation...</div>}
// If isConfirmed is true, display the div with the text "Transaction confirmed."
{isConfirmed && <div>Transaction confirmed.</div>}
// If there is an error, display the div with error message
{error && (
<div>Error: {(error as BaseError).shortMessage || error.message}</div>
)}
</form>
)
}