ทำ subscribe event ง่ายๆ เมื่อมีคนโอน token (USDT)
สวัสดีครับ บทความนี้เป็นตัวอย่างการทำ Subscribe events Token หรือจะใช้กับ NFT ก็ได้ โดยเมื่อเราได้รับ event เราก็สามารถแจ้งเตือน Push Notification, ส่ง email, Post Slack , Discord, Telegram หรือ LINE ก็แล้วแต่เราเลย
บทความนี้ ผมใช้ Viem นะครับ เนื่องจากลองเปลี่ยน Tool จาก Ethers.js ดู โดยการเชื่อมต่อผ่าน JSON RPC

ตัวอย่าง ผมจะลองทำการ 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 ❤️