1. トランザクションのライフサイクルの処理

1.1. なぜ重要なのか?

スマートコントラクトとのやり取りにおいて最も課題となるのは、トランザクションの送信速度や、ノードからの結果が返ってくるまでの待ち時間です。これはユーザー体験(UX)に大きな影響を与える特性です。トランザクションでは、エラー、リバート、ガス不足などの問題が発生する可能性があるため、ユーザーインターフェースを設計する際には、ユーザーが現在の状況を明確に把握できるよう、トランザクションのライフサイクル全体を適切に処理するよう配慮する必要があります。

1.2. Wagmiはどのようなサービスを提供していますか?

WagmiのReact Hooksには、トランザクションのライフサイクルを管理するのに役立つ多くの機能があります。例:

useReadContract

Wagmiの useReadContract hookを呼び出すと、データが返されます 関数 変更せずに 状態. さらに、このフックはステータスオブジェクトも返します(例: エラー, 処理中) これにより、ユーザーにその取引のステータスを表示できるようになります。

// 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の useWriteContract hookは データ …を含むオブジェクト ハッシュ を呼び出した後のトランザクションの 関数 それが 状態 スマートコントラクトの。

データ
`WriteContractReturnType | undefined`

デフォルトは `undefined`
最後に正常に解決されたデータ 

さらに、このフックは私たちに 処理中 トランザクションの保留状態を表示するために使用できるオブジェクト。

さらに、Wagmiでは以下のサービスも提供しています useWaitForTransactionReceipt トランザクションの結果を待機するためのフックで、2つの戻り変数があります: 読み込み中, isSuccess.

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>
  )
}