IPFS:如何将文件添加到现有文件夹?

IDo*_*OOP 15 ipfs

给定一个相当大的文件夹,它已被推送到网络,并在本地删除.如何将文件添加到该文件夹​​,而无需重新下载整个文件夹呢?

Som*_*123 14

我回答这个问题有点晚了,但我发现现有的两个答案有点不清楚。

Tl;博士;只有命令和最少的信息

如果您想要全面详细的解释,请向下滚动到以 开头的部分The 2 keys to mutability

如果您只需要应该运行的命令以及准系统使用信息,以便您知道如何根据您的用例实际调整命令,请阅读此 TL;DR; 部分。

使用 IPNS / DNSLink 引用可更新的 IPFS 对象

IPNS

创建一个密钥,如果在生产中使用则备份它,然后用于ipfs name publish更改密钥当前指向的对象。/ipns/通过在命令/URL 前面添加前缀而不是 .来访问您的密钥/ipfs/

ipfs key gen test
# backup your key if used in production
ipfs key export -o /home/somewhere/safe/test.key test
umount /ipns
ipfs name publish -k test QmWRsWoZjiandZUXLyczXSoWi84hXNHvBQ49BiQx9hPdjs
#    Published to k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0: /ipfs/QmWRsWoZjiandZUXLyczXSoWi84hXNHvBQ49BiQx9hPdjs

ipfs ls /ipns/k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0
# Qme85tx5Wnsjc5pZZs1JGogBNUVM2WThC18ERh6t2YFJSK 37 lorem.txt

ipfs name publish -k test QmaDDLFL3fM4sQkQfV82LdNqtNnyaeAmgC46Qc7FDQdkq8
#    Published to k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0: /ipfs/QmaDDLFL3fM4sQkQfV82LdNqtNnyaeAmgC46Qc7FDQdkq8

# Since it's not a folder this time, we use 'ipfs cat' to read 
# it to the console, since we know the file was plain text.
ipfs cat /ipns/k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0
# foo bar foo bar foo foo foo
# bar foo foo bar bar foo bar
Run Code Online (Sandbox Code Playgroud)

DNS链接

_dnslink在要用作 IPNS 参考的(子)域上方设置 TXT 记录。将值设置为dnslink=/ipns/<id>或 ,dnslink=/ipfs/<id>具体取决于您是将其指向 IPFS 对象还是 IPNS 地址,然后替换<id>为您想要将其指向的对象 ID/IPNS 地址。

ipfs key gen test
# backup your key if used in production
ipfs key export -o /home/somewhere/safe/test.key test
umount /ipns
ipfs name publish -k test QmWRsWoZjiandZUXLyczXSoWi84hXNHvBQ49BiQx9hPdjs
#    Published to k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0: /ipfs/QmWRsWoZjiandZUXLyczXSoWi84hXNHvBQ49BiQx9hPdjs

ipfs ls /ipns/k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0
# Qme85tx5Wnsjc5pZZs1JGogBNUVM2WThC18ERh6t2YFJSK 37 lorem.txt

ipfs name publish -k test QmaDDLFL3fM4sQkQfV82LdNqtNnyaeAmgC46Qc7FDQdkq8
#    Published to k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0: /ipfs/QmaDDLFL3fM4sQkQfV82LdNqtNnyaeAmgC46Qc7FDQdkq8

# Since it's not a folder this time, we use 'ipfs cat' to read 
# it to the console, since we know the file was plain text.
ipfs cat /ipns/k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0
# foo bar foo bar foo foo foo
# bar foo foo bar bar foo bar
Run Code Online (Sandbox Code Playgroud)

就像普通的 IPNS 一样,您现在应该能够使用 IPFS CLI 工具或 IPFS 网关来查询它,而/ipns/<your_domain>不是使用/ipfs/<object_id>.

如果我们现在 cat/ipns/test.privex.io我们可以看到它工作正常,指向 foo bar 文本文件(没有包装文件夹)。

ipfs@privex ~ $ ipfs cat /ipns/test.privex.io
foo bar foo bar foo foo foo
bar foo foo bar bar foo bar
Run Code Online (Sandbox Code Playgroud)

将现有 IPFS 对象 ID 添加到另一个 IPFS 对象(包装文件夹)

使用以下命令,您可以使用各自的对象 ID 将单个 IPFS 文件或整个包装文件夹添加到现有对象,并且该命令将输出一个新的对象 ID,引用包含原始文件夹数据的新对象,以及您要添加的新数据。

