如何创建与 IPFS 兼容的多哈希
Posted
技术标签:
【中文标题】如何创建与 IPFS 兼容的多哈希【英文标题】:How to create an IPFS compatible multihash 【发布时间】:2017-04-21 06:49:35 【问题描述】:我正在尝试创建一个与 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
【问题讨论】:
我经历了几乎相同的过程:0kalmi.blogspot.hu/2015/12/what-goes-into-ipfs-multihash.html 【参考方案1】: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
)
【讨论】:
是否可以验证/检查创建的 ipfs 哈希是否有效? @米格尔·莫塔 @alper 您可以检查变量的格式,检查一组已知的哈希函数,并验证长度是否与后面的任何数据匹配。对于固定长度的哈希函数,您还可以验证长度是否“正确”。 我在以下链接上找到了执行此操作的功能:github.com/ipld/py-cid@Arthur2e5【参考方案2】:IPFS 中的文件被“转换”为 Unixfs 文件,这是 DAG 中文件的表示形式,在您的示例中,您使用 sha2-256 直接对 multihash.txt 进行哈希处理,但 IPFS 内部发生的情况是:
文件被分块成 256KiB 的片段 每个块都进入 Unixfs protobuf https://github.com/ipfs/js-ipfs-unixfs 内的一个 DAG 节点 创建了一个 dag,其中包含指向所有块的链接。【讨论】:
如果一个文件夹有2个不同的文件,如何获取主文件夹的hash?【参考方案3】:其他一些答案已经过时了。这对我有用:
const UnixFS = require('ipfs-unixfs') // @4.0.3
const DAGNode = require('ipld-dag-pb') // @0.22.2
const data = Buffer.from("Hello World\n")
const file = new UnixFS(data)
const node = new DAGNode(file.marshal())
const link = await node.toDAGLink()
const cid = link.Hash
console.log(cid.toV0().toString())
// Qmf412jQZiuVUtdgnB36FXFX7xg5V6KEbSJ4dpQuhkLyfD
【讨论】:
【参考方案4】: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)
【讨论】:
【参考方案5】:目前最简单的方法是简单地使用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
【讨论】:
以上是关于如何创建与 IPFS 兼容的多哈希的主要内容,如果未能解决你的问题,请参考以下文章
Filecoin官方资讯:宣布Filecoin虚拟机,存储 + 计算 = 腾飞
如何将 Access 报表(包括子报表)保存为 Excel 兼容文件和可读 PDF?
让IPFS一直在后台运行,顺带学习如何创建一个service服务