如何在以太坊上使用IPFS存储数据

  • QuickNode
  • 发布于 2025-02-22 23:19
  • 阅读 69

本文介绍了如何将IPFS与以太坊集成,详细讲解了IPFS的工作原理、使用QuickNode工具存储数据、部署智能合约并存储IPFS数据的步骤。

概述

在区块链主网上存储大量文件可能会非常昂贵,而像 IPFS 这样的去中心化文件存储系统可以派上用场。有时,NFT 也会使用 IPFS。在本指南中,我们将介绍如何使用 QuickNode 的 IPFS 工具将 IPFS 与以太坊集成。

你将需要什么

你将做什么

  • 了解 IPFS
  • 学习如何使用 QuickNode 的 IPFS 工具
  • (可选)学习如何运行本地 IPFS 节点
  • 在 IPFS 上存储一些数据
  • 部署智能合约并将 IPFS 数据存储在其中
依赖项 版本
node.js 16.13.2>=
ethers.js ^5.7.2
browserify ^17.0.0
uniq ^1.0.1

什么是 IPFS?

我们今天使用的网络大多是中心化的;即使是存储在云上的数据也是中心化的,并由大型云提供商控制。想象一下,如果维基百科的服务器宕机,这将导致我们失去大量知识。中心化似乎并不是一件好事,那么我们为什么还要继续使用它呢?这是因为我们希望我们的页面、图像和其他内容能够以极低的延迟和高质量快速加载。使用中心化服务器时,可以调节内容交付速度。此外,在 IPFS 出现之前,还没有一个万无一失的替代方案。IPFS(InterPlanetary File System 的缩写)是一个适合下一代互联网 Web3 的文件存储和共享系统。IPFS 的核心是一个版本化文件系统,它可以存储文件并跟踪版本,类似于 git。IPFS 还定义了文件如何在网络中移动,使其成为一个分布式文件系统。它非常灵活,可以与多种传输层协议一起工作,如 TCPuTPUDTQUICTOR,甚至蓝牙。

IPFS 如何工作?

每当有人想从互联网下载文件时,用户必须查询文件的确切地址,这通常是远程服务器的 IP 地址,称为基于位置的寻址。但如果服务器宕机了怎么办?那个人将无法获取文件。可能还有另一个用户之前已经下载了该文件的副本,但计算机仍然无法从另一个用户那里获取该文件。为了解决这个问题,IPFS 使用基于内容的寻址而不是基于位置的寻址。与其说在哪里找到文件,不如说找到什么文件。每个使用 IPFS 上传的文件都与一个唯一的哈希值相关联,因此当有人想要下载文件时,他们可以查询网络以获取文件哈希,IPFS 网络中的某个人将向用户提供该文件。IPFS 具有内置的安全性,因为可以始终验证请求的文件和提供/下载的文件的哈希值。使用哈希值的另一个好处是避免重复。当多个用户尝试上传相同的文件时,它只会被接受一次,从而使网络非常高效。

IPFS 和以太坊

像以太坊这样的区块链为我们提供了时间戳数据,这使得篡改这些数据几乎是不可能的,但在以太坊上存储文件可能非常昂贵,因为以太坊区块链必须进行大量的处理,而 IPFS 返回的基于内容的地址大小为 46 字节,考虑到文件的大小,这是一个很小的量。因此,在 IPFS 上发布文件并在以太坊区块链上存储其基于内容的地址更便宜。在下面的示例中,我们将把一张图片发布到 IPFS,将其哈希值存储在智能合约中,并使用 ethers.jsQuickNode 检索/查看该图片。

IPFS 和 QuickNode

使用 QuickNode 的 IPFS 工具,开发人员不必担心运行和管理自己的 IPFS 节点。相反,他们可以通过 QuickNode 仪表板或通过 API 调用固定和提供他们的去中心化数据(在此查看文档)。QuickNode 支持 IPFS 固定和网关,因此开发人员可以固定数据并通过公共或私有网关提供数据。

要查看 QuickNode 和 IPFS 的另一个资源,请查看本指南:使用 IPFS 创建和托管博客

在下一节中,我们将学习如何使用 QuickNode 在 IPFS 上存储数据。

在 IPFS 上发布文件

虽然我们推荐使用 QuickNode 的 IPFS 工具来固定和提供数据,但我们将在下面演示两种方法(例如 1. 使用 QuickNode 的托管 IPFS 服务;2. 运行本地 IPFS 节点)。

  • QuickNode IPFS
  • 本地 IPFS 节点

提示

要在 QuickNode 上使用 IPFS,需要 Build 计划或更高版本。查看我们的定价页面上的功能细分。

导航到 QuickNode 仪表板并点击左侧边栏的 IPFS 选项卡。

