使用Pinata API上传NFT元数据到IPFS时fs报错及filehash未定义咨询
问题根因
- 异步逻辑时序错误:
createFile使用回调式异步写入文件,调用后未等待写入完成就直接执行读取操作,此时文件尚未生成,导致读取失败 - 路径解析错误:使用相对路径
./metadata时,路径指向会跟随脚本执行目录变化,测试和正式项目的执行入口位置不同,导致无法找到目标目录写入文件 - 错误被静默吞噬:
upload函数的catch块没有任何错误处理逻辑,执行出错后直接返回undefined,无法定位具体报错点 - 环境不兼容:如果你的正式项目运行在浏览器前端环境,浏览器原生不支持Node.js专属的
fs模块,就会触发fs.writeFile is not a function报错
解决方案
场景1:代码运行在Node.js后端环境
直接使用修正后的Upload.js代码,通过path模块生成绝对路径,调整异步逻辑保证写入完成后再读取:
const fs = require('fs').promises const fsSync = require('fs') const path = require('path') const pinataSDK = require('@pinata/sdk') require('dotenv').config() const pinata = pinataSDK( '0bb............e3', 'a0ad52...............446f79a0be' ) // 生成metadata目录的绝对路径,固定指向当前Upload.js文件所在目录下的metadata文件夹 const METADATA_DIR = path.resolve(__dirname, './metadata') // 目录不存在时自动创建 if (!fsSync.existsSync(METADATA_DIR)) { fsSync.mkdirSync(METADATA_DIR, { recursive: true }) } const createFile = async (data) => { const jsonString = JSON.stringify(data) const filePath = path.resolve(METADATA_DIR, `./${data.publishingHistory}.json`) try { await fs.writeFile(filePath, jsonString) console.log('metadata file created successfully') return filePath } catch (err) { console.log('Error writing file', err) throw err } } export const upload = async (metadata) => { try { const isAuth = await pinata.testAuthentication() console.log(isAuth) // 等待文件写入完成再执行后续操作 const filePath = await createFile(metadata) const ipfsTransfer = await pinata.pinFileToIPFS(fsSync.createReadStream(filePath)) const filehash = `https://gateway.pinata.cloud/ipfs/${ipfsTransfer.IpfsHash}` console.log(filehash) return filehash } catch (error) { console.error('Upload failed:', error) throw error } }
场景2:代码运行在浏览器前端环境
浏览器不支持fs模块,无需写入本地文件,直接将元数据转成File对象上传即可:
import pinataSDK from '@pinata/sdk' const pinata = pinataSDK( '0bb............e3', 'a0ad52...............446f79a0be' ) export const upload = async (metadata) => { try { const isAuth = await pinata.testAuthentication() console.log(isAuth) // 直接生成File对象,无需本地存储 const blob = new Blob([JSON.stringify(metadata)], { type: 'application/json' }) const file = new File([blob], `${metadata.publishingHistory}.json`) const ipfsTransfer = await pinata.pinFileToIPFS(file) const filehash = `https://gateway.pinata.cloud/ipfs/${ipfsTransfer.IpfsHash}` console.log(filehash) return filehash } catch (error) { console.error('Upload failed:', error) throw error } }
mintArtwork函数无需修改即可正常调用。
内容的提问来源于stack exchange,提问作者Jonathan Cole
相关产品推荐
相关产品推荐

