如何创建与IPFS兼容的multihash

jca*_*314 7 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'
Run Code Online (Sandbox Code Playgroud)

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

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

Mig*_*ota 8

IPFS使用multihash,格式如下:

base58(<varint hash function code> <varint digest size in bytes> <hash function output>)

可以在此表中找到散列函数代码列表.

这是使用SHA2-256作为散列函数的过程的一些伪代码.

sha2-256   size  sha2-256("hello world")
0x12       0x20  0xb94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
Run Code Online (Sandbox Code Playgroud)

连接这三个项目将产生

1220b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
Run Code Online (Sandbox Code Playgroud)

然后将其编码为base58

QmaozNR7DZHQK1ZcU9p7QdrshMvXqWK6gpu5rmrkPdT3L4
Run Code Online (Sandbox Code Playgroud)

这是一个如何在JavaScript中实现multihash的示例:

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
Run Code Online (Sandbox Code Playgroud)

您可以使用CLI生成多重分支:

$ go get github.com/multiformats/go-multihash/multihash
$ echo -n "hello world" | multihash -a sha2-256
QmaozNR7DZHQK1ZcU9p7QdrshMvXqWK6gpu5rmrkPdT3L4
Run Code Online (Sandbox Code Playgroud)

正如@David所说,IPFS中的一个文件被"转换"为一个Unixfs"文件",它代表了DAG中的文件.因此,当您使用add上传文件到IPFS时,数据具有元数据包装器,当您对其进行多重处理时,它将为您提供不同的结果.

例如:

$ echo -n "hello world" | ipfs add -Q
Qmf412jQZiuVUtdgnB36FXFX7xg5V6KEbSJ4dpQuhkLyfD
Run Code Online (Sandbox Code Playgroud)

这是Node.js中如何生成完全相同的multihash的示例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
})
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助