该命令的语法是:ipfs object patch add-link [object-to-add-to] [name-of-newly-added-file-or-folder] [object-to-inject]

          Domain:     privex.io
(Subdomain) Name:     _dnslink.test
     Record Type:     TXT
           Value:     dnslink=/ipns/k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0
    TTL (expiry):     120 (seconds)
Run Code Online (Sandbox Code Playgroud)

可变性的 2 个关键

1.尽管内容发生变化,IPFS对象ID仍保持不变

不幸的是,IPFS对象ID(以 Q 开头的 ID)是不可变的,这意味着将来如果不获取新 ID,就无法更改其内容,因为对象 ID 实际上是一个哈希值(通常是 SHA256 的一种形式)。

然而,IPNS 和 DNSLink 都有一个解决方案

IPNS 是“Interplantary Name System”,它与 IPFS 紧密集成。它允许您生成地址(公钥)和私钥,类似于比特币和许多其他加密货币的工作方式。使用您的私钥,您可以指向您的 IPNS

首先,您需要生成一个密钥(注意:您需要为您想要的每个 IPNS 地址提供一个密钥)

ipfs@privex ~ $ ipfs cat /ipns/test.privex.io
foo bar foo bar foo foo foo
bar foo foo bar bar foo bar
Run Code Online (Sandbox Code Playgroud)

如果您计划将 IPNS 地址用于测试以外的其他用途,则应导出私钥并将其副本保存在安全的地方。请注意,私钥是一个二进制文件,因此如果您想将其存储在需要纯文本的地方,您可以将其转换为 base64,如下所示:base64 test.key

ipfs@privex:~$ ipfs object patch add-link QmXCfnzXHThHwaTvSSAKeErxK48XkyVoL6ZNEhkpKmZyW3 hello/foo.txt QmaDDLFL3fM4sQkQfV82LdNqtNnyaeAmgC46Qc7FDQdkq8
QmaWoYZnSXnKqzskrBwtmZPE74qKe4AF5YfwaY83nzeCCL
Run Code Online (Sandbox Code Playgroud)

接下来,我们将向 IPNS 地址发布一个随机 IPFS 文件夹,其中包含一个文件 (lorem.txt),其中包含几行 lorem ipsum 文本。如果您使用 FUSE/ipns文件夹,则可能需要先卸载它,然后才能通过 IPNS 发布:

ipfs@privex:~$ ipfs key gen test
k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0
Run Code Online (Sandbox Code Playgroud)

但这只是一个示例 - 为了证明 IPNS 地址实际上可以使用不同的内容进行更新,在下一个示例中,我将直接将单个文本文件发布到 IPNS 地址(而不是包装的文件夹)。

ipfs key export -o /home/somewhere/safe/test.key test
Run Code Online (Sandbox Code Playgroud)

DNS链接

DNSLink 是IPNS 的一部分,它允许通过标准域系统(例如example.com)提供人类可读的IPNS 地址。

由于 IPNS 部分相当长,因此我将保持这一部分简短而温馨。如果您想了解更多有关 DNSLink 的信息,请访问dnslink.io

首先,您已经有一个可供使用的域,或者您从注册商(例如Namecheap )处获取了一个域。

转到您的域名记录管理面板 - 如果您使用Cloudflare,那么它们就是您的域名管理面板。_dnslink.yourdomain.com如果您想使用子域,请添加 TXT 记录_dnslink.mysub.yourdomain.com(在大多数注册商上,您只需输入您正在管理的域之前的部分,即_dnslink_dnslink.mysub)。

在值框中,输入dnslink=后跟 或/ipfs//ipns/具体取决于您要使用 IPFS 对象 ID 还是 IPNS 名称地址,然后在末尾输入您的对象 ID/IPNS 名称。

例如,如果您将域指向前面示例中的 IPNS 地址,则需要输入:

ipfs@privex:~$ umount /ipns

ipfs@privex:~$ ipfs name publish -k test QmWRsWoZjiandZUXLyczXSoWi84hXNHvBQ49BiQx9hPdjs
    Published to k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0: /ipfs/QmWRsWoZjiandZUXLyczXSoWi84hXNHvBQ49BiQx9hPdjs

ipfs@privex:~$ ipfs ls /ipns/k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0
Qme85tx5Wnsjc5pZZs1JGogBNUVM2WThC18ERh6t2YFJSK 37 lorem.txt
Run Code Online (Sandbox Code Playgroud)

或者,如果您想将其指向包含lorem.txt几行 lorem ipsum 的示例文件夹,则为

