You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用wagmi v2.5.7与RainbowKit调用合约时遇write不是函数问题

解决wagmi v2.5.7中useContractWrite的'write is not a function'错误

问题根源

wagmi从v1升级到v2后,useContractWrite的API有重大变更:

  • 原write方法已更名为writeAsync
  • 参数传递逻辑调整,动态参数需要特殊处理才能实时更新

具体修复步骤

  1. 替换write为writeAsync
    这是报错的直接原因,v2中不再提供write方法,统一使用异步的writeAsync。

  2. 动态处理合约调用参数
    你的代码中args直接依赖newRate状态,但组件初始化时newRate为空,且后续状态变化不会自动同步到useContractWrite的参数中。需要将args改为函数形式,确保每次调用时获取最新值:

const {
  writeAsync, // 替换原write为writeAsync
  isLoading,
  error: writeError,
} = useContractWrite({
  address: contractAddress, // v2推荐用address替代旧的addressOrName
  abi: contractABI, // 替代旧的contractInterface
  functionName: "adjustRates",
  // 改为函数形式实时获取最新newRate
  args: () => [newRate ? BigInt(newRate) : 0],
  onSettled(data, error) {
    if (error) {
      console.error("Transaction Error:", error);
      setError(error.message || "Adjustment failed.");
    } else {
      console.log("Transaction Success:", data);
      setError("");
    }
  },
});
  1. 更新调用逻辑
    在handleAdjustRates中调用writeAsync:
try {
  const tx = await writeAsync();
  console.log("Transaction initiated:", tx);
} catch (err) {
  console.error("Adjustment failed:", err);
  setError(err.message || "An unexpected error occurred.");
}

额外注意事项

  • v2中addressOrName和contractInterface已被address和abi替代,旧字段虽暂时兼容,但建议使用新字段避免后续版本问题。
  • 确保wagmi Client配置正确,必须包含publicClient和walletClient实例,这是合约交互的基础。

修改后的完整组件代码

import React, { useState } from "react";
import { useAccount, useContractWrite } from "wagmi";
import { Button, Input, Text } from "@nextui-org/react";
import {
  presaleAdr as contractAddress,
  presale_ABI as contractABI,
} from "@/constants/presaleAdr";

function ModifyRate() {
  const [newRate, setNewRate] = useState("");
  const [error, setError] = useState("");
  const { isConnected } = useAccount();

  const {
    writeAsync,
    isLoading,
    error: writeError,
  } = useContractWrite({
    address: contractAddress,
    abi: contractABI,
    functionName: "adjustRates",
    args: () => [newRate ? BigInt(newRate) : 0],
    onSettled(data, error) {
      if (error) {
        console.error("Transaction Error:", error);
        setError(error.message || "Adjustment failed.");
      } else {
        console.log("Transaction Success:", data);
        setError("");
      }
    },
  });

  const handleAdjustRates = async () => {
    setError("");
    if (!isConnected) {
      setError("请先连接钱包。");
      return;
    }

    if (!newRate) {
      setError("请输入新的费率。");
      return;
    }

    try {
      const tx = await writeAsync();
      console.log("交易已发起:", tx);
    } catch (err) {
      console.error("费率调整失败:", err);
      setError(err.message || "发生未知错误。");
    }
  };

  return (
    <div className="w-1/2 m-auto h-auto">
      <Input
        clearable
        bordered
        fullWidth
        color="primary"
        size="lg"
        placeholder="输入新费率"
        value={newRate}
        onChange={(e) => setNewRate(e.target.value)}
        disabled={isLoading}
      />
      <Button
        auto
        disabled={isLoading || !newRate || !isConnected}
        onClick={handleAdjustRates}
      >
        {isLoading ? "处理中..." : "调整费率"}
      </Button>
      {writeError && <Text color="error">{writeError.message}</Text>}
    </div>
  );
}

export default ModifyRate;

内容的提问来源于stack exchange,提问作者angryhayder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 18:26:03