区块链 | IPFS:Merkle DAG

news/2024/5/20 11:40:58

🦊原文:IPFS: Merkle DAG 数据结构 - 知乎
🦊写在前面:本文属于搬运博客,自己留存学习。



1 Merkle DAG 的简介

Merkle DAG 是 IPFS 系统的核心概念之一。虽然 Merkle DAG 并不是由 IPFS 团队发明的,它来自于 Git 数据结构,但是 IPFS 团队对其进行了改造。可以肯定的是,IPFS 团队并非直接拿来使用,而是在原有基础上进行修改以更适合项目的使用。

Merkle DAG 的全称是 Merkle Directed Acyclic Graph,即默克有向无环图。它是在 Merkle Tree 基础上构建的,Merkle Tree 是由美国计算机学家 Merkle 于 1979 年申请的专利。Merkle DAG 跟 Merkle Tree 很相似,但不完全一样,比如:Merkle DAG 不需要进行树的平衡操作,非叶子节点允许包含数据等。



2 Merkle DAG 的功能

Merkle DAG 拥有如下的功能:

  • 内容寻址:使用多重哈希来唯一标识一个数据块的内容;
  • 防篡改:通过检查哈希值来确认数据块的内容是否被篡改;
  • 去重:由于内容相同的数据块哈希值是相同的,因此很容易去除重复的数据,以节省存储空间;


3 IPFS 的数据对象格式

IPFS 的数据对象格式如下:

type IPFSLink struct {name string 		// Link的名字hash Multihash 		// 数据的加密哈希size int 			// 数据大小
}type IPFSObject struct {links []IPFSLink 	// Link数组data []byte 		// 数据内容
}

这段代码是用 Go 语言写的,Go 语言又称为 Golang 语言。

在 IPFS 网络中,大的文件通常会被分割成多个小片。每个碎片拥有自己的哈希值,再根据碎片的哈希值生成对应的「链接」。按照每个碎片在文件中出现的顺序,使用它们的链接生成「链接数组」,再使用「链接数组」生成最终的顶层「对象」,以此来表示文件。

除此之外,IPFS 赋予应用完全的数据字段控制权,允许应用自由定义数据类型和结构,包括那些 IPFS 系统无法直接识别的复杂数据结构,从而提供了极大的灵活性。



4 IPFS 的数据对象如何工作

第一步:准备数据

一张图片,文件名为 rainy_day.jpg,文件大小为 1MB,如下图所示:

在这里插入图片描述

说明:我没有采用原博的图片,因为图片上的水印导致图片内容改变了。如果你想自己测试的话,那么建议使用一个超过 256K 的数据文件,因为 IPFS 当前的数据分片标准是 256K 一个。



第二步:添加文件

执行 ipfs add 命令以添加文件:

$ ipfs add rainy_day.jpg
added QmQhSvoNcYCXk7JAjXzkQN8TmQaA8wP4oZxB9EmDNXiUzd rainy_day.jpg

说明:在本文中,以 $ 开头的是命令,不以 $ 开头的是输出结果。



第三步:查看文件分片

执行 ipfs ls -v 命令以查看文件分片:

$ ipfs ls -v QmQhSvoNcYCXk7JAjXzkQN8TmQaA8wP4oZxB9EmDNXiUzd

输入的就是刚才得到的哈希值。

如下所示,可以看到文件被分成了 5 个区块(block),每个区块的大小为 256K,除了最后一个。

Hash Size Name
QmTKqvEAgEaWfJVZjq7drgQUBLxwWzyrCTBVzZ9dcBc3Cq 262158
QmQCxXC4EUqw9gRmiRStNfYSr15oyPTV6yVJ7G9KBzecVt 262158
QmT4vb3Ujn6RpLijb8z4jFooCWmNqgvPbSagQf1WgdJjZe 262158
QmZ4UtPdZ5aBL4g55Yb7erWVtJGEBwhyGd5dCwYx28CafK 262158
QmcbpccHVURapPiKPn37yG14ar1myeFvTdqm215RRKcKqW 3071

由此可见,当执行 ipfs add 命令时,文件 first.JPG 的数据被分割成多个相等大小的区块,同时构建一个 Merkle DAG 来将这些数据区块整合成一个有序的结构。如下图所示:

在这里插入图片描述

上图源自 IPFS 官方在线测试网站:https://dag.ipfs.tech/



5 IPFS 的查询命令

我们还可以使用 IPFS 提供的命令来查看数据块(block)的信息,数据块下面还允许链接子数据块(sub-block),本文的例子中没有涉及。

相关的查询命令如下:

  • ipfs block stat:查询数据块的大小,不包含子块;
  • ipfs refs:列出数据块的子块信息;
  • ipfs ls or ipfs object links:显示所有的块和子块的大小;

