IPFS基础-高级操作

本文主要讲IPFS的一些高级应用,虽说高级,但依旧属于IPFS基础中尽可能掌握的内容。主要讲解IPFS网络中如何持久保存数据、如何发布消息、命名空间怎样使用等。

IPFS中发布动态内容

从IPFS原理可知,每上传一个文件,都有唯一的一个地址指向这个文件,假如我发布了一篇博客,此时得到一个地址A,如果我对博客内容做了一点改动,重新发布后,得到的地址变为了B, 这样会对博客浏览者造成很大困惑,无法通过一个稳定的地址来访问我的这篇博客。针对此类问题,IPFS推出了一个新的技术,叫IPNS(星际文件命名系统),其实这技术也不算新了,很多年前就已经推出了。 使用该技术,会为一个文件提供一个稳定的命名空间或者叫地址(姑且这么理解),无论文件改变多少次,该地址始终都会指向最新改动后的文件。也就是说,无论我的博客修改并发布多少次,IPNS的地址始终指向我最后一次修改后的博客。

先新建一个文件,并上传到IPFS

1
2
echo "hello jason" > test.txt
ipfs add test.txt

输出结果:

1
added QmcMR7dqXvUxgCXpwmKHyeu4mbwGAfvd5zoa7fY4UYmtPP test.txt

通过RSA公钥绑定文件内容

  1. 查看当前IPFS节点的所有公钥
1
ipfs key list -l

输出结果:

1
k51qzi5uqu5dmd05ublqz4hxj2iuyy888cihg06pzda9lm4qghxnwrnwywaup0 self 

表示当前IPFS节点只有一个公钥key,且其别名为self,表示属于节点ID的,就是说该公钥唯一对应到IPFS的节点ID
2. 创建新的RSA公钥

1
ipfs key gen --type=rsa --size=2048 newkey

生成新的公钥:k2k4r8pp1pt90mojqe0xgerxyjum439xhob526rvmhd5iambe7ri60f1
也就是说,此时该IPFS节点有两个公钥了,用上面的命令ipfs key list -l查看:

1
2
k51qzi5uqu5dmd05ublqz4hxj2iuyy888cihg06pzda9lm4qghxnwrnwywaup0 self   
k2k4r8pp1pt90mojqe0xgerxyjum439xhob526rvmhd5iambe7ri60f1 newkey

发现新加了一个公钥匙,对应别称为newkey
3. 将文件CID挂载到newkey的公钥地址上

1
ipfs name publish --key=newkey QmcMR7dqXvUxgCXpwmKHyeu4mbwGAfvd5zoa7fY4UYmtPP

输出结果:

1
Published to k2k4r8pp1pt90mojqe0xgerxyjum439xhob526rvmhd5iambe7ri60f1: /ipfs/QmcMR7dqXvUxgCXpwmKHyeu4mbwGAfvd5zoa7fY4UYmtPP

输出表明已经将文件CID关联到指定公钥了,即绑定了固定的一个地址,也就是IPNS地址
4. 浏览器访问:

1
http://localhost:8080/ipns/k51qzi5uqu5dmd05ublqz4hxj2iuyy888cihg06pzda9lm4qghxnwrnwywaup0
  1. 以后每次改动文件后,重复执行上面的步骤,最终都可以用同一个公钥来访问这个文件最新状态,其实也就是,每次公钥绑定了哪个CID,就能通过公钥(IPNS)在浏览器中看到对应CID的文件内容

通过当前节点绑定文件内容

看了上面的内容,其实很容易理解这个节点绑定文件内容的逻辑,也就是说ipfs name publish的时候,不要指定--key,则会默认将CID绑定到节点的self的公钥上,这个公钥本来就是关联节点ID的,因此文件就直接和节点绑定了,这样的坏处是,整个节点只能指向一个文件,很不灵活,因此一般不会在生产环境中使用这种方式。这里就不详细说明了(没啥好讲的,都是同一回事)。

持久保存IPFS网络数据

如果文件存储在别人的IPFS节点上,直接在自己节点ipfs cat 文件,虽然能够读取到远程节点的这个文件,但这个文件只会临时缓存到自己的节点上,一段时间后,自己节点的缓存机制(手动命令:ipfs repo gc)会自动将这个文件给删除掉,造成下次从自己节点再次读取该文件的时,还得重新缓存的问题,严重影响了体验。
为此,需要一个方式,能够永久保留下从远程节点读取到的文件。这里需要用到的命令是:

