# IPFS 简介 **Published by:** [Untitled](https://paragraph.com/@0xb483169fb514727aa8cc68ffcf8e43c254f83cd2/) **Published on:** 2023-01-13 **URL:** https://paragraph.com/@0xb483169fb514727aa8cc68ffcf8e43c254f83cd2/ipfs ## Content https://ipfs.tech 简介 星际文件系统(InterPlanetary File System,缩写为IPFS)是一个旨在实现文件的分布式存储、共享和持久化的网络传输协议。它是一种内容可寻址的对等超媒体分发协议。在IPFS网络中的节点构成一个分布式文件系统。 主要有以下几个特点 支持弹性网络:在传统的互联网中,文件是存储在中心化服务器上的,假如你的文件服务器宕机了。就会导致文件不可访问。但在IPFS中,你还可以从其他节点获取文件。 内容审核更困难:因为IPFS上的文件可以来自很多地方,所以任何人都更难封锁。 更快的文件获取速度:由于你可以从附近的节点上获取文件。而不是其他更远的地方,所以大大提升了访问速度。(类似于CDN) 今天的万维网是以所有权和访问权为结构的,这意味着你要想从拥有者那里获得文件,必须要先获得访问权。但IPFS是基于占有和参与的理念的,即人们拥有着彼此的文件并参与提供文件。 IPFS只有在人们积极参与的情况下才能更好的运转。如果你用你的电脑使用IPFS共享文件,但后来你关闭了,其他人就不能再从你那里获得文件。但是,如果文件的副本存储在其他运行着IPFS的计算机上,则这些文件就可以做出共享。 工作原理 IPFS遵循了三个基本原则 通过内容寻址来进行唯一的标识 一般情况下文件的路径是基于位置,无论是你本地的文件 /Users/..../code.js 还是网络上可访问的文件 http://www.google.com/index.html。 但IPFS 的文件路径不是基于地址的,而是基于文件内容。IPFS会基于文件内容生成一个加密的哈希值,这个值用来作为路径的一部分,如下面地址中 ipfs/ 后面的内容 /ipfs/QmcuLr8xuHm6ViSYuppjDxCXE8vDuUBKmdAwcrTJRRnEUY IPFS 使用内容寻址,即通过内容而不是通过它的位置来定位文件。每个使用 IPFS 协议的文件都有一个内容标识符,即 CID,也就是它的哈希值。这个哈希值对于文件来说是独一无二的。 通过有向无环图(DAG)进行内容链接 IPFS和许多其他分布式系统一样使用了一种称为有向无环图(DAG)的数据结构。具体来说,是使用了默克尔有向无环图(Merkle DAG)。 为了建立一个Merkle DAG表示你的文件,IPFS通常首先将文件分块。(分块意味着文件的不同部分可以有不同的来源,并被快速验证)。分块的内容会经过哈希运算得到一个哈希值作为CID,并作为 Merkle DAG 的节点。 这些节点再次经过哈希运算也就得到了该文件的CID。 同样,如果文件处于文件夹内,则也会根据文件夹内的文件内容经过哈希运算得到文件夹的CID。 如果你有两个类似的文件,文件分块后的生成的CID 如果有相同的,则可以引用相同的数据子集,可以很好的达到去重的效果。 例如,更新文件时,更新的文件和未更新文件的第一个块的CID相同,则可以引用相同的块。而不是重新创建。 因此,概括地说,IPFS让你为内容赋予 CID,并将这些内容连接在Merkle DAG中。 通过分布式哈希表(DHT) 发现内容 DHT的最主要思想是全网维护一个巨大的文件索引哈希表,这个哈希表的条目形如。其中,Key通常是文件的某个哈希算法下的哈希值(也可以是文件名或者文件内容描述) ,而Value则是存储文件的IP地址。查询时,仅需要提供Key,就能从表中查询到存储节点的地址。 由于这个哈希表很大,因此它会被分割成小块,按照一定的算法和规则分布到全网各个节点上。 每个节点仅需要维护一小块哈希表,但每块哈希表不止由一个节点维护(这样即使节点意外挂掉也有其他的节点使DHT可用) 当节点接受到查询请求后,如果可以在自己的桶(每一个节点维护的DHT子集被称为”桶“)中找到则回复,否则联系最近节点回复。这个过程一直到找到目标节点为止。 这三个原则相互依存,实现IPFS的生态系统。 使用 命令行使用 命令行安装 js-ipfs $ npm install -g ipfs 也可以安装客户端 https://ipfs.tech/#install 初始化ipfs仓库 $ jsipfs init initializing ipfs node at .jsipfs 启动本地 ipfs 网络实例 $ jsipfs daemon Initializing IPFS daemon... HTTP API listening on /ip4/127.0.0.1/tcp/5002/http gRPC listening on /ip4/127.0.0.1/tcp/5003/ws Gateway (read only) listening on /ip4/127.0.0.1/tcp/9090/http Web UI available at http://127.0.0.1:5002/webui Daemon is ready 添加文件 $ jsipfs add util.ts added QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH util.ts 访问文件内容 $ jsipfs cat QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH API使用 首先需要一个可以公网访问的服务器作为 ipfs 节点。可以选择自己的公网服务器或者 infura 服务。这里就以 infura 为例,而且其还有着5G的免费空间可以使用。在 infura 上创建 ipfs 项目后会有一个 projectId 和 projectSecret 安装 项目中安装 ipfs-http-client $ yarn add ipfs-http-client 初始化 import { create, urlSource, CID } from 'ipfs-http-client' import fs from 'node:fs' const projectId = 'xxxxxx' const projectSecret = 'xxxxxx' const auth = 'Basic ' + Buffer.from(projectId + ':' + projectSecret).toString('base64') const ipfs = create({ host: 'ipfs.infura.io', port: 5001, protocol: 'https', headers: { authorization: auth } }) 上传资源 const upload = async () => { // 上传本地文件 或 网络资源 或 文本 // 1. 本地资源 const file = fs.readFileSync('./test.sol', 'utf-8') // 2. 网络资源 //const file = urlSource('https://www.baidu.com/img/PCfb_5bf082d29588c07f842ccde3f97243ea.png') // 3. 文本 // const file = 'hello world' const result = await ipfs.add(file) console.log(result) } upload() 上传成功后会返回如下格式的内容 { path: 'QmNvHxnJQ6Ho9LWw1FwCn3nqcJXSeM76cmmd6JvoLEzW8Q', cid: CID(QmNvHxnJQ6Ho9LWw1FwCn3nqcJXSeM76cmmd6JvoLEzW8Q), size: 593 } 通过浏览器的地址 https://ipfs.infura.io/ipfs/${path},即可访问内容 读取资源 const cat = async () => { const decoder = new TextDecoder(); let content = ''; for await (const chunk of ipfs.cat('QmNvHxnJQ6Ho9LWw1FwCn3nqcJXSeM76cmmd6JvoLEzW8Q')) { content += decoder.decode(chunk); } console.log(content) } ## Publication Information - [Untitled](https://paragraph.com/@0xb483169fb514727aa8cc68ffcf8e43c254f83cd2/): Publication homepage - [All Posts](https://paragraph.com/@0xb483169fb514727aa8cc68ffcf8e43c254f83cd2/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@0xb483169fb514727aa8cc68ffcf8e43c254f83cd2): Subscribe to updates