200行代码实现一个可追溯的文件系统

2023-10-25 08:31

本文主要是介绍200行代码实现一个可追溯的文件系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

难篡改、可追溯,这两个性质是区块链被广泛认可的良好特性。

最早比特币只实现了交易转账的可追溯,如果要实现数据变更的可追溯,就需要编写智能合约来实现了,可惜大多数区块链系统的合约开发都不是很好用,这个门槛把很多试图体验区块链的人挡在了门外。

如果能把区块链变成一块硬盘,放在里面的文件自动就具备了“难篡改、可追溯”的性质,是不是很酷?本文将介绍如何基于百度超级链来来实现这样一个文件系统,主要的代码只有200行左右。

传统的文件系统是操作系统的一部分,一般是在内核里面实现的。区块链系统都运行在用户态,如何把区块链变成一块存储盘呢?这就要用到Fuse(Filesystem in Userspace)了,简单来说它是一个用户态文件系统框架,只要你的程序实现了open、read、write等等一系列接口,就可以虚拟出一个文件系统。

图1 Fuse的原理(引自Wikipedia)

在超级链中,可以通过智能合约的put_object把数据存储到区块链上,通过get_object查询,也可以通过new_iterator遍历查询。

设计思路

一个简单而大胆的想法,就是用文件的名字作为key,然后把文件的内容作为value,借助智能合约存储到区块链上,比如put_object(“/mydir/1.txt”, “a long story”)。读取该文件,就是调用get_object(“/mydir/1.txt”)。列出目录,就是通过new_iterator(“/mydir”)循环遍历迭代器,拿到所有该前缀的文件名。说干就干,马上写出一个超级链合约,实现我们这个文件系统的内核。

图2 智能合约实现get,put,scan三个接口,用于模拟文件系统

各位看官可能会问,这个合约的功能和redis、leveldb等key-value存储相比,有什么特殊之处呢?这个就要说到超级链的XuperModel模型了。

在超级链里面的事务模型是XuperModel,它是基于经典的UTXO模型演化而来,经典的UTXO模型只能描述转账场景,而XuperModel创新之处在于可以描述更加通用的数据变更。

图3 智能合约存储的多版本管理

超级链底层的数据多版本机制实现也与数据库不同。数据库的一般做法是将逻辑Key+版本号拼接成物理Key,但是这个方式只能保留有限个版本,一旦版本太多,就会导致区间查询迭代很慢,因为要Scan大量无用的老版本。超级链用了一种链式哈希的多版本接口,在状态树中Key对应的Value只是哈希指针,指向账本中事务的Output字段,要回溯之前的老版本也只需要通过事务的Input指针再往前回溯。当需要回滚事务或区块的时候,产生的IO开销也极低。

接下来,要实现一个模块,这个模块起到“桥梁”的作用,把区块链智能合约存储映射成一块盘,这个就是用到了文章开头提到的Fuse。 

图5. 把合约空间mount为一块盘

简单起见,我们用python来实现,python有个库python-fuse可以帮助我们少写很多代码。下图贴出了主要的代码逻辑,目前的实现没有做chunk管理,一个文件就是一个整体。对于随机读、随机写的实现比较简单粗暴。

图4  Xfs的主要代码逻辑

见证奇迹的时刻,运行XFS

让我们看看效果。首先启动xchain单机节点。

nohup ./xchain &          //启动grpc服务

nohup ./xchain-httpgw &   //启动http服务

然后, 创建一个空目录:mkdir –p /tmp/myxfs

部署合约,python3.6 deploy_fs.py

最后, 启动xfs 把合约mount到/tmp/myxfs:python3.6 xfs_demo.py -f /tmp/myxfs/

图5 用起来本地文件系统体验一致,丝般顺滑

同时,在xfs_demo的控制台上,看到了如下输出,这个是系统调用触发的,我们可以看到一次写入操作产生了区块链上的一个交易,有交易id: 303c867e195ba464778250b2e7f21a841c1825daabe35728c02a04ecc7289f22。

图6 系统调用被映射为智能合约的调用

可以用xchain-cli查询一下这个交易,./xchain-cli tx query 303c867e195ba464778250b2e7f21a841c1825daabe35728c02a04ecc7289f22,这的确是存储在区块链上的。

图7 文件写入对应的Transaction的结构(局部)

甚至,可以在这个文件系统上跑一个sqlite:

图8 在区块链上跑SQLite

图9 SQLite底层的文件操作映射到Xfs变成合约调用操作

可追溯的文件系统

最后,重点看看这个文件系统和传统文件系统不同的地方:可追溯。

首先,产生一个文件,里面写上“Hello World”,然后,再次在这个文件后面追加一行:”I will be back”。这个可追溯文件系统支持用户在文件名后面加个版本号,比如@1表示最新的版本,@2表示倒数第二个版本。可追溯的效果如下图:

图10 可追溯文件系统的效果

图11 实现可追溯的数据结构基础

很多版本管理工具,如Git也可以实现同样的效果,然而借助区块链,我们实现了去中心化的数据一致性、难篡改等特性,并且只用了200行左右的代码,这一切只是超级链能力的冰山一角。我们会持续完善基于智能合约的开发框架和工具链,敬请关注。

附,文中的代码地址(点击阅读原文直达):

https://github.com/fxsjy/xuper_python

如果你是区块链开发者、技术发烧友,

欢迎加入超级链开发者社群。

加群方式:添加百度超级链小助手微信(image-baidu),

回复:我是开发者

这篇关于200行代码实现一个可追溯的文件系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/281310

相关文章

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja