รูปจากเว็บ https://viem.sh/

ลองใช้งาน Viem เปรียบเทียบกับ Ethers.js

Viem Apr 11, 2023

เนื่องจากผมเห็น Twitter เกี่ยวกับ Viem ผ่านๆ เมื่ออาทิตย์ที่ผ่านมา ยังไม่ได้มีเวลาลอง วันนี้ก็เลยถือโอกาสลองเล่นดูว่าจะทดแทน Ethers.js ได้หรือไม่ และดี หรือไม่ดียังไง อย่างนึงที่ผมไม่ค่อยชอบสำหรับ Ethers.js คือ Docs ไม่ค่อยน่าอ่านเท่าไหร่ 🤣

viem · TypeScript Interface for Ethereum
Build reliable Ethereum apps & libraries with lightweight, composable, & type-safe modules from viem.
GitHub - ethers-io/ethers.js: Complete Ethereum library and wallet implementation in JavaScript.
Complete Ethereum library and wallet implementation in JavaScript. - GitHub - ethers-io/ethers.js: Complete Ethereum library and wallet implementation in JavaScript.

Viem

Viem เป็น Client Library สำหรับต่อกับ Ethereum Blockchain แบบเดียวกับ Ethers.js features ที่เด่นๆ คือ

  • TypeScript - รองรับ TypeScript มี type safety
  • Bundle Size - มีขนาดเล็กกว่า Ethers.js
  • Performance - ตัว Viem เคลมว่า Performance ดีสุด ดูผลเทสที่นี่
  • number จะ return เป็น bigint

บทความนี้ ผมลอง interact กับ blockchain แบบเดียวกันกับ ethers.js นะครับ

Interact Smart Contract ด้วย Ethers.js
วิธีการ Interact กับ Smart Contract ด้วยการใช้ Ethers.js ไม่ว่าจะเป็นการ call function ธรรมดา ที่ไม่ได้ไปยุ่งเกี่ยวกับ state ไม่ต้องเสียค่า gas หรือการ send transaction ที่ต้องมี signer (ทั้งจาก Private Key หรือจากการ sign, การ confirm

ติดตั้ง

npm install viem

การ Connect JSON RPC

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

const RPC_URL = 'https://rpc.ankr.com/eth'

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

ทดลอง get block number

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

const RPC_URL = 'https://rpc.ankr.com/eth'

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

const run = async () => {
  const blockNumber = await client.getBlockNumber()
  console.log(blockNumber) // 17019110n
}

run()
  .then()
  .catch((err) => console.error(err))

เนื่องจาก การทำงานคล้ายๆกันคือ createPublicClient ด้วย chain และ RPC_URL ฉะนั้น ผมขอข้ามโค๊ดตรงนั้นไป และแสดงโค๊ดที่ใช้งานละกัน

ดู balance ของ wallet address

const run = async () => {
  const balance = await client.getBalance({
    address: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', // vitalik.eth
  })
  console.log('balance', balance) // 5149620840741634567741n
}

การ format unit

import { formatUnits } from 'viem'

const run = async () => {
  const balance = await client.getBalance({
    address: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', // vitalik.eth
  })
  console.log('balance', balance)
  console.log('balance in ETH', formatUnits(balance, 18))
}

// balance 5149620840741634567741n
// balance in ETH 5149.620840741634567741

Etherscan ของ Vitalik.eth

การต่อ Contract

อ่าน ABI แบบ human-readable จะใช้ parseAbi แบบนี้

import { parseAbi } from 'viem'

const ERC20ABI = parseAbi(
[
  'function symbol() public view returns (string)',
  'function decimals() public view returns (uint8)',
  'function totalSupply() public view returns (uint256)',
  'function balanceOf(address _owner) public view returns (uint256 balance)']
)

การ read contract จะใช้ client.readContract ตัวอย่าง อ่าน total supply ของ USDT บน Ethereum mainnet

const totalSupply = await client.readContract({
  address: '0xdac17f958d2ee523a2206206994597c13d831ec7',
  abi: ERC20ABI,
  functionName: 'totalSupply'
})
console.log('totalSupply', totalSupply)
console.log('totalSupply in USDT', formatUnits(totalSupply, 6))
  
// totalSupply 35283904986788565n
// totalSupply in USDT 35283904986.788565

เอาจริงๆ สำหรับความคิดเห็นผมคือ ถ้าเราเคยใช้ web.js / Ethers.js มาก่อน มาใช้ Viem ก็ไม่ได้ยุ่งยาก หรือซับซ้อนอะไรเท่าไหร่ อาจจะมีการเขียนต่างกันเล็กน้อย แต่อ่าน Docs แปปเดียว ก็เข้าใจแล้ว ลองไปเล่นกันดูนะครับ

ตัวอย่างอื่นๆ สามารถไปอ่านเพิ่มเติมที่ Migrate from Ethers v5 to Viem และ Examples ได้ครับ

Ethers v5 → viem
Migrate from Ethers v5 to viem
Migrate Ethers -> to Viem
viem/examples at main · wagmi-dev/viem
TypeScript Interface for Ethereum. Contribute to wagmi-dev/viem development by creating an account on GitHub.

Happy Coding ❤️

Tags

Chai Phonbopit

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