使用wagmi和viem调用USDT合约transfer时返回0x错误求助
解决wagmi + viem调用USDT transfer返回0x的ContractFunctionExecutionError
核心排查与修复步骤
1. 匹配链与合约地址
USDT合约地址0xdAC17F958D2ee523a2206206994597C13D831ec7仅在以太坊主网有效。如果你的应用连接测试网(Sepolia/Goerli等),该地址不是合法USDT合约,调用必然返回空数据0x。
- 检查wagmi链配置,确保使用
mainnet:import { mainnet } from 'wagmi/chains' const config = createConfig({ chains: [mainnet], transports: { [mainnet.id]: http() }, // ...其他连接器配置 })
2. 校验USDT合约ABI
必须确保ABI包含正确的transfer函数定义,USDT的transfer签名为function transfer(address recipient, uint256 amount) returns (bool)。错误的ABI会导致viem无法解析返回值,触发该错误。
- 最小可用ABI片段:
const usdtAbi = [ { "inputs": [{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}], "name":"transfer", "outputs": [{"name":"","type":"bool"}], "stateMutability":"nonpayable","type":"function" } ]
3. 检查余额与Gas
- USDT余额:发送方地址
0x00d2ADa3365e40C05E8772e58B9aAcf356F3E474需持有至少10000000(10 USDT)的余额,否则transfer会revert,部分场景下返回空数据。 - ETH Gas余额:发送方需有足够ETH支付Gas,否则交易无法上链,也会触发此类错误。
4. 升级viem版本
viem@1.2.15存在ERC20返回值解析的已知bug,升级到最新稳定版(如^1.10.0)可解决:
npm install viem@latest wagmi@latest
修正后的可复现代码
import { useContractWrite, useWaitForTransaction } from 'wagmi' import { usdtAbi } from './abis/usdt' function USDTTransfer() { const { write, data, error } = useContractWrite({ address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', abi: usdtAbi, functionName: 'transfer', args: ['0x04dAb01aA15Dc4e57910420f7464bFC68579b2d2', 10000000n], // 必须用BigInt类型 }) const { isLoading, isSuccess } = useWaitForTransaction({ hash: data?.hash }) if (error) return <div>Error: {error.message}</div> return ( <button onClick={() => write?.()} disabled={isLoading}> {isLoading ? 'Transferring...' : 'Send 10 USDT'} </button> ) }
关键修正:
- amount参数必须用
BigInt(viem要求数值参数使用BigInt) - 确保ABI正确包含transfer函数
- 链配置指向以太坊主网
环境搭建验证步骤
- 初始化并安装依赖:
npx create-react-app usdt-transfer && cd usdt-transfer npm install wagmi viem @tanstack/react-query - 在
src/index.js配置wagmi主网连接:import { WagmiConfig, createConfig, mainnet } from 'wagmi' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { MetaMaskConnector } from 'wagmi/connectors/metaMask' import { http } from 'viem' const queryClient = new QueryClient() const config = createConfig({ chains: [mainnet], connectors: [new MetaMaskConnector({ chains: [mainnet] })], transports: { [mainnet.id]: http() }, }) ReactDOM.createRoot(document.getElementById('root')).render( <WagmiConfig config={config}> <QueryClientProvider client={queryClient}> <App /> </QueryClientProvider> </WagmiConfig>, ) - 确保MetaMask钱包切换到以太坊主网。
内容的提问来源于stack exchange,提问作者archara
相关产品推荐
相关产品推荐

