🔔

【Ethers.js × Solidity】Eventの取り扱い方

2022/07/26に公開

Eventとは?

スマートコントラクトはガス代を支払うユーザーによって実行されますが、その結果処理がうまく実行されたかどうかを確認する方法がEventになります。Eventの仕組みを理解することで、UXの高いDappsを開発することができます。

スマコン側の実装

テキストを受け取ってイベントを発行するだけの簡易的なスマコンを実装

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract message {
    event msgEvent(address indexed from, string msg);
    function message(string memory message) public {
       emit msgEvent(msg.sender, message);
    }
}

フロント側の実装

スマコンの実行とそれに合わせてイベントをリスニングして、実行完了に合わせてコンソールログとして表示する仕組みを実装

import {useState, useEffect} from 'react'
import {ethers} from 'ethers'

const App = () => {
  const [msg, setMsg] = useState("");
  const contractAddress = "0x..."
  const abi = ["function message(string memory message) public"]

  useEffect(() => {
    const msgCatch = (_from, _msg) => {
      console.log("from: ", _from);
      console.log("message: ", _msg);
    };
    const provider = new ethers.providers.Web3Provider(window.ethereum);
    const signer = provider.getSigner();
    const contract = new ethers.Contract(contractAddress, abi, signer);
    const filter = contract.filters.msgEvent(null,null);
    contract.on(filter, msgCatch);
  }, []);

  const doMessage = async () => {
    const provider = new ethers.providers.Web3Provider(window.ethereum);
    const accounts = await provider.send("eth_requestAccounts", []);
    const signer = provider.getSigner();
    const contract = new ethers.Contract(contractAddress, abi, signer);
    contract.message(msg);
  };

  const doChange = (e) => {
    setMsg(e.target.value);
  };

  return (
    <>
      <div>
        <input type="text" onChange={doChange} />
        <a onClick={doMessage}>tweet</a>
      </div>
    <>
  );
};

export default App;

特に重要な部分

const filter = contract.filters.msgEvent(null,null);
contract.on(filter, msgCatch);

filterでmsgEventのeventをフィルタの設定をしています。その後contract.onでeventを拾い次第msgCatch関数を呼ぶようにしています。

参考文献

https://katoten.com/solidity-event-indexed-etherjs/
https://zenn.dev/razokulover/articles/46e255a523fad6

Discussion