IPFS初窥3
source link: http://www.hi-roy.com/2018/10/10/IPFS初窥3/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
在上一篇文章中记录到了IPFS的 BitSwap
协议,今天接着往下看关于 Object
的部分。
Merkle DAG
Merkle DAG是IPFS核心概念之一,在Git的数据结构上进行了改造。理解Merkle DAG之前先来了解下 Merkle Tree 。
简单说,Merkle Tree是一种特殊的树结构,其叶子节点的值为包含记录的哈希值,而非叶子节点的值为子节点哈希值合并后的哈希结果,一图胜千言:
Merkle Tree最常见的一个应用就是数据验证领域了,这种数据结构可以大量减少验证所需传输的数据量,在 Top Hash
已知的情况下想验证L3中的数据是否被篡改过,只需要向一个可信任的中心请求获取 Hash0
和 Hash1-1
即可。
正由于比特币中将Merkle Tree的根哈希值包含在了区块头中,所以各种轻钱包(SPV)才得以出现。
而Merkle DAG则是一种 有向无环图 结构,而且和Merkle Tree有个很重要的区别就是Merkle DAG中准许非叶节点存储数据。IPFS中数据结构定义如下:
type IPFSLink struct { Name string Hash Multihash Size int } type IPFSObject struct{ links []IPFSLink data []byte }
首先我们有这样一个目录结构:
ipfs ├── imgs │ └── 1.jpg ├── test.txt └── video └── paxos和分布式系统.mp4
然后执行 add
命令添加:
ipfs add -r ipfs added QmTBGNDfodpscKje46wyTmzsPsJ6REWebionWK9dVc2Cms ipfs/imgs/1.jpg added QmRmfJ8RYrULTZkjt9H11kkPBswrzVQXf36QAF3XoBG6XZ ipfs/test.txt added Qme5oV4uKLA2BDVjFtqiCfFqv74LZXTqG1oiuu5gshqvk7 ipfs/video/paxos和分布式系统.mp4 added QmQEwN1jbjPPAnfjnbXjCi92yKu7gZbZnmK2niotz4d8oK ipfs/imgs added QmVYaDuyoS4otNXnQ7WRbBP4ZZuLi7PLhyz2LV9vLWVwWb ipfs/video added QmPkbxXPM2hY97NR8Tf25KZxysWn4FZrsuPwD8ztYM32j4 ipfs 53.15 MiB / 53.16 MiB [=============================================================================================================================================================] 99.98%
这里插一句,在浏览器中访问
http://localhost:8080/ipfs/QmTBGNDfodpscKje46wyTmzsPsJ6REWebionWK9dVc2Cms http://localhost:8080/ipfs/QmQEwN1jbjPPAnfjnbXjCi92yKu7gZbZnmK2niotz4d8oK/1.jpg http://localhost:8080/ipfs/QmPkbxXPM2hY97NR8Tf25KZxysWn4FZrsuPwD8ztYM32j4/imgs/1.jpg
这3种访问路径都可以最终得到 1.jpg
这个图片。
可以使用 ls
命令查看文件切分情况:
ipfs ls -v Qme5oV4uKLA2BDVjFtqiCfFqv74LZXTqG1oiuu5gshqvk7 Hash Size Name QmexC2a5eSkVuoErKhAjxpMt6DJoQeS57T3yU1cxCpb3Tu 45623854 QmR2GQi1DhvGzZ1Ra1fgpwKBTd9ubt9aPUSCvqMZPHB3cp 10103195
可以看出,mp4文件被切分成了2部分。
再使用 object get
命令查看 ipfs
这个文件夹的DAG:
ipfs object get QmPkbxXPM2hY97NR8Tf25KZxysWn4FZrsuPwD8ztYM32j4 { "Links": [ { "Name": "imgs", "Hash": "QmQEwN1jbjPPAnfjnbXjCi92yKu7gZbZnmK2niotz4d8oK", "Size": 18418 }, { "Name": "test.txt", "Hash": "QmRmfJ8RYrULTZkjt9H11kkPBswrzVQXf36QAF3XoBG6XZ", "Size": 18 }, { "Name": "video", "Hash": "QmVYaDuyoS4otNXnQ7WRbBP4ZZuLi7PLhyz2LV9vLWVwWb", "Size": 55727234 } ], "Data": "\u0008\u0001" }
也和上面给的数据结构定义一致。
还有更重要的一点,IPFS准许使用者使用 block
相关命令直接操作Merkle DAG中的数据,比如:
echo "hi roy" | ipfs block put QmUHW9uK8aKYHNSSJwS1AnnBt1dV6wbKmDWDr8tmRk9pXo ipfs block get QmUHW9uK8aKYHNSSJwS1AnnBt1dV6wbKmDWDr8tmRk9pXo hi roy
有这个功能可玩性就很高了,白皮书中给出了几种结构:
- 键值对存储(key-value stores)
- 关系型数据库(traditional relatioinal databases)
- 三元组存储(Linked Data triple stores)
- 文档发布系统(Linked document publishing systems)
- 通信平台(Linked communications platforms)
- 加密货币区块链(cryptocurrency blockchains)
再插一句,很多小伙伴不知道如何向已经存在的文件夹中添加新文件,比如想向 ipfs
目录添加文件 test2.txt
:
ipfs add test2.txt added QmUARAWmSHC3aiWhYFcGfQGEyfAKdUPWqFHxemY3iDJDRM test2.txt 11 B / 11 B [=======================================================================================================================================================================] 100.00% ipfs ls -v QmPkbxXPM2hY97NR8Tf25KZxysWn4FZrsuPwD8ztYM32j4 Hash Size Name QmQEwN1jbjPPAnfjnbXjCi92yKu7gZbZnmK2niotz4d8oK 18418 imgs/ QmRmfJ8RYrULTZkjt9H11kkPBswrzVQXf36QAF3XoBG6XZ 18 test.txt QmVYaDuyoS4otNXnQ7WRbBP4ZZuLi7PLhyz2LV9vLWVwWb 55727234 video/
可以发现文件并没有添加进文件夹中,而仅仅是获得了一个自己的哈希值。可以使用下面的命令:
ipfs object patch add-link QmPkbxXPM2hY97NR8Tf25KZxysWn4FZrsuPwD8ztYM32j4 test21.txt QmUARAWmSHC3aiWhYFcGfQGEyfAKdUPWqFHxemY3iDJDRM QmZzY6fgW2ndjoAXpa2gMSaJ3c8h6hzq1TFusdF33u2jvy
这里会返回一个新的哈希值,查看这个发现文件已经被添加进去了:
ipfs ls -v QmZzY6fgW2ndjoAXpa2gMSaJ3c8h6hzq1TFusdF33u2jvy Hash Size Name QmQEwN1jbjPPAnfjnbXjCi92yKu7gZbZnmK2niotz4d8oK 18418 imgs/ QmRmfJ8RYrULTZkjt9H11kkPBswrzVQXf36QAF3XoBG6XZ 18 test.txt QmUARAWmSHC3aiWhYFcGfQGEyfAKdUPWqFHxemY3iDJDRM 19 test21.txt QmVYaDuyoS4otNXnQ7WRbBP4ZZuLi7PLhyz2LV9vLWVwWb 55727234 video/
注意存储后的文件名是 ipfs object patch add-link
中指定的值,而不是原文件名。再多说一句,这个命令需要的参数仅仅是哈希值,换言之如果你知道其他人的link地址也可以加到自己的文件下。
另外,最新的文件系统已经变成IPLD了,是Merkle DAG的一个变种。
IPNS
由上面的例子也可以看出来,在IPFS中每次新增、修改某个文件都会导致哈希值的变化,这对于实际应用中是十分不便的。为了处理这个问题,IPFS中引入了一个可变命名空间的概念——IPNS(InterPlanetary Name Space),结合之前说的 路由系统 实现了”不可变的内容”和”可变的引用”的组合(可以结合编程语言中指针的概念):
routing.setValue(NodeId,<ns-object-hash>)
之前说过每个节点的NodeID来源与其公钥的哈希值,那么给每个节点分配一个可变命名空间 /ipns/<NodeID>
,用户将私钥签名过的数据发布到这个路径上,别的用户下载这个数据时可以检查签名是否和公钥、NodeID匹配来验证真实性。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK