接下來個人覺得是非常重要的章節,在區塊鏈是非常長調用合約
您可以通過傳入 ABI、位址以及公共和/或錢包用戶端來創建具有該函數的 getContract
合約實例。創建後,您可以調用合約方法、獲取事件、偵聽事件等。
這用個簡單的範例呼叫 erc20 目前的總數
import { createPublicClient, http, getContract } from 'viem';
import { mainnet } from 'viem/chains';
import { erc20ABI } from './abi/erc20_abi.js';
export const publicClient = createPublicClient({
chain: mainnet,
transport: http(),
});
// 取得合約
const contract = getContract({
address: '0xdac17f958d2ee523a2206206994597c13d831ec7',
abi: erc20ABI,
publicClient,
});
const result = await contract.read.totalSupply();
console.log(result);
這裡可以看到 address , abi 這兩個部分,是必填的!!
如果你不想每次操作時都傳入 address , abi 你可以使用 getContract
更輕鬆的使用合約。
這邊貼了官方的範例,這邊是說了兩者的不同
import { getContract } from 'viem'
import { wagmiAbi } from './abi'
import { publicClient, walletClient } from './client'
const contract = getContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
publicClient,
walletClient,
})
const balance = await contract.read.balanceOf([
'0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
])
const hash = await contract.write.mint([69420])
const logs = await contract.getEvents.Transfer()
const unwatch = contract.watchEvent.Transfer(
{
from: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
to: '0xa5cc3c03994db5b0d9a5eedd10cabab0813678ac'
},
{ onLogs: logs => console.log(logs) }
)
import { wagmiAbi } from './abi'
import { publicClient, walletClient } from './client'
const balance = await publicClient.readContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
functionName: 'balanceOf',
args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC']
})
const hash = await walletClient.writeContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
functionName: 'mint',
args: [69420]
})
const unwatch = publicClient.watchContractEvent({
address: '0xfba3912ca04dd458c843e2ee08967fc04f3579c2',
abi: wagmiAbi,
eventName: 'Transfer',
args: {
from: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
to: '0xa5cc3c03994db5b0d9a5eedd10cabab0813678ac'
},
onLogs: logs => console.log(logs)
})
可以看到除了不會重新呼叫 abi, address 以外,還有相較清晰許多(但兩種方法都可以!!!)
但這裡想要提醒一下,會受到你引入的 Client 而可以控制哪些 function
如果你引入 publicClient 可以使用以下的方法
如果你引入 walletClient 可以使用以下的方法
這後續會說到!
程式實作:
https://github.com/0xRory/ITHepleViem/blob/main/examples/6_1_contract.js
參考文件:
https://viem.sh/docs/contract/getContract.html