# Publish the IPFS object 'QmaDDLFL3fM4sQkQfV82LdNqtNnyaeAmgC46Qc7FDQdkq8' 
# to our existing named key 'test'
ipfs@privex:~$ ipfs name publish -k test QmaDDLFL3fM4sQkQfV82LdNqtNnyaeAmgC46Qc7FDQdkq8

# Since it's not a folder this time, 'ipfs ls' won't return anything. 
# So instead, we use 'ipfs cat' to read it to the console, since we 
# know the file was plain text.
ipfs@privex:~$ ipfs cat /ipns/k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0

foo bar foo bar foo foo foo
bar foo foo bar bar foo bar
Run Code Online (Sandbox Code Playgroud)

出于示例目的,这里总结了我的设置方式test.privex.io

dnslink=/ipns/k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0
Run Code Online (Sandbox Code Playgroud)

设置完成后,IPNS 地址仍然指向原始 foo bar 文本数据,我用来ipfs cat读取域指向的数据:

dnslink=/ipfs/QmWRsWoZjiandZUXLyczXSoWi84hXNHvBQ49BiQx9hPdjs
Run Code Online (Sandbox Code Playgroud)

2. 将现有 IPFS 对象添加到您的对象,而无需下载/组织要添加的对象。

首先我们创建 IPFS 对象 - 一个包含hello/lorem.txt对象 ID 的包装文件夹QmXCfnzXHThHwaTvSSAKeErxK48XkyVoL6ZNEhkpKmZyW3

          Domain:     privex.io
(Subdomain) Name:     _dnslink.test
     Record Type:     TXT
           Value:     dnslink=/ipns/k51qzi5uqu5dkqxbxeulacqmz5ekmopr3nsh9zmgve1dji0dccdy86uqyhq1m0
    TTL (expiry):     120 (seconds)

(note: most people are fine with "auto" TTL, or the somewhat standard 600 TTL. If you intend to change the DNSLink value regularly, or you're experimenting and likely updating it constantly, you may want a low TTL of 60 or even 30)
Run Code Online (Sandbox Code Playgroud)

接下来,为了创建不属于原始包装文件夹一部分的示例外部对象 ID,我创建了foo.txt包含几行随机foo bar文本的文件,并将其单独上传到 IPFS。它的对象ID是QmaDDLFL3fM4sQkQfV82LdNqtNnyaeAmgC46Qc7FDQdkq8

ipfs@privex:~$ ipfs cat /ipns/test.privex.io
foo bar foo bar foo foo foo
bar foo foo bar bar foo bar

Run Code Online (Sandbox Code Playgroud)

最后,我们将我之前创建的对象 ( )ipfs object patch add-link添加到我创建的原始包装文件夹 ( ) 的文件夹内。foo.txtQmaDDLFL3fM4sQkQfV82LdNqtNnyaeAmgC46Qc7FDQdkq8hello/QmXCfnzXHThHwaTvSSAKeErxK48XkyVoL6ZNEhkpKmZyW3

该命令的语法是:ipfs object patch add-link [object-to-add-to] [name-of-newly-added-file-or-folder] [object-to-inject]


ipfs@privex:~$ mkdir hello
ipfs@privex:~$ echo -e "lorem ipsum dolor\nlorem ipsum dolor\n" > hello/lorem.txt

ipfs@privex:~$ ipfs add -p -r -w hello
added Qme85tx5Wnsjc5pZZs1JGogBNUVM2WThC18ERh6t2YFJSK hello/lorem.txt
added QmWRsWoZjiandZUXLyczXSoWi84hXNHvBQ49BiQx9hPdjs hello
added QmXCfnzXHThHwaTvSSAKeErxK48XkyVoL6ZNEhkpKmZyW3
 37 B / 37 B [=======================================================================] 100.00%

ipfs@privex:~$ ipfs ls QmXCfnzXHThHwaTvSSAKeErxK48XkyVoL6ZNEhkpKmZyW3
QmWRsWoZjiandZUXLyczXSoWi84hXNHvBQ49BiQx9hPdjs - hello/

ipfs@privex:~$ ipfs ls QmXCfnzXHThHwaTvSSAKeErxK48XkyVoL6ZNEhkpKmZyW3/hello
Qme85tx5Wnsjc5pZZs1JGogBNUVM2WThC18ERh6t2YFJSK 37 lorem.txt
Run Code Online (Sandbox Code Playgroud)

它输出一个新的对象 ID,QmaWoYZnSXnKqzskrBwtmZPE74qKe4AF5YfwaY83nzeCCL该 ID 是新创建的对象的 ID,其中包含hello/lorem.txt原始对象的 ID 和hello/foo.txt稍后注入的对象的 ID。

注意:当将整个包装文件夹添加到另一个包装文件夹时,此命令也适用,但请小心避免双重嵌套。例如,您有Qxxxx/hello/world-Qyyyy/lorem/ipsum如果您将 Qyyyy 添加到 Qxxxx 并指定名称lorem- 它将被添加为Qzzzz/lorem/lorem/ipsum

如果我们现在ipfs ls对新的对象 ID 进行操作,我们可以看到子hello/文件夹同时包含foo.txt-lorem.txt确认 foo.txt 已成功注入到副本中,而无需下载原始文件和 foo.txt - 然后正确组织它们上传之前放在一个文件夹中。

ipfs@privex:~$ echo -e "foo bar foo bar foo foo foo\nbar foo foo bar bar foo bar\n" > foo.txt

ipfs@privex:~$ ipfs add foo.txt
added QmaDDLFL3fM4sQkQfV82LdNqtNnyaeAmgC46Qc7FDQdkq8 foo.txt
 57 B / 57 B [======================================================================] 100.00%
Run Code Online (Sandbox Code Playgroud)

概括

正如第一节中所解释的,IPFS 对象 ID 是不可变的,因此虽然可以合并 IPFS 上的现有对象,但它仍然会产生新的对象 ID。

但是,通过使用 IPNS 密钥地址和/或 DNSLink,您可以拥有指向任何 IPFS 对象的可变(可编辑)引用,并且可以按需更新为指向新的对象 ID,例如,每当您更新一个现有的对象,或者如果您决定只是希望您的 IPNS 密钥/域指向完全不同的东西,您可以自由地这样做:)

  • 史诗般的答案。Thk u。 (2认同)

