ทำ subscribe event ง่ายๆ เมื่อมีคนโอน token (USDT)

Blockchain Apr 11, 2023

สวัสดีครับ บทความนี้เป็นตัวอย่างการทำ Subscribe events Token หรือจะใช้กับ NFT ก็ได้ โดยเมื่อเราได้รับ event เราก็สามารถแจ้งเตือน Push Notification, ส่ง email, Post Slack , Discord, Telegram หรือ LINE ก็แล้วแต่เราเลย

บทความนี้ ผมใช้ Viem นะครับ เนื่องจากลองเปลี่ยน Tool จาก Ethers.js ดู โดยการเชื่อมต่อผ่าน JSON RPC

viem · TypeScript Interface for Ethereum
Build reliable Ethereum apps & libraries with lightweight, composable, & type-safe modules from viem.

ตัวอย่าง ผมจะลองทำการ subscribe event ของ token ผมเลือกเป็น USDT

  • Contract Address : 0xdac17f958d2ee523a2206206994597c13d831ec7

โดยปกติ ERC-20 หรือ ERC-721 มักจะมี event Transfer อยู่แล้ว ตัว ABI ด้านล่าง คือ สิ่งที่เราจะต้องใช้เวลา subscribe event.

# ERC-20
event Transfer(address indexed _from, address indexed _to, uint256 _value)

# ERC-721
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);

ทำการ Connect JSON RPC ด้วย createPublicClient

import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'

const client = createPublicClient({ 
  chain: mainnet,
  transport: http()
})

ทำการ subscribe event Transfer

โดยผมทำการ log เอาเฉพาะ  _from , _to และ _value มาแสดง (ค่า args คือ argument ของ event ABI เรา)

const USDT = '0xdac17f958d2ee523a2206206994597c13d831ec7'
const ERC20ABI = [
  'event Transfer(address indexed _from, address indexed _to, uint256 _value)',
]

const unwatch = client.watchContractEvent({
  address: USDT,
  abi: parseAbi(ERC20ABI),
  eventName: 'Transfer',
  onLogs: (logs) => {
    const args = logs.map(({ args }) => args)
    console.log('args', args)
  },
})

แต่ละ block ก็จะมี transaction ของ USDT ประมาณนี้ ( _value ของ USDT ใช้ 6 decimal places)

args [
  {
    _from: '0x54cd970F3e31907cc51a1E9Bf21F94f13194407E',
    _to: '0x74de5d4FCbf63E00296fd95d33236B9794016631',
    _value: 3186471247n
  },
  {
    _from: '0x74de5d4FCbf63E00296fd95d33236B9794016631',
    _to: '0x06da0fd433C1A5d7a4faa01111c044910A184553',
    _value: 3158589624n
  },
  {
    _from: '0x74de5d4FCbf63E00296fd95d33236B9794016631',
    _to: '0x2aCf35C9A3F4c5C3F4c78EF5Fb64c3EE82f07c45',
    _value: 27881623n
  },
  {
    _from: '0x9A8428c1eb4Cec52Bf91B19c08cAA9e7beF525bb',
    _to: '0x7636a5bfD763CEFec2DA9858c459F2a9b0FE8A6C',
    _value: 145308187500n
  },
  ...
]

ซึ่งตัว log จริงๆ มันจะไม่ได้มีแค่ args มี address, topics , data, txHash, blockHash เป็นต้น

[...,
{
  address: '0xdac17f958d2ee523a2206206994597c13d831ec7',
  topics: [
    '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
    '0x000000000000000000000000efe00f74614cdf683ce5f95e0743b9869de05c1a',
    '0x00000000000000000000000074de5d4fcbf63e00296fd95d33236b9794016631',
  ],
  data: '0x0000000000000000000000000000000000000000000000000000000236d46f54',
  blockNumber: 17025874n,
  transactionHash:
    '0x00bb76e91e5c4b30b32b910e16961688ba68d985b327ebb213eadb246812fb5a',
  transactionIndex: 64n,
  blockHash:
    '0x2520296a0726611f1dd05035b146e1b7d9ddef73bf66091e5b5d4d569adee9c4',
  logIndex: 101n,
  removed: false,
  args: {
    _from: '0xEfE00F74614cdf683Ce5f95e0743b9869dE05c1a',
    _to: '0x74de5d4FCbf63E00296fd95d33236B9794016631',
    _value: 9509826388n,
  },
  eventName: 'Transfer',
}
]

ถ้าไม่มี args result มาให้ เราสามารถ decode event log ได้ ประมาณนี้

import { decodeEventLog } from 'viem'

onLogs: (logs) => {
  const topics = decodeEventLog({
    abi: parseAbi(ERC20ABI),
    data: logs.data,
    topics: logs.topics
  })
}

เมื่อลองเทียบ Viem กับก่อนหน้านี้ที่ใช้ Ethers.js ในการ subscribe events ก็จะเป็นแบบด้านล่าง

const abi = [
  'event Transfer(address indexed _from, address indexed _to, uint256 _value)'
]

const contract = new Contract(USDT, abi, provider)

const listener = (from, to, amount, event) => {
  // ...
}
contract.on('Transfer', listener)

สรุป

ก็เป็นตัวอย่างง่ายๆ ในการ subscribe event ของ Contract ที่เราต้องการ  โดยใช้ Viem เนื่องจากช่วงนี้กำลังลองหัดใช้อยู่

นอกจากนี้เรายังสามารถ subscribe event NFT หรือพวก Dex, Router ต่างๆ ได้ เช่น Uniswap แล้วเลือก filter event swap เป็นต้น หรืออย่าง NFT ก็เลือก event Mint (จริงๆ ก็คือ Transfer)  สิ่งที่ต้องรู้ก็คือ Contract Address, Event ที่ต้องการ แค่นั้น

Happy Coding ❤️

Tags

Chai Phonbopit

เป็น Web Dev ทำงานมา 10 ปีหน่อยๆ ด้วยภาษา JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจ Web3, Crypto และ Blockchain เขียนบล็อกที่ https://devahoy.com