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

如何以最佳方式配置Solidity合约与React/Next.js前端的连接?

Solidity合约与React/Next.js前端连接的Hardhat/Truffle最优配置

一、Hardhat + React/Next.js 配置方案

1. 初始化Hardhat项目

npx hardhat init

选择JavaScript/TypeScript项目模板,按提示完成依赖安装。

2. 合约编译与部署

  • 编写合约(示例:contracts/SimpleStorage.sol),执行编译:
npx hardhat compile

编译完成后,artifacts/contracts目录会生成包含ABI和字节码的JSON文件。

  • 编写部署脚本(scripts/deploy.js):
const hre = require("hardhat");

async function main() {
  const SimpleStorage = await hre.ethers.getContractFactory("SimpleStorage");
  const simpleStorage = await SimpleStorage.deploy();
  await simpleStorage.deployed();
  console.log(`合约部署地址:${simpleStorage.address}`);
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
  • 启动本地节点并部署合约:
npx hardhat node # 启动本地Hardhat节点
npx hardhat run scripts/deploy.js --network localhost # 部署合约到本地节点

记录终端输出的合约地址。

3. 前端项目配置

  • 创建React/Next.js项目:
# React
npx create-react-app frontend
# Next.js
npx create-next-app@latest frontend
  • 安装ethers.js(Hardhat官方推荐的交互库):
cd frontend
npm install ethers
  • 将Hardhat生成的ABI文件(artifacts/contracts/SimpleStorage.sol/SimpleStorage.json)复制到前端utils目录,导出ABI字段:
export const contractABI = [/* 粘贴JSON中的abi数组 */];

4. 前端合约交互示例

在React组件/Next.js页面中实现钱包连接与合约调用:

import { useState, useEffect } from 'react';
import { ethers } from 'ethers';
import { contractABI } from '../utils/contractABI';

const CONTRACT_ADDRESS = "你的合约部署地址";

function App() {
  const [contract, setContract] = useState(null);
  const [value, setValue] = useState('');

  useEffect(() => {
    if (!window.ethereum) {
      alert("请安装MetaMask钱包");
      return;
    }

    const init = async () => {
      const provider = new ethers.providers.Web3Provider(window.ethereum);
      await provider.send("eth_requestAccounts", []);
      const signer = provider.getSigner();
      const contract = new ethers.Contract(CONTRACT_ADDRESS, contractABI, signer);
      setContract(contract);
      // 读取合约初始值
      const currentValue = await contract.retrieve();
      setValue(currentValue.toString());
    };
    init();
  }, []);

  const updateValue = async (e) => {
    e.preventDefault();
    if (!contract) return;
    const tx = await contract.store(value);
    await tx.wait();
    const newVal = await contract.retrieve();
    setValue(newVal.toString());
  };

  return (
    <div>
      <h1>Simple Storage 交互</h1>
      <p>当前值:{value}</p>
      <form onSubmit={updateValue}>
        <input
          type="text"
          value={value}
          onChange={(e) => setValue(e.target.value)}
          placeholder="输入新值"
        />
        <button type="submit">更新值</button>
      </form>
    </div>
  );
}

export default App;

二、Truffle + React/Next.js 配置方案

1. 初始化Truffle项目

npx truffle init
npm install

2. 合约编译与部署

  • 编写合约(示例:contracts/SimpleStorage.sol),执行编译:
truffle compile

编译完成后,build/contracts目录会生成包含ABI和字节码的JSON文件。

  • 编写迁移脚本(migrations/2_deploy_contracts.js):
const SimpleStorage = artifacts.require("SimpleStorage");

module.exports = function (deployer) {
  deployer.deploy(SimpleStorage);
};
  • 启动Ganache本地节点,执行部署:
truffle migrate --network development

记录终端输出的合约地址。

3. 前端项目配置

  • 创建React/Next.js项目(步骤同Hardhat),安装web3.js:
cd frontend
npm install web3
  • 将Truffle生成的SimpleStorage.json复制到前端utils目录。

4. 前端合约交互示例

在React组件/Next.js页面中实现交互:

import { useState, useEffect } from 'react';
import Web3 from 'web3';
import SimpleStorage from '../utils/SimpleStorage.json';

const CONTRACT_ADDRESS = "你的合约部署地址";

function App() {
  const [contract, setContract] = useState(null);
  const [value, setValue] = useState('');

  useEffect(() => {
    if (!window.ethereum) {
      alert("请安装MetaMask钱包");
      return;
    }

    const init = async () => {
      const web3 = new Web3(window.ethereum);
      await window.ethereum.enable();
      const contract = new web3.eth.Contract(SimpleStorage.abi, CONTRACT_ADDRESS);
      setContract(contract);
      // 读取合约初始值
      const currentValue = await contract.methods.retrieve().call();
      setValue(currentValue);
    };
    init();
  }, []);

  const updateValue = async (e) => {
    e.preventDefault();
    if (!contract) return;
    const accounts = await web3.eth.getAccounts();
    await contract.methods.store(value).send({ from: accounts[0] });
    const newVal = await contract.methods.retrieve().call();
    setValue(newVal);
  };

  return (
    <div>
      <h1>Simple Storage 交互</h1>
      <p>当前值:{value}</p>
      <form onSubmit={updateValue}>
        <input
          type="text"
          value={value}
          onChange={(e) => setValue(e.target.value)}
          placeholder="输入新值"
        />
        <button type="submit">更新值</button>
      </form>
    </div>
  );
}

export default App;

最佳实践

  • 将合约地址存入前端.env文件,Next.js需使用NEXT_PUBLIC_前缀暴露变量:
    NEXT_PUBLIC_CONTRACT_ADDRESS=0x...
    
  • 本地开发时,确保Hardhat/Ganache节点与前端使用同一网络(默认localhost:8545)。
  • 处理钱包连接失败、合约调用异常等边界情况,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 01:20:19