例如:

$ ipfs block stat QmTKqvEAgEaWfJVZjq7drgQUBLxwWzyrCTBVzZ9dcBc3Cq
Key: QmTKqvEAgEaWfJVZjq7drgQUBLxwWzyrCTBVzZ9dcBc3Cq
Size: 262158

既然每个数据块都能被我们查询到,那么我们可以手动将这些数据块重新组合起来。

比如刚才那张图片,就可以使用命令:

$ ipfs cat hash1 hash2 hash3 ... hashn > rainy_day.jpg

从而得到上面的那张照片,有兴趣的读者可以自己动手试试。



6 直接操作 Merkle DAG

IPFS 可以让我们直接操作 Merkle DAG 的数据,举个例子:

$ echo "hello world" | ipfs block put
QmZjTnYw2TFhn9Nn7tjmPSoTBoY7YRkwPzwSrSbabY24Kp$ ipfs block get QmZjTnYw2TFhn9Nn7tjmPSoTBoY7YRkwPzwSrSbabY24Kp
hello world

上述命令的意思应该是:将 “hello world” 编码为一个 IPFS 块,IPFS 返回该数据块的哈希值。然后,可以通过该哈希值访问到数据内容是 “hello world”。

怎么样?很魔性吧,我们完全控制了数据块中的数据内容和结构,IPFS 把 Merkle DAG 的操作权限几乎全部下放给了开发者,开发者可以很容易构造出来自己的数据结构。

IPFS 在论文里面提出了可以自己一些潜在的数据结构:

  • 键值对存储(Key-value Stores)
  • 关系型数据库(Traditional Relatioinal Databases)
  • 三元组存储(Linked Data Triple Stores)
  • 文档发布系统(Linked Document Publishing Systems)
  • 通信平台(Linked Communications Platforms)
  • 加密货币区块链(Cryptocurrency Blockchains)

在此基础上开发者还可以完全自定义自己的数据结构。看到最后一条了吧,IPFS 为所有的区块链准备好了数据存储结构,IPFS 将作为区块链的基础设施存在。




http://www.mrgr.cn/p/43501712

相关文章

uniapp:抖音PK进度条(nvue)

nvue中,仿抖音PK进度条效果, <template><view class="index" :style="{width:windowWidth+px,height:index_windowHeight+px,paddingTop:windowTop+px}"><view class="pk"><text class="pk_jindu_left_val fsz-24 …

【OpenGL4.6】VS2022安装OpenGL4.6的全过程

文章目录 一、说明二、vs2022环境安装2.1. 安装vs20222.2 为OpenGL专门建立目录 三、下载安装cmake&#xff0c;用于编译源代码3.1 为什么安装Cmake3.2 下载和安装Cmake 四、下载安装glfw&#xff0c;用于窗口界面4.1 设置glfw库&#xff0c;用于创建窗体4.2 如何使用glfw库? …

密码学《图解密码技术》 记录学习 第十二章

目录 第十二章 12.1 骡子的锁匠铺 12.2 本章学习的内容 12.3 使用随机数的密码技术 12.4 随机数的性质 12.4.1 对随机数的性质进行分类 12.4.2 随机性 12.4.3 不可预测性 12.4.4 不可重现性 小测验 1 骰子 &#xff08;答案见 1…

time:Python的时间时钟处理