1
ipfs pin add QmcMR7dqXvUxgCXpwmKHyeu4mbwGAfvd5zoa7fY4UYmtPP

如此可以将远程文件永久保存在自己节点上

查看当前节点有哪些永久保存的文件和目录

1
ipfs pin ls --type=all

资源手动回收

也就是手动清除缓存,释放资源

1
ipfs repo gc

强制删除本地的某个文件目录及其子文件

1
ipfs pin rm -r QmejvEPop4D7YUadeGqYWmZxHhLc4JBUCzJJHWMzdcMe2y

操作IPFS Merkle DAG

IPFS的两个核心概念:默克尔树(Merkle)和有向无环图(DAG)。数据的存储结构大部分是Merkle DAG形式构成。理论部分不在这里介绍,本文主要介绍Merkle DAG的操作。
之所以介绍,是因为在操作分布式数据库分布式版本控制软件时,非常重要。 更通俗的说,就是操作一个文件的子块数据时,是需要掌握这部分内容的
关于块和对象的裂变理论部分,本文不作详述。只要记着:Block超过256Kb,就会生成新的Block;Object的Links数量超过174个,就会生成新的Object

创建Merkle DAG结构

通过ipfs add上传的文件,本身就是为文件创建Merkle DAG对象

1
ipfs add test.txt

输出结果:

1
added QmWJgfUvpjNN7ycjYac86kogRPmS1Bj33gH2LRMA9dPW1j test.txt

查看结构信息和子对象信息:

1
ipfs object links -v QmWJgfUvpjNN7ycjYac86kogRPmS1Bj33gH2LRMA9dPW1j

输出结果:

1
2
3
Hash                                           Size   Name
QmZCxwMMGar8RDc4ckezyL1uNS2ACKKyUvh6kDc6g2urHP 262158
QmVp79sgyHbzvpF8cdB7pmpbBYEkNoKUEBajTzpv9HhdqV 19869

可以看出有两个地址来管理这个test.txt文件,第一个地址:QmZCxwMMGar8RDc4ckezyL1uNS2ACKKyUvh6kDc6g2urHP对应文件的256kb文件块,另一个地址:QmVp79sgyHbzvpF8cdB7pmpbBYEkNoKUEBajTzpv9HhdqV对应文件的剩余大小。也就是说,一个文件是按照256kb来切分文件块的。
使用如下命令即可查看每个子块的信息:

1
2
ipfs cat QmZCxwMMGar8RDc4ckezyL1uNS2ACKKyUvh6kDc6g2urHP
ipfs cat QmVp79sgyHbzvpF8cdB7pmpbBYEkNoKUEBajTzpv9HhdqV

组装子块数据

该命令可以将文件的指定子块合并成一个新文件。

1
ipfs cat QmZCxwMMGar8RDc4ckezyL1uNS2ACKKyUvh6kDc6g2urHP QmVp79sgyHbzvpF8cdB7pmpbBYEkNoKUEBajTzpv9HhdqV > test2.txt

这是Merkle DAG的一种应用。该应用同时也可以用于身份校验,比如某两个子块合并后校验权限A,某三个子块合并后校验权限B,这个扩展应用根据需要灵活考虑。

块和对象的区别

  1. 块:代表的是文件分割后的一部分,可以通过如下命令查看块信息,只有hash和对应的大小:
1
ipfs block stat QmZCxwMMGar8RDc4ckezyL1uNS2ACKKyUvh6kDc6g2urHP

输出结果:

1
2
Key: QmZCxwMMGar8RDc4ckezyL1uNS2ACKKyUvh6kDc6g2urHP
Size: 262158
  1. 对象:一般代表的是在IPFS中存储的一个完整文件,当然,块也可以理解是一个对象。查看信息,比如块hash用如下命令查看:
1
ipfs object stat QmZCxwMMGar8RDc4ckezyL1uNS2ACKKyUvh6kDc6g2urHP

输出结果:

1
2
3
4
5
NumLinks:       0
BlockSize: 262158
LinksSize: 4 # 链接本身也是有容量等
DataSize: 262154
CumulativeSize: 262158

可以看出输出结果明显比用块查看多出很多信息,入链接数、块大小、对象大小等

