首页 文章

如何在IPFS中重新创建多哈的哈希摘要

提问于
浏览
3

假设我正在向IPFS添加数据,如下所示:

$ echo Hello World | ipfs add

这将给我 QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u - 一个Base58编码的Multihash的CID .

将它转换为Base16,告诉我IPFS添加的哈希摘要是SHA2-256哈希:

12 - 20 - 74410577111096cd817a3faed78630f2245636beded412d3b212a2e09ba593ca
<hash-type> - <hash-length> - <hash-digest>

我知道IPFS不只是对数据进行散列,而是先将它序列化为Unixfs protobuf,然后将其置于dag中 .

我想揭开神秘面纱,如何到达 74410577111096cd817a3faed78630f2245636beded412d3b212a2e09ba593ca ,但我不确定如何 grab 创建的dag,其中包含Unixfs protobuf和数据 .

例如,我可以将序列化的原始数据写入磁盘并使用protobuf解码器进行检查:

$ ipfs block get QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u > /tmp/block.raw
$ protoc --decode_raw < /tmp/block.raw

这将以可读格式提供序列化数据:

1 {
  1: 2
  2: "Hello World\n"
  3: 12
}

然而,通过SHA-256的管道仍然给我一个不同的哈希,这是有道理的,因为IPFS将protobuf放在一个dag和multihashes中 .

$ protoc --decode_raw < /tmp/block.raw | shasum -a 256

所以我决定弄清楚如何 grab 那个dag节点,自己哈希以获得我正在寻找的哈希 .

我希望使用 ipfs dag get QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u 会给我一个可以解码的multihash,但事实证明它返回了一些我不知道如何检查的其他数据哈希:

$ ipfs dag get QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u
$ {"data":"CAISDEhlbGxvIFdvcmxkChgM","links":[]}

关于如何从这里解码 data 的任何想法?

UPDATE

data 是原始数据的Base64表示形式:https://github.com/ipfs/go-ipfs/issues/4115

2 回答

  • 1

    您正在寻找的哈希是 ipfs block get QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u 输出的哈希值 . IPFS散列编码值 .

    而不是运行:

    protoc --decode_raw < /tmp/block.raw | shasum -a 256
    

    赶紧跑:

    shasum -a 256 < /tmp/block.raw
    

    但事实证明它返回了一些我不知道如何检查的其他数据哈希

    那是因为我们目前在protobuf中使用protobuf . 外部protobuf具有 {Data: DATA, Links: [{Name: ..., Size: ..., Hash: ...}]} 结构 .

    在:

    1 {
      1: 2
      2: "Hello World\n"
      3: 12
    }
    

    1 { ... } 部分是外部protobuf的数据字段 . 但是, protoc --decode_raw *recursively* decodes this object so it decodes the Data`字段:

    • 字段1(数据类型):2(文件)

    • 第2场(数据):"Hello World\n"

    • 字段3(文件大小):12(字节)

    对于上下文,相关的protobuf定义是:

    外:

    // An IPFS MerkleDAG Link
    message PBLink {
    
      // multihash of the target object
      optional bytes Hash = 1;
    
      // utf string name. should be unique per object
      optional string Name = 2;
    
      // cumulative size of target object
      optional uint64 Tsize = 3;
    }
    
    // An IPFS MerkleDAG Node
    message PBNode {
    
      // refs to other objects
      repeated PBLink Links = 2;
    
      // opaque user data
      optional bytes Data = 1;
    }
    

    内:

    message Data {
        enum DataType {
            Raw = 0;
            Directory = 1;
            File = 2;
            Metadata = 3;
            Symlink = 4;
            HAMTShard = 5;
        }
    
        required DataType Type = 1;
        optional bytes Data = 2;
        optional uint64 filesize = 3;
        repeated uint64 blocksizes = 4;
    
        optional uint64 hashType = 5;
        optional uint64 fanout = 6;
    }
    
    message Metadata {
        optional string MimeType = 1;
    }
    
  • 1

    我不确定编码是什么,但你可以在js-ipfs中解组这样的dag数据字段:

    const IPFS = require('ipfs')
    const Unixfs = require('ipfs-unixfs')
    
    const ipfs = new IPFS
    
    ipfs.dag.get('QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u', (err, d) => {
      console.log(Unixfs.unmarshal(d.value.data).data.toString()))
      // prints Hello World
    })
    

相关问题