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

NFT市场开发问题:IPFS图片上传失败+MetaMask无弹窗求助

NFT市场开发问题排查与解决方案

问题概述

  • 点击「Create & List NFT!」按钮时,MetaMask未弹出授权窗口
  • localhost环境下出现IPFS图片上传错误
  • 不确定是否需要在Infura配置专属RPC节点,替换链接后问题仍未解决

错误截图

localhost错误截图

核心代码(create.js)

import { useState } from 'react'
import { ethers } from "ethers"
import { Row, Form, Button } from 'react-bootstrap'
import { create as ipfsHttpClient } from 'ipfs-http-client'
const client = ipfsHttpClient('https://ipfs.infura.io:5001/api/v0')

const Create = ({ marketplace, nft }) => {
  const [image, setImage] = useState('')
  const [price, setPrice] = useState(null)
  const [name, setName] = useState('')
  const [description, setDescription] = useState('')
  const uploadToIPFS = async (event) => {
    event.preventDefault()
    const file = event.target.files[0]
    if (typeof file !== 'undefined') {
      try {
        const result = await client.add(file)
        console.log(result)
        setImage(`https://ipfs.infura.io/ipfs/${result.path}`)
      } catch (error){
        console.log("ipfs image upload error: ", error)
      }
    }
  }
  const createNFT = async () => {
    if (!image || !price || !name || !description) return
    try{
      const result = await client.add(JSON.stringify({image, price, name, description}))
      mintThenList(result)
    } catch(error) {
      console.log("ipfs uri upload error: ", error)
    }
  }
  const mintThenList = async (result) => {
    const uri = `https://ipfs.infura.io/ipfs/${result.path}`
    // mint nft 
    await(await nft.mint(uri)).wait()
    // get tokenId of new nft 
    const id = await nft.tokenCount()
    // approve marketplace to spend nft
    await(await nft.setApprovalForAll(marketplace.address, true)).wait()
    // add nft to marketplace
    const listingPrice = ethers.utils.parseEther(price.toString())
    await(await marketplace.makeItem(nft.address, id, listingPrice)).wait()
  }
  return (
    <div className="container-fluid mt-5">
      <div className="row">
        <main role="main" className="col-lg-12 mx-auto" style={{ maxWidth: '1000px' }}>
          <div className="content mx-auto">
            <Row className="g-4">
              <Form.Control
                type="file"
                required
                name="file"
                onChange={uploadToIPFS}
              />
              <Form.Control onChange={(e) => setName(e.target.value)} size="lg" required type="text" placeholder="Name" />
              <Form.Control onChange={(e) => setDescription(e.target.value)} size="lg" required as="textarea" placeholder="Description" />
              <Form.Control onChange={(e) => setPrice(e.target.value)} size="lg" required type="number" placeholder="Price in ETH" />
              <div className="d-grid px-0">
                <Button onClick={createNFT} variant="primary" size="lg">
                  Create & List NFT!
                </Button>
              </div>
            </Row>
          </div>
        </main>
      </div>
    </div>
  );
}

export default Create

问题分析与解决建议

1. IPFS上传错误修复

当前使用的Infura公共IPFS节点未配置认证信息,会触发访问限制导致上传失败:

  • 登录Infura创建IPFS项目,获取Project ID和Project Secret
  • 修改IPFS客户端初始化代码,加入基础认证:
const auth = 'Basic ' + Buffer.from('你的Infura项目ID:你的Infura项目密钥').toString('base64');
const client = ipfsHttpClient({
  host: 'ipfs.infura.io',
  port: 5001,
  protocol: 'https',
  headers: {
    authorization: auth,
  },
});

2. MetaMask授权窗口不弹出解决

代码缺少钱包连接前置逻辑,合约调用未关联用户签名者:

  • 添加钱包连接函数,确保用户先完成MetaMask连接:
const connectWallet = async () => {
  if (window.ethereum) {
    const provider = new ethers.providers.Web3Provider(window.ethereum);
    await provider.send("eth_requestAccounts", []);
    const signer = provider.getSigner();
    // 确保marketplace和nft合约实例是通过signer初始化的,而非只读Provider
  }
}
  • 在页面中添加「连接钱包」按钮,要求用户先完成连接再操作NFT创建
  • 检查合约实例初始化逻辑,必须使用Signer而非普通Provider,否则无法触发授权弹窗

3. Infura专属RPC节点配置说明

公共RPC节点存在速率限制和稳定性问题,建议配置专属节点:

  • 在Infura创建对应链的项目(如以太坊Goerli测试网)
  • 获取项目的RPC URL,替换前端Provider初始化代码:
const provider = new ethers.providers.JsonRpcProvider('你的Infura专属RPC地址');
  • 专属节点能提升请求成功率,避免高频操作时被限流,生产环境建议必配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 11:13:12