然后,点击 Files 选项卡,点击 New 按钮并选择 Upload a file 或直接将你要固定的文件拖入。我们将使用下面的图片作为示例。

一旦固定,你将看到文件名,以及其他数据,如文件的 CID、是否已固定以及固定日期。

这很简单!此外,我们不必担心运行和管理自己的 IPFS 节点。你可以点击文件旁边的省略号,然后点击 Copy IPFS URL 以获取文件托管的 URL。此外,你可以在此省略号菜单下重新下载或查看文件的详细信息。花点时间试试看。

现在我们已经通过 QuickNode 将文件固定在 IPFS 上,我们可以进入下一节。

我们的第一步是安装 IPFS 并将我们的文件发布到 IPFS。你可以根据操作系统下载并安装 IPFS CLI,按照 IPFS 文档中的安装指南,创建项目目录并更改目录。

打开你的终端/cmd 并初始化 IPFS 仓库。

$ ipfs init

现在,打开另一个终端/cmd 窗口并启动 IPFS 守护进程。这将作为你的本地 IPFS 节点。

$ ipfs daemon

你可以使用自己的图像或元数据,或使用下面的示例图像。

示例 image.jpg

将你想要的图像移动到项目目录(此处为 image.jpg),然后返回上一个终端/cmd 窗口,使用以下命令将图像发布到 IPFS:

$ ipfs add image.jpg

成功上传后,你将看到类似以下的输出:

保存生成的哈希值,因为我们稍后需要它来检索图像。

设置你的 QuickNode 端点

为了查询以太坊区块链,我们需要访问以太坊节点,为此我们可以使用几乎任何以太坊客户端,例如 Geth 或 OpenEthereum(前身为 Parity)。由于从合约中获取单个哈希值有点复杂,我们将从 QuickNode 获取一个免费端点来简化操作。我们需要一个以太坊 Sepolia 端点来从链上获取数据,因为我们已经将合约部署在 Sepolia 测试网上。创建免费以太坊 Sepolia 端点后,请保留你的 HTTP Provider URL,因为稍后需要它。

Quicknode 以太坊 Sepolia 的截图,带有 HTTP 链接和 WSS

在 MetaMask 上添加自定义网络

现在,你可能想知道为什么我们要在 MetaMask 中设置自定义网络。虽然我们可以使用网络列表中的默认 Sepolia 测试网。我们将使用自定义网络,这样我们就不会被限速,并且可以享受高达 8 倍的更快速度。

打开你的 MetaMask 钱包并点击右上角的省略号。点击 Settings --> Networks --> Add Network。新页面打开后,点击 MetaMask 扩展页面底部的 Add a network manually 按钮。

你需要输入以下字段:

  • 网络名称:Sepolia QuickNode
  • 新 RPC URL:YOUR QUICKNODE HTTP PROVIDER URL
  • 链 ID:11155111
  • 货币符号:ETH
  • 区块浏览器 URL(可选):https://sepolia.etherscan.io/

之后,点击保存。如果你导航回 MetaMask 扩展,并点击 Networks 选项卡,你现在应该可以看到你的 QuickNode Sepolia 网络可用。确保它被选中。

在下一节中,我们将使用 QuickNode 的多链水龙头为我们的 MetaMask 钱包提供资金。

QuickNode 多链水龙头

到目前为止,我们已经在 IPFS 上存储了文件,创建了 QuickNode 端点并在 MetaMask 中添加了自定义网络。接下来,我们需要获取一些测试 ETH 以支付智能合约的部署和交互费用。

导航到 QuickNode 多链水龙头并连接你的钱包或粘贴你的钱包地址。你需要选择 Ethereum 链和 Sepolia 网络,然后请求资金。

有了资金后,我们可以进入部署部分。

部署我们的合约

前往 Ethereum Remix IDE 并创建一个新的 Solidity 文件,例如 - IPFS.sol

将以下代码粘贴到你的新 Solidity 脚本中:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
contract IPFS {
    string ipfsHash;

    function sendHash(string memory x) public {
        ipfsHash = x;
    }

    function getHash() public view returns (string memory) {
        return ipfsHash;
    }
}

让我们回顾一下上面的代码。

  • 第 1 行:指定 SPDX 许可证类型,这是在 Solidity ^0.6.8 之后添加的。每当智能合约的源代码公开时,这些许可证可以帮助解决/避免版权问题。如果你不希望指定任何许可证类型,可以使用特殊值 UNLICENSED 或直接跳过整个注释(不会导致错误,只会发出警告)。
  • 第 2 行:声明 Solidity 版本。
  • 第 3 行:启动名为 IPFS 的合约。
  • 第 4 行:声明一个类型为 string 的变量 ipfsHash 以存储我们的文件哈希。
  • 第 6-8 行:声明一个类型为 public 的函数 sendHash(),这意味着它可以从此函数外部由其他合约和程序访问。它接受一个字符串 x 作为输入,并将 x 的值存储到 ipfsHash 变量中。
  • 第 10-12 行:声明一个类型为 public 且可变性为 view 的函数 getHash(),这意味着它只能查看,不能修改以太坊区块链的状态,并返回存储在 ipfsHash 变量中的哈希。

