调用buyNft购买NFT触发undefined的price属性读取报错
NFT购买功能报错:无法读取undefined的price属性
问题表现
开发NFT市场购买功能时,执行buyNft函数发起NFT购买操作,控制台抛出错误:Cannot read properties of undefined (reading 'price'),提示price值为undefined。
loadNFTs函数可正常拉取链上NFT列表数据,列表加载效果符合预期- 触发购买逻辑时稳定复现上述报错
问题相关代码
async function loadNFTs() { const provider = new ethers.providers.JsonRpcProvider('https://rpc-mumbai.maticvigil.com') const tokenContract = new ethers.Contract(nftAddress, NFT.abi, provider) const marketContract = new ethers.Contract(marketAddress, Marketplace.abi, provider) const data = await marketContract.fetchMarketItems() const items = await Promise.all(data.map(async i => { const tokenUri = await tokenContract.tokenURI(i.tokenId); const meta = await axios.get(tokenUri); let price = web3.utils.fromWei(i.price.toString(), 'ether'); let item = { price, tokenId: i.tokenId.toNumber(), seller: i.seller, owner: i.owner, image: meta.data.image, name: meta.data.name, description: meta.data.description, address: meta.data.address } return item })) console.log('items: ', items) setNfts(items); setLoadingState(false); } async function buyNft({nft}) { const web3Modal = new Web3Modal({ network: "mainnet", cacheProvider: true, }); const connection = await web3Modal.connect(); const provider = new ethers.providers.Web3Provider(connection); const signer = provider.getSigner(); const contract = new ethers.Contract(marketAddress, Marketplace.abi, signer); nft = nfts.price console.log('nft', nft) const price = web3.utils.toWei(nft.price.toString(), 'ether'); console.log('------',price); const transaction = await contract.createMarketSale(nftAddress, nft.tokenId, { value: price }); await transaction.wait(); loadNFTs(); }
根因定位
- 核心错误为
buyNft函数中存在错误的变量覆写逻辑:- 代码中写了
nft = nfts.price,其中nfts是通过setNfts存储的NFT列表数组,并非单个NFT对象,直接读取数组的price属性返回值本身就是undefined - 该行代码将函数入参传入的、正常的单个NFT对象
nft直接覆写为上述undefined值,后续执行nft.price.toString()时,操作目标是undefined,自然会抛出读取属性失败的错误
- 代码中写了
- 存在隐藏的网络配置问题:Web3Modal初始化时配置的网络为
mainnet以太坊主网,但loadNFTs读取数据使用的是Polygon Mumbai测试网RPC,即使修复price报错,后续也会因网络不匹配导致交易失败。
修复方案
- 直接删除错误的
nft = nfts.price代码行,直接使用函数入参传入的nft对象即可 - 修正Web3Modal的网络配置为
mumbai,和当前使用的测试网环境匹配
修复后的buyNft函数核心代码:
async function buyNft({nft}) { const web3Modal = new Web3Modal({ network: "mumbai", // 修正网络配置匹配Mumbai测试网 cacheProvider: true, }); const connection = await web3Modal.connect(); const provider = new ethers.providers.Web3Provider(connection); const signer = provider.getSigner(); const contract = new ethers.Contract(marketAddress, Marketplace.abi, signer); console.log('当前待购买NFT: ', nft) // loadNFTs阶段已经将price转为ether单位字符串,此处直接转wei即可 const price = web3.utils.toWei(nft.price.toString(), 'ether'); console.log('支付金额(wei): ',price); const transaction = await contract.createMarketSale(nftAddress, nft.tokenId, { value: price }); await transaction.wait(); loadNFTs(); }
内容的提问来源于stack exchange,提问作者Abhishek Chauhan
相关产品推荐
相关产品推荐

