React+ethers开发以太坊交易应用遇map读取未定义错误求助
错误分析与解决方案:TypeError: Cannot read properties of undefined (reading 'map')
错误根源
从报错栈追踪可以定位到,问题出在getEthereumContract函数中实例化ethers.Contract的代码行:
const transactionContact = new ethers.Contract(contractAddress, contractABI, signer);
报错原因是传入的contractABI为undefined,或者格式不符合ethers对ABI的要求(必须是标准的JSON数组结构),导致ethers内部初始化Interface时尝试对undefined调用map方法,触发类型错误。
解决方案
1. 检查ABI的导出与定义
打开./utils/constants.js文件,确保:
contractABI是一个有效的Solidity合约ABI数组(可从Remix、Hardhat等编译工具直接复制)- 导出语句正确,示例:
// ./utils/constants.js export const contractAddress = "0xYourContractAddressHere"; export const contractABI = [ // 示例ABI结构(根据你的合约实际内容调整) { "inputs": [{"internalType": "address", "name": "_to", "type": "address"}, {"internalType": "uint256", "name": "_amount", "type": "uint256"}], "name": "addToBlockChain", "outputs": [], "stateMutability": "payable", "type": "function" } ];
2. 增加ABI有效性校验
在getEthereumContract中提前校验ABI,避免后续执行报错:
const getEthereumContract = async () => { if (!contractABI || !Array.isArray(contractABI)) { throw new Error("合约ABI无效或未定义"); } const provider = new ethers.providers.Web3Provider(window.ethereum, "any"); const signer = provider.getSigner(); const transactionContact = new ethers.Contract(contractAddress, contractABI, signer); return transactionContact; };
3. 修正交易逻辑冗余问题
你的sendTransaction函数中同时调用了eth_sendTransaction(直接转账ETH)和合约的addToBlockChain方法,这会发起两次独立交易,需根据业务需求二选一:
- 如果只是单纯转账ETH,删除合约相关代码,保留
eth_sendTransaction即可 - 如果需要调用合约方法,删除
eth_sendTransaction的调用,仅保留合约方法调用:
const sendTransaction = async () => { const addressTo = document.querySelector('#to').value; const amount = document.querySelector('#amount').value; if (!addressTo || !amount) { alert("交易信息不完整"); return; } try { setIsLoading(true); const transactionContract = await getEthereumContract(); const parsedAmount = ethers.utils.parseEther(amount); // 仅调用合约方法,ethers会自动处理交易请求 const transactionHash = await transactionContract.addToBlockChain(addressTo, parsedAmount, { value: parsedAmount // 如果合约方法是payable,需传入对应value }); console.log(`交易提交中:${transactionHash.hash}`); await transactionHash.wait(); console.log(`交易成功:${transactionHash.hash}`); } catch (err) { console.error("交易失败:", err); alert("交易失败,请检查控制台日志"); } finally { setIsLoading(false); } };
内容的提问来源于stack exchange,提问作者Het
相关产品推荐
相关产品推荐