Jay*_*ayB 11

您只能在再次下载后使用ipns来执行此操作,ipfs get如果仍然固定在本地存储上,则应该很快:

(1)首先递归(即重新添加)你的文件夹递归到ipfs : ipfs add -r /path/to/folder. 最后一个stdout行的第二列包含刚刚添加的父文件夹的ipfs哈希.(原始文件仍然相同,因此哈希也是一样的.)

(2)然后发布那个哈希:ipfs name publish /ipfs/<CURRENT_PARENTFOLDER_HASH>.这将返回您的对等ID,您可以共享链接/ipns/<PEER_ID>; ipfs name publish每当文件夹内容(以及父文件夹哈希)发生更改时,重复此步骤().然后,ipns对象将始终指向文件夹的最新版本.

(3)如果你计划分享很多,你可以为你共享的每个文件夹创建一个新的密钥对:ipfs key gen --type=rsa --size=2048 new-share-key...然后使用该密钥(而不是你的默认密钥)发布(以后再重新发布)该文件夹:ipfs name publish --key=new-share-key /ipfs/<CURRENT_PARENTFOLDER_HASH>

另请参阅此处的文档:https://ipfs.io/docs/commands/#ipfs-name-publish


Cae*_*sar 7

使用文件API应该很容易.假设您已将新文件添加到ipfs并获取其哈希值,请尝试:

ipfs files cp /ipfs/QmExistingLargeFolderHash /folder-to-modify
ipfs files cp /ipfs/QmNewFileHash /folder-to-modify/new-file
Run Code Online (Sandbox Code Playgroud)

这当然不会将文件添加到现有文件夹(因为文件夹和文件是不可变的),它只是创建了添加了新文件的文件夹的副本/新版本.因此,它将有一个新的哈希:

ipfs files stat /folder-to-modify
Run Code Online (Sandbox Code Playgroud)

除非必要,文件API不会固定引用的文件或检索任何子文件夹,因此可以在网络中的任何节点上完成此操作,而不会产生大量流量.

[编辑]过了一会儿,我了解到还有一些事情你可以做:

  • 代替

    ipfs files cp /ipfs/QmNewFileHash /folder-to-modify/new-file
    
    Run Code Online (Sandbox Code Playgroud)

    ipfs files write -te如果你还没有将文件添加到ipfs,你可以使用.

  • 您可以启用HTTP API的写入功能,以使用PUT请求获取文件夹新版本的哈希值.请参阅此博文.
  • 你可以通过保险丝挂载ipns并写入…/ipns/local.
  • 也许最好:你可以ipfs object patch add-link /ipfs/QmExistingLargeFolderHash new-file /ipfs/QmNewFileHash一步到位地完成它