操作Block

对于小的文件(小于256Kb),可以直接使用block来操作,能够提高处理效率。

  1. block存储小数据
1
echo "hello jason block" | ipfs block put

输出结果:

1
QmQbQ6mZ79dj7VSXUZWDfLavVvwEYkRrhbpELMDP3J4CtY
  1. block读取小数据
1
ipfs block get QmQbQ6mZ79dj7VSXUZWDfLavVvwEYkRrhbpELMDP3J4CtY

输出结果:

1
hello jason block
  1. 查看block信息
1
ipfs block stat QmQbQ6mZ79dj7VSXUZWDfLavVvwEYkRrhbpELMDP3J4CtY

输出结果:

1
2
Key: QmQbQ6mZ79dj7VSXUZWDfLavVvwEYkRrhbpELMDP3J4CtY
Size: 18
  1. 删除
1
ipfs block rm QmQbQ6mZ79dj7VSXUZWDfLavVvwEYkRrhbpELMDP3J4CtY

输出结果:

1
removed QmQbQ6mZ79dj7VSXUZWDfLavVvwEYkRrhbpELMDP3J4CtY

操作Object

  1. 创建IPFS DAG对象
1
echo "hello jason object" | ipfs add

输出结果:

1
added QmZU1y9z8WxQJLAxQHrqFDrQsmLrLYuHiCfMYhbLFP8S43 QmZU1y9z8WxQJLAxQHrqFDrQsmLrLYuHiCfMYhbLFP8S43
  1. 返回对象数据,输出JSON格式
1
ipfs object get QmZU1y9z8WxQJLAxQHrqFDrQsmLrLYuHiCfMYhbLFP8S43

输出结果:

1
{"Links":[],"Data":"\u0008\u0002\u0012\u0013hello jason object\n\u0018\u0013"}

可以看出返回两个字段:Links子块链接和Data数据
3. 返回解码后的数据

1
ipfs object data QmZU1y9z8WxQJLAxQHrqFDrQsmLrLYuHiCfMYhbLFP8S43

输出结果:

1
hello jason object
  1. 为已有数据追加新数据
1
2
echo "patch info" > ./patch.txt
ipfs object patch append-data QmZU1y9z8WxQJLAxQHrqFDrQsmLrLYuHiCfMYhbLFP8S43 ./patch.txt

输出结果:

1
QmfDtGvBafCPCoR6hNetXAgBZ2kg4Y2CPpfHL2RRGU38z2
  1. 解析新内容
1
ipfs object data QmfDtGvBafCPCoR6hNetXAgBZ2kg4Y2CPpfHL2RRGU38z2

输出结果:

1
2
hello jason object
patch info

IPFS消息发布

该功能当前属于实验功能(记忆从0.4版本到今天0.8版本这个功能一直处于实验阶段),需要在启动IPFS节点的时候,带入如下参数,开启消息功能:

1
ipfs daemon --enable-pubsub-experiment

相关主要命令

1
2
3
4
5
6
7
8
9
10
11
# 列出本节点订阅的全部主题
ipfs pubsub ls

# 列出与本节点相连接的开通pubsub功能的节点
ipfs pubsub peers

# 发布数据到相应的主题
ipfs pubsub pub <topic><data>

# 订阅主题
ipfs pubsub sub <topic>

实际操作

多节点模拟主题发布与订阅,需先确保各个节点的私有环境,排除外界其余关联节点的干扰。比如A、B两个节点,将B节点关联到A节点

  1. 在A节点订阅主题topic-A,如此凡是发往这个这个主题的消息,都会被A接收
1
ipfs pubsub sub topic-A

此时A处于接收状态
2. 在B节点对主题topic-A发布消息Hello Jason

1
ipfs pubsub pub topic-A "Hello Jason"
  1. 此时A节点收到B节点发来的信息:Hello Jason

  2. 扩展:消息可以通过中间节点转发:A->C->B,就是说即使C不订阅任何主题,只要B订阅了A的主题,依旧能经过C来接收到

应用场景

  1. 可以用于及时通信
  2. 可用于分布式数据库

总结

本文综合介绍了IPFS的一些高级操作,能够更深的了解一些IPFS的应用层的技术逻辑,对后续业务层应用会起到一定的帮助。

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2017-2023 Jason
  • Visitors: | Views:

谢谢打赏~

微信