† IPFSを実行しながら学んでいく5 ~ js-ipfsでの追加と取得 ~

2022.07.14

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

go-ipfsを使ってIPFSを操作を行なっていましたが、これの他にJavascriptで操作できるライブラリがあります。

JS-IPFS 

このライブラリは、コマンドラインアプリケーションとして、またはプログラムで直接IPFSノードを起動するためのライブラリとして使用できて、 全てのIPFSプロトコルの機能をすべて実現しているとのことです。

今回はこれをインストールして使っていきたいと思います。

やってみる

インストール

npmを使ってインストールできます。

npm install -g ipfs

コマンドラインからも実行できます。

jsipfs <<コマンド>>

で、go-ipfsの時と同じことが実行できます。

$ jsipfs init

を実行し、ipfs nodeを初期化します。

実行ユーザーのホームディレクトリに.jsipfsというフォルダが作成されます。これがjsipfsで使用するレポジトリとなります。

コマンドラインで実行する必要がない場合は、

$ npm install ipfs-core

でipfs-core パッケージを使用します。 ipfsのすべての機能を備えていますが、より軽量なパッケージです。

IPFSにコンテンツを追加

コマンドライン

$ jsipfs add sample-15s.mp4
added QmQkL8yboMWQVtGt56a2gKc4NaUiSTH2hxAkz3RxuEbt3F sample-15s.mp4

Node.js

ipfs-coreをインポートして使用します。

import * as IPFS from 'ipfs-core'

const node = await IPFS.create()

const result = await node.add('Hello world')
console.info(result)

/*
{
  path: 'QmNRCQWfgze6AbBCaT1rkrkV5tJ2aP4oTNPb5JZcXYywve',
  cid: CID(QmNRCQWfgze6AbBCaT1rkrkV5tJ2aP4oTNPb5JZcXYywve),
  size: 19,
  mode: 420,
  mtime: undefined
}
*/

ファイルを読み込む例)

import * as IPFS from 'ipfs-core'
const node = await IPFS.create()

fs.readFile("./sample-15s.mp4", async(err, data) => {
    const result = await node.add(data)
    console.info(result)
})

/* 
{
  path: 'QmQkL8yboMWQVtGt56a2gKc4NaUiSTH2hxAkz3RxuEbt3F',
  cid: CID(QmQkL8yboMWQVtGt56a2gKc4NaUiSTH2hxAkz3RxuEbt3F),
  size: 11919388,
  mode: 420,
  mtime: undefined
}
*/

addの仕様はこちらに。

ipfs.add(data, [options]) という形で使いますが、dataには、

  • FileContent
    • Uint8Array | Blob | String | Iterable<Uint8Array> | Iterable<number> | AsyncIterable<Uint8Array> | ReadableStream<Uint8Array> のタイプ
    • 上記のコードはこのFileContentを引数に与えた形
  • FileObject
    • 以下のような形式のプレーンなJSオブジェクト
{
  // The path you want the file to be accessible at from the root CID _after_ it has been added
  path?: string
  // The contents of the file (see below for definition)
  content?: FileContent
  // File mode to store the entry with (see https://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation)
  mode?: number | string
  // The modification time of the entry (see below for definition)
  mtime?: UnixTime
}

のどちらかが使えます。

IPFSからコンテンツを取得

catを使うと、有効なIPFSのパスで指定されたファイルを取得できます。

コマンドライン

$ jsipfs cat QmNRCQWfgze6AbBCaT1rkrkV5tJ2aP4oTNPb5JZcXYywve

/*
Hello world
*/

Node.js

import * as IPFS from 'ipfs-core'

const node = await IPFS.create()
const stream = node.cat('QmNRCQWfgze6AbBCaT1rkrkV5tJ2aP4oTNPb5JZcXYywve')

const decoder = new TextDecoder()
let data = ''

for await (const chunk of stream) {
  data += decoder.decode(chunk, { stream: true })
}

console.log(data)

/*
Hello world
*/

catの仕様はこちら

IPFSのパスからAsyncIterable<Uint8Array>が返ってきます。

lsを使ったリストアップも。

import * as IPFS from 'ipfs-core'
for await (const file of node.ls('QmNRCQWfgze6AbBCaT1rkrkV5tJ2aP4oTNPb5JZcXYywve')) {
    console.log(file)
}
/*
{
  cid: CID(QmNRCQWfgze6AbBCaT1rkrkV5tJ2aP4oTNPb5JZcXYywve),
  path: 'QmNRCQWfgze6AbBCaT1rkrkV5tJ2aP4oTNPb5JZcXYywve',
  name: 'QmNRCQWfgze6AbBCaT1rkrkV5tJ2aP4oTNPb5JZcXYywve',
  size: 11,
  type: 'file',
  mode: 420
}
*/

// ディレクトリ
for await (const file of node.ls('QmNRCQWfgze6AbBCaT1rkrkV5tJ2aP4oTNPb5JZcXYywve')) {
    console.log(file)
}
/*
{
  cid: CID(QmUhfSscnyJx72Lwuhxaz14FAwHq9zePS6H7uqWhRL3NhL),
  path: 'QmWRXMG73rTSFhtLRBxLhWNvUpKwUoSA3EJArPvRXd2LGU/hls.html',
  name: 'hls.html',
  size: 1430,
  type: 'file',
  mode: 420
}
{
  cid: CID(QmQSSS6NcTE8bPstCDc6rucfXFjErNkJDooAh9ou1ss47L),
  path: 'QmWRXMG73rTSFhtLRBxLhWNvUpKwUoSA3EJArPvRXd2LGU/sample.js',
  name: 'sample.js',
  size: 55,
  type: 'file',
  mode: 420
}
*/

ipfs.ls(ipfsPath)呼び出しますが、ipfsPathは ipfsのパスかCID のどちらかを指定できます

最後に

追加と取得だけでしたが、js-ipfsを使ってJavascriptでIPFSの操作を体験できました。

全てを試すことはできていませんが、ipfsを使ったアプリケーションを作成したい人はぜひ使ってみてください。