前言 time库运行访问多种类型的时钟,这些时钟用于不同的场景。本篇,将详细讲解time库的应用知识。 获取各种时钟 既然time库提供了多种类型的时钟。下面我们直接来获取这些时钟,对比其具体的用途。具体代码如下: import timeprint(time.monotonic()) print(time.monotonic_…

时间函数的简单理解和应用(time.h)

目录关于时间的函数及tm结构体描述对函数的简单理解操作函数功能实现 关于时间的函数及tm结构体描述time.h头文件中常用的几个函数描述如下:序号 函数&描述1 time_t time(time_t *tloc)最基础的函数,计算当前时间,并返回成 time_t(aka long int)格式而且返回值是从Epoch…

FastAPI vs Flask: 选择最适合您的 Python Web 框架

文章目录 1. 简介2. 安装和设置3. 路由和视图4. 自动文档生成5. 数据验证和序列化6. 性能和异步支持结论 在 Python Web 开发领域&#xff0c;FastAPI 和 Flask 是两个备受欢迎的选择。它们都提供了强大的工具和功能&#xff0c;但是在某些方面有所不同。本文将比较 FastAPI 和…

《二十三》Qt 简单小项目---视频播放器

QT 使用QMediaPlayer实现的简易视频播放器 效果如下&#xff1a; 功能点 播放指定视频点击屏幕暂停/播放开始/暂停/重置视频拖拽到指定位置播放 类介绍 需要在配置文件中加入Multimedia, MultimediaWidgets这俩个库。 Multimedia&#xff1a;提供了一套用于处理音频、视频…

Streamlit:快速构建可视化网页(数据科学必备)

很多算法工程师在完成数据分析、模型训练或者项目总结的时候,往往只能通过ppt汇报,添加数据图表、截图模型实验结果等。如果想提供一个前端演示demo,通常可以搭建flask服务,但是flask需要学习很多前端知识,如css、html等,这又是一个深之又深的坑。那有没有什么工具能够跳…

「Dasha and Photos」Solution

简述题意 给定一个 n m n \times m nm 的方格&#xff0c;每个格子里有一个小写英文字母。 现在你有 k k k 个 n m n \times m nm 的方格&#xff0c;这些方格都是给定方格的基础上将左上角为 ( a i , b i ) (a_i,b_i) (ai​,bi​)&#xff0c;右下角为 ( c i , d i ) …

SpringBoot项目GraalVM迁移

一些背景 一直想把项目迁移到使用GraalVM构建出的原生应用上,但是在前段时间的一次尝试后,发现很难做到,其中一个最主要原因就在于我目前手头上没有X86架构的电脑。平时我使用的是一个M1处理器的MacBook,编译出的Docker镜像架构指令集也是Arm64的,无法在我的X86服务器启动…

Android Studio报错:Constant expression required

【出现的问题】&#xff1a; 使用JDK17以上版本&#xff0c;switch语句报错&#xff1a;Constant expression required 【解决方法】&#xff1a; 在gradle.properties配置文件下添加代码&#xff1a; android.nonFinalResIdsfalse 如图&#xff1a; 接着再点击右上角的Sync…

国内验签SSL证书——数据不出境,政务、高校、金融机构必备

涉及金融、政务、教育等重要领域的网站&#xff0c;国家要求是重要数据坚决不能出境。特别是《中华人民共和国网络安全法》的实施&#xff0c;国内验签SSL证书成为了提升网站安全性、保护用户数据和维护网站信誉的重要工具。 国内验签SSL证书的优势 1数据不出境 根据国家相关法…

基于springboot+mybatis+vue的项目实战之(后端+前后端联调)

步骤&#xff1a; 1、项目准备&#xff1a;创建数据库&#xff08;之前已经创建则忽略&#xff09;&#xff0c;以及数据库连接 2、建立项目结构文件夹 3、编写pojo文件 4、编写mapper文件&#xff0c;并测试sql语句是否正确 5、编写service文件 6、编写controller文件 …

PLC学习笔记

PLC学习笔记 前言一、一些基操知识二、GX works2编程2.1 位逻辑1.2 中间寄存器1.3 PLC的扫描方式 总结 前言 我这个人真的是太渴望知识了~ 一、一些基操知识 一般X表示输入&#xff0c;Y表示输出。一般八个为一组X0~X7M表示中间寄存器&#xff0c;M0~M7时间T、计数C 二、GX …

Java基于Spring Boot框架的课程管理系统(附源码,说明文档)

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

董浩影评

本文来自博客园,作者:↑-↑-我-的-仓-鼠-↑-↑,转载请注明原文链接:https://www.cnblogs.com/donghao99/p/18182035

《视觉十四讲》例程运行记录(5)——运行ch8视觉里程计2光流法和直接法的实践例程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、运行ch8的例程代码1. 编译例程代码前的修改2. 编译例程3. 编译报错(1) 报错一&#xff1a;使用cmake .. 编译时出现(2) 报错二&#xff1a;make编译时出现(3) 报…

Rust | 实现 API 限速操作 Example

在这篇文章中,我们将讨论如何在 Rust 中实现 API 限速。当涉及到生产中的服务时,是为了确保不良行为者不会滥用 API——这就是 API 限速的作用所在。 我们将实现 “滑动窗口” 算法,通过动态周期来检查请求历史,并使用基本的内存 hashmap 来存储用户 IP 及其请求时间。我们…

synchronized关键字的底层原理

1synchronized关键字的底层原理 Monitor 举个例子&#xff1a; 1.线程1执行synchronized代码块&#xff0c;里面用到了lock(对象锁)。首先会让这个lock对象和monitor关联&#xff0c;判断monitor中的owner属性是否为null。如果为null直接获取对象锁。owner只能关联一个线程。 2…

【JUC】并发编程 Synchronized 锁升级原理

Synchronized如何实现同步/互斥的效果&#xff1f; monitorenter&#xff1a; 将锁对象对象头中Mark Word的前30bit替换成指向操作系统中与其关联的monitor对象&#xff0c;将锁记录位状态改为10 monitorexit&#xff1a; 将锁对象对象头中Mark Word进行重置&#xff0c;重新恢…