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

如何将Solidity的addParticipant函数接入React?Context.jsx代码咨询

问题

需要将以下Solidity合约中的添加参与者功能接入React项目,请问在Context.jsx文件中应编写何种正确代码?

对应的Solidity合约代码

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0 <0.9.0;

contract Transactions{
    uint32 public participant_id = 0;   // 参与者ID

    struct participant {
        string userName;
        string password;
        string participantType;
        address participantAddress; // 以太坊账户地址
    }
    mapping(uint32 => participant) public participants; // 参与者列表

    // addParticipant函数用于添加带有不同属性的新参与者
    function addParticipant(string memory _name, string memory _pass, address _pAdd, string memory _pType) public returns (uint32)
    {
        uint32 userId = participant_id++;// 自增参与者ID
        participants[userId].userName = _name;
        participants[userId].password = _pass;
        participants[userId].participantAddress = _pAdd;
        participants[userId].participantType = _pType;

        return userId;
    }
}
解决方案

在React的Context.jsx中,我们结合ethers.js实现合约交互,同时管理钱包连接状态和添加参与者的核心逻辑,以下是完整代码:

import { createContext, useContext, useState, useEffect } from 'react';
import { ethers } from 'ethers';
// 导入合约ABI,建议单独存放在abi.json文件中
import TransactionsABI from './abi.json';

const AppContext = createContext();

// 替换为你的合约部署地址
const CONTRACT_ADDRESS = "0xYourContractAddressHere";

export const AppProvider = ({ children }) => {
    const [provider, setProvider] = useState(null);
    const [signer, setSigner] = useState(null);
    const [contract, setContract] = useState(null);
    const [isConnected, setIsConnected] = useState(false);

    // 初始化钱包连接与合约实例
    useEffect(() => {
        const initContract = async () => {
            if (!window.ethereum) {
                alert("请安装MetaMask等以太坊钱包");
                return;
            }

            const tempProvider = new ethers.BrowserProvider(window.ethereum);
            setProvider(tempProvider);

            // 监听账户切换,自动刷新状态
            window.ethereum.on('accountsChanged', () => window.location.reload());

            try {
                const tempSigner = await tempProvider.getSigner();
                const tempContract = new ethers.Contract(CONTRACT_ADDRESS, TransactionsABI, tempSigner);
                setSigner(tempSigner);
                setContract(tempContract);
                setIsConnected(true);
            } catch (err) {
                console.error("合约初始化失败:", err);
            }
        };
        initContract();
    }, []);

    // 添加参与者的核心函数
    const addParticipant = async (name, password, participantAddress, participantType) => {
        if (!contract) {
            alert("请先连接钱包");
            return false;
        }

        try {
            // 调用合约方法并发起交易
            const tx = await contract.addParticipant(name, password, participantAddress, participantType);
            // 等待交易上链确认
            await tx.wait();
            console.log("参与者添加成功,交易哈希:", tx.hash);
            return true;
        } catch (err) {
            console.error("添加参与者失败:", err);
            alert("添加失败,请检查参数或钱包权限");
            return false;
        }
    };

    return (
        <AppContext.Provider value={{
            isConnected,
            addParticipant
        }}>
            {children}
        </AppContext.Provider>
    );
};

// 自定义Hook,方便组件调用Context内容
export const useAppContext = () => useContext(AppContext);

关键说明

  • ABI文件:需将Solidity合约编译后的ABI导出为abi.json,确保文件路径正确。
  • 合约地址:必须替换CONTRACT_ADDRESS为实际部署的合约地址。
  • 钱包兼容:代码默认适配MetaMask,若使用其他钱包需调整连接逻辑。
  • 组件调用示例:在业务组件中通过useAppContext Hook调用addParticipant函数即可完成交互:
import { useAppContext } from './Context';

const AddParticipantForm = () => {
    const { addParticipant } = useAppContext();

    const handleSubmit = async (e) => {
        e.preventDefault();
        const name = e.target.name.value;
        const password = e.target.password.value;
        const address = e.target.address.value;
        const type = e.target.type.value;
        await addParticipant(name, password, address, type);
    };

    return (
        <form onSubmit={handleSubmit}>
            <input name="name" placeholder="用户名" />
            <input name="password" placeholder="密码" />
            <input name="address" placeholder="以太坊地址" />
            <input name="type" placeholder="参与者类型" />
            <button type="submit">添加参与者</button>
        </form>
    );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:50:28