如何创建与IPFS兼容的multihash

时间:2016-12-06 15:11:53

标签: ipfs

我尝试创建兼容IPFS的mutihash,但它不匹配。我在这里问,因为我还没有找到一个从散列到最终结果的例子。

echo -n multihash > multihash.txt


ipfs add multihash.txt
added QmZLXzjiZU39eN8QirMZ2CGXjMLiuEkQriRu7a7FeSB4fg multihash.txt


sha256sum multihash.txt
9cbc07c3f991725836a3aa2a581ca2029198aa420b9d99bc0e131d9f3e2cbe47  multihash.txt

node

> var bs58=require('bs58')
bs58.encode(new Buffer('9cbc07c3f991725836a3aa2a581ca2029198aa420b9d99bc0e131d9f3e2cbe47','hex'))
'BYptxaTgpcBrqZx9tghNCWFfUuYBcGfLydEvDjXqBV7k'

> var mh=require('multihashes')
mh.toB58String(mh.encode(new Buffer('9cbc07c3f991725836a3aa2a581ca2029198aa420b9d99bc0e131d9f3e2cbe47','hex'), 'sha2-256'))
'QmYtUc4iTCbbfVSDNKvtQqrfyezPPnFvE33wFmutw9PBBk'

目的是使用multihashes包重新创建IPFS路径QmZLXzjiZU39eN8QirMZ2CGXjMLiuEkQriRu7a7FeSB4fg

我可以创建相同的哈希QmYtUc...9PBBk,如下例所示:https://github.com/multiformats/multihash#example

6 个答案:

答案 0 :(得分:8)

IPFS使用multihash,其格式如下:

  

base58(

哈希函数代码列表可在this table中找到。

以下是使用SHA2-256作为哈希函数的进程的伪代码。

sha2-256   size  sha2-256("hello world")
0x12       0x20  0xb94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9

将这三个项目串联起来会产生

1220b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9

然后将其编码为base58

QmaozNR7DZHQK1ZcU9p7QdrshMvXqWK6gpu5rmrkPdT3L4

以下是如何在JavaScript中实质上实现多哈希的示例:

const crypto = require('crypto')
const bs58 = require('bs58')

const data = 'hello world'

const hashFunction = Buffer.from('12', 'hex') // 0x20

const digest = crypto.createHash('sha256').update(data).digest()

console.log(digest.toString('hex')) // b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9

const digestSize = Buffer.from(digest.byteLength.toString(16), 'hex')

console.log(digestSize.toString('hex')) // 20

const combined = Buffer.concat([hashFunction, digestSize, digest])

console.log(combined.toString('hex')) // 1220b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9

const multihash = bs58.encode(combined)

console.log(multihash.toString()) // QmaozNR7DZHQK1ZcU9p7QdrshMvXqWK6gpu5rmrkPdT3L4

有一个CLI可用于生成多哈希:

$ go get github.com/multiformats/go-multihash/multihash
$ echo -n "hello world" | multihash -a sha2-256
QmaozNR7DZHQK1ZcU9p7QdrshMvXqWK6gpu5rmrkPdT3L4

如@David所说, IPFS中的文件被“转换”为Unixfs“文件”,它是DAG 中文件的表示。因此,当您使用add将文件上传到IPFS时,数据具有元数据包装器,当您对其进行多哈希处理时,它会为您提供不同的结果。

例如:

$ echo -n "hello world" | ipfs add -Q
Qmf412jQZiuVUtdgnB36FXFX7xg5V6KEbSJ4dpQuhkLyfD

这是Node.js中的一个示例,该示例如何生成与ipfs add完全相同的多重哈希:

const Unixfs = require('ipfs-unixfs')
const {DAGNode} = require('ipld-dag-pb')

const data = Buffer.from('hello world', 'ascii')
const unixFs = new Unixfs('file', data)

DAGNode.create(unixFs.marshal(), (err, dagNode) => {
  if (err) return console.error(err)

  console.log(dagNode.toJSON().multihash) // Qmf412jQZiuVUtdgnB36FXFX7xg5V6KEbSJ4dpQuhkLyfD
})

希望这会有所帮助

答案 1 :(得分:2)

IPFS中的文件被转换为'在一个Unixfs文件中,它是DAG中文件的表示,在您的示例中,您使用sha2-256直接对您的multihash.txt进行哈希处理,但IPFS内部发生的事情是:

答案 2 :(得分:0)

dagNode.toJSON()。多散列

multihash 来自何处?

对于字符串'hello world', 如果我将JSON.stringify(dagNode.toJSON())与上面提供的multihash函数一起使用,则会得到以下哈希:QmVcA1pgWVK56usYp8ksob25gcfLmR4NggRi5kqz1Rmzfh

但是,ipfs返回此哈希:Qmf412jQZiuVUtdgnB36FXFX7xg5V6KEbSJ4dpQuhkLyfD

有人能写出一整篇有效的文章吗?不仅仅是您认为重要的部分。但是,将每个部分放在一起可能对我们其他人来说是挑战/耗时的。

答案 3 :(得分:0)

const { randomBytes } = require('crypto')
const multihash = require('multihashes')

const buffer = Buffer.from(randomBytes(32), 'hex')
const encoded = multihash.encode(buffer, 'sha2-256')
const hash = multihash.toB58String(encoded)
console.log(hash)

答案 4 :(得分:0)

当前最简单的方法是简单地使用ipfs-http-client。在该线程中,以上所有以前的解决方案都不再对我有用。

import ipfsClient from "ipfs-http-client";
const ipfs = ipfsClient(IPFS_PROVIDER, "5001", { protocol: "https" });

// onlyHash: true only generates the hash and doesn't upload the file
const hash = (await ipfs.add(new Buffer(vuln), { onlyHash: true }))[0].hash

答案 5 :(得分:0)

其他一些答案已过时。这对我有用:

    const Unixfs = require('ipfs-unixfs'); // @0.1.16
    const { DAGNode } = require('ipld-dag-pb'); // @0.18.1
    const bs58 = require('bs58'); // @4.0.1

    // ...

    const data = Buffer.from('hello world');
    const unixFs = new Unixfs('file', data)
    const dagNode = new DAGNode(unixFs.marshal());
    const link = await dagNode.toDAGLink();
    const multihash = bs58.encode(link._cid.multihash).toString();
    console.log(multihash); // Qmf412jQZiuVUtdgnB36FXFX7xg5V6KEbSJ4dpQuhkLyfD