# Web3 应用调用 IPFS 服务实现文件去中心化存储 **Published by:** [Blue](https://paragraph.com/@blue-9/) **Published on:** 2023-12-27 **URL:** https://paragraph.com/@blue-9/web3-ipfs ## Content 在Web3应用中,有一个很重要的功能就是存储文件,在传统的Web2应用开发中,我们一般会把文件存储在服务器或OSS中,在Web3我们一般把文件存储在IPFS服务中,IPFS服务可以实现文件的去中心化存储,这篇文章主要讲讲Web3应用中如何使用IPFS服务来存储文件。一、关于 IPFSIPFS是一种点对点的超媒体协议,即一个实现文件去中心化存储的协议,通过IPFS可以将文件分解为很多区块并存储在多个提供存储服务的服务器上,和我们Web3去中心化的概念一样,所以我们在Web3应用中文件存储一般也是使用IPFS。 提供IPFS的服务商很多:Pinata: Pinata是一个去中心化的文件存储平台,为开发人员和企业提供了稳定、安全、高效的文件存储和分发服务。nft.storage: nft.storage是一个专门针对NFT存储的去中心化平台,为开发人员和企业提供了安全、高效的NFT存储服务。web3.storage: Web3.storage是用于与IPFS网络和Filecoin区块链互动的网关的另一次迭代。这次我们选择Pinata来实现IPFS上传的操作,选择其他服务商,如Web3.storage操作也是类似。二、Pinata 服务申请Gateway及API Key首先需要去Pinata官网申请一下Gateway和API Key。Gateway是用于最后我们展示图片路径前缀,API Key用于在Web3应用前端中调用Pinata的文件上传服务。image.pngimage.png三、编写链端服务这里我写了一个简单的链端服务,来新增和查询任务。// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; contract List { struct Task { uint id; string name; string ipfsHash; address owner; } Task[] private list; function createTask(string calldata name, string calldata ipfsHash) public { uint taskId = list.length; list.push(Task( taskId, name, ipfsHash, msg.sender )); } function getTask() public view returns (Task[] memory) { Task[] memory temporary = new TaskUnsupported embed; uint counter = 0; for (uint i = 0; i < list.length; i++) { if (list[i].owner == msg.sender) { temporary[counter] = list[i]; counter++; } } Task[] memory result = new TaskUnsupported embed; for (uint i = 0; i < counter; i++) { result[i] = temporary[i]; } return result; } } 其中的ipfsHash字段就是用于前端上传文件到IPFS后,Pinata返回的Hash字段,最终要展示图片也是用这个Hash值和之前我们申请的Gateway拼接展示。四、前端调用IPFS服务上传图片const axios = require('axios') const FormData = require('form-data') const fs = require('fs') const JWT = 'PINATA_IPFS_API_KEY' const pinFileToIPFS = async () => { const formData = new FormData(); const src = "2.jpg"; const file = fs.createReadStream(src) formData.append('file', file) const pinataMetadata = JSON.stringify({ name: 'testjpg', }); formData.append('pinataMetadata', pinataMetadata); const pinataOptions = JSON.stringify({ cidVersion: 0, }) formData.append('pinataOptions', pinataOptions); try{ const res = await axios.post("https://api.pinata.cloud/pinning/pinFileToIPFS", formData, { maxBodyLength: "Infinity", headers: { 'Content-Type': `multipart/form-data; boundary=${formData._boundary}`, 'Authorization': `Bearer ${JWT}` } }); console.log(res.data); } catch (error) { console.log(error); } } pinFileToIPFS() 前端主要axios去调用Pinata提供的IPFS上传接口上传文件,上传成功后在res.data中会响应一个IpfsHash字段,我们再把这个字段提供给智能合约存储即可。 最后在前端展示图片时通过https:///ipfs/拼接展示即可。 具体文档也可参考Pinata官网文档:点此查看五、案例及源码这个我写一个完整的案例,源码也开源给大家参考:案例演示:点此查看链端源码:点此查看前端源码:点此查看到此就实现了在Web3应用中通过Pinata提供的IPFS服务实现上传文件的操作,希望各位小伙伴给我多多点赞、收藏哦~ ## Publication Information - [Blue](https://paragraph.com/@blue-9/): Publication homepage - [All Posts](https://paragraph.com/@blue-9/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@blue-9): Subscribe to updates