接下来,导航到 Solidity Compiler 选项卡并点击 Compile。一旦编译成功,你应该会看到一个绿色勾号。

之后,让我们导航到 Deploy & Run Transactions 选项卡,并在 Environment 字段下选择 Injected Web3 选项(确保你的 MetaMask 在 Sepolia 测试网络上)。然后,点击 Deploy 按钮并在你的 MetaMask 钱包中批准交易。

一旦你的智能合约部署完成,在 Remix 中展开 Deployed Contracts 部分。我们需要将我们在上一节中发布文件到 IPFS 后获得的哈希值粘贴到 sendHash 按钮附近的输入字段中,然后点击 sendHash;然后在 Metamask 中批准交易。

一旦交易确认,我们的哈希值将存储在部署的合约中。要验证,请点击 getHash,并查看存储在智能合约中的哈希值的输出。

从 Compile 选项卡复制并保存合约的 ABI,并从部署的合约部分下的复制按钮复制合约地址。我们稍后需要这两者。

了解更多关于 ABI 及其生成的信息,请查看本指南:什么是 ABI

现在,让我们看看如何从以太坊区块链中检索哈希值并使用哈希值查看图像。

安装依赖项

我们将使用 ethers.js 编写一个简短的脚本,与我们的部署的智能合约进行交互,并使用 IPFS 网关和哈希值访问我们的图像。然后我们将使用一个名为 browserify 的包在浏览器中使用我们的 Node.js 脚本。

我们将使用 npm(Node Package Manager)安装 ethers.js 和 browserify,它随 node.js 一起提供;了解更多关于 ethers.js 的信息,请查看本指南:如何使用 ethers.js 连接到以太坊网络

打开你的终端/cmd 并运行以下命令以创建项目文件夹并安装依赖项:

mkdir ipfsProject
cd ipfsProject
npm init --y
echo > IPFS.js && echo > index.html
npm i ethers@5 browserify uniq

如果一切顺利,ethers、browserify 和 uniq 将被安装。接下来,让我们设置文件。

查看存储在 IPFS 上的文件

第 1 步:打开 IPFS.js 文件并复制粘贴以下代码:

var ethers = require('ethers');

var provider = new ethers.providers.JsonRpcProvider("YOUR_QUICKNODE_ENDPOINT");
var contractAddress = "CONTRACT_ADDRESS_FROM_REMIX";
var abi = [\
    {\
        "inputs": [\
            {\
                "internalType": "string",\
                "name": "x",\
                "type": "string"\
            }\
        ],\
        "name": "sendHash",\
        "outputs": [],\
        "stateMutability": "nonpayable",\
        "type": "function"\
    },\
    {\
        "inputs": [],\
        "name": "getHash",\
        "outputs": [\
            {\
                "internalType": "string",\
                "name": "",\
                "type": "string"\
            }\
        ],\
        "stateMutability": "view",\
        "type": "function"\
    }\
];

var contract = new ethers.Contract(contractAddress, abi, provider);

function getHashFromContract() {
    return contract.getHash()
        .then(function(hash) {
            return hash;
        })
        .catch(function(error) {
            console.error('Error fetching hash from contract:', error);
        });
}

document.addEventListener('DOMContentLoaded', function() {
    getHashFromContract().then(function(hash) {
        if (hash) {
            document.getElementById("btn").addEventListener('click', function() {
                window.location.href = "https://ipfs.io/ipfs/" + hash;
            });
        }
    });
});

继续将 YOUR_QUICKNODE_ENDPOINT 替换为你之前创建的 Sepolia HTTP 提供者,并将 CONTRACT_ADDRESS_FROM_REMIX 替换为上一节中部署的合约地址。

上面的代码解释:

  • 第 1 行:导入 ethers 库。
  • 第 2 行:将我们的 Quicknode 的 URL 存储在 url 变量中。
  • 第 3 行:实例化新的 ethers.providers.JsonRpcProvider 实例并将其存储在 provider 中。
  • 第 4 行:将合约地址存储在 address 变量中。
  • 第 5-32 行:将我们从上一步获得的 ABI 存储在 abi 变量中
  • 第 33 行:在 ethers 中初始化一个合约实例,并使用地址、abi 和 provider 连接到我们部署的合约。
  • 第 35 行:调用我们合约的 getHash 方法,该方法返回存储在合约
  • 原文链接: quicknode.com/guides/eth...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
QuickNode
QuickNode
江湖只有他的大名,没有他的介绍。