はじめに
『DApps開発入門』という本や色々記事を書いているかるでねです。
今回は、IPFSのハッシュをENSに登録・取得できるようにする仕組みを提案しているERC1062についてまとめていきます!
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
他にも様々なEIPについてまとめています。
概要
ERC1062は、IPFS(InterPlanetary File System)に保存されたリソースと、Ethereum上のネーミングサービスであるENS(Ethereum Naming Service)との間のマッピング手法を提案しています。
具体的には、IPFSの暗号学的ハッシュ(ファイルの一意の指紋)をENSのPublic Resolverと連携させることで、IPFS上のリソースをENSから「取得」および「設定」できる機能を提供します。
この仕組みによって、開発者やコミュニティはより多くのユースケースを提供できるようになるだけでなく、ENSの人間にとって読みやすい名前を通じて、ユーザーが分散型リソースへより簡単にアクセスできるようになります。
IPFSとENSの連携は、今後のWeb3.0サービスの基盤技術として重要な役割を担うと位置づけられています。
動機
完全な分散型Webサービスを構築するためには、分散型のファイルストレージが必要です。
IPFSは、以下の3つの利点からその要件を満たす存在です。
-
大容量データの管理と一意の識別
IPFSでは、すべてのファイルに暗号学的に一意なハッシュが与えられるため、整合性のあるデータ管理が可能です。 -
P2Pネットワークによる効率的な配信
IPFSはピア・ツー・ピア型のネットワークで構成されており、分散的かつ安全に大量のデータを配信できます。これにより、中央集権的なサーバーに依存せずに帯域コストの削減が可能となります。 -
バージョン管理と重複排除による効率化
ファイルごとに履歴が追跡され、ネットワーク全体で重複を排除する仕組みにより、ストレージ効率が向上します。
この特徴はENSとの統合に非常に適しており、ユーザーは通常のブラウザを使ってENS名を入力するだけでIPFS上のコンテンツに簡単にアクセスできるようになります。
仕様
IPFSのファイル識別子(フィンガープリント)はBase58形式で表現されますが、EthereumのAPIではバイナリデータを16進数(Hex)形式で扱います。
そのため、IPFSのアドレスをENSに保存・取得する際には、Base58とHexの間で相互変換が必要になります。
この変換には「バイナリバッファ」を用いることで両者の橋渡しを行います。
具体的には、以下の流れで処理します。
- IPFSのBase58文字列をバイナリバッファに変換。
- そのバッファをHex形式に変換して、ENSのコントラクトに保存。
- ENSからIPFSアドレスを取得する時には、Hex形式の値を取り出して再びバッファに戻してからBase58文字列に再変換。
この仕組みによって、ENSのレコードとIPFS上のファイルを正確に紐付けることができます。
実装
この仕様を実装するには、ENSのPublic Resolverが提供する以下の2つの関数が必要になります。
-
setMultihash
- ENSの特定ノードに対してIPFSのハッシュを登録。
-
multihash
- 登録されたIPFSのハッシュを取得。
setMultihash
function setMultihash(bytes32 node, bytes hash) public only_owner(node);
IPFSハッシュをENSノードに保存する関数。
ENSノードに対して、Base58→Hexに変換されたIPFSのハッシュを登録します。
この関数は、対象ノードのオーナーによってのみ呼び出すことができます。
引数
-
node
- ENSノード(ドメイン名)を示す32バイトの識別子(
bytes32
形式)。
- ENSノード(ドメイン名)を示す32バイトの識別子(
-
hash
- Hex形式に変換されたIPFSハッシュ(
bytes
型)。
- Hex形式に変換されたIPFSハッシュ(
multihash
function multihash(bytes32 node) public view returns (bytes);
IPFSハッシュをENSノードから取得する関数。
指定されたENSノードに紐付けられたIPFSハッシュ(Hex形式)を取得します。
取得後はそれをBase58形式に再変換することで、対応するIPFS上のリソースアドレスが得られます。
引数
-
node
- ENSノード(ドメイン名)を示す32バイトの識別子(
bytes32
形式)。
- ENSノード(ドメイン名)を示す32バイトの識別子(
戻り値
-
bytes
- 保存されているIPFSハッシュのHex形式データ。
only_owner
modifier only_owner(bytes32 node);
ENSノードのオーナーのみが操作できるようにする修飾子。
この修飾子が付与された関数は、対象のENSノードのオーナーであるアドレスのみが実行可能です。
これにより、勝手に他人のENSレコードを書き換えることを防ぎます。
パラメータ
-
node
- アクセス制御を行う対象のENSノード識別子(
bytes32
形式)。
- アクセス制御を行う対象のENSノード識別子(
テストケース
IPFSのBase58形式とEthereumが扱うHex形式との相互変換を行うために、multihashes
というライブラリを使用します。
このライブラリは、IPFSハッシュのエンコード/デコード処理に最適化されています。
Base58 → Hexへの変換
IPFSのBase58形式のハッシュを、ENSコントラクトで保存できるHex形式に変換します。
import multihash from 'multihashes'
export const toHex = function(ipfsHash) {
let buf = multihash.fromB58String(ipfsHash);
return '0x' + multihash.toHexString(buf);
}
この関数では以下の手順で処理を行います。
-
fromB58String
を使って、Base58文字列からバイナリバッファに変換。 - そのバッファを
toHexString
でHex文字列に変換。 -
0x
プレフィックスを付与して返却。
Hex → Base58への変換
ENSコントラクトから取得したHex形式のIPFSハッシュを、元のBase58形式に戻します。
import multihash from 'multihashes'
export const toBase58 = function(contentHash) {
let hex = contentHash.substring(2)
let buf = multihash.fromHexString(hex);
return multihash.toB58String(buf);
}
この関数では以下の手順で処理を行います。
- 先頭の
0x
を削除。 -
fromHexString
を使ってHex文字列からバイナリバッファに変換。 -
toB58String
を使ってBase58形式に再エンコード。
これらの変換処理により、IPFSとENSの相互運用が可能になります。
参考実装
この仕組みは、ブラウザ拡張機能として実装されています。
ユーザーはこの拡張機能を導入することで、通常のDNSのようにENSドメインをブラウザのアドレスバーに入力するだけで、IPFS上の分散コンテンツにアクセスできます。
これにより、以下のようなユーザー体験が実現されます。
- ENS名をURLとして入力(例:
vitalik.eth
) - 拡張機能が自動的に対応するIPFSハッシュを解決
- 分散型コンテンツを直接ブラウザに表示
この仕組みにより、一般ユーザーでも直感的に利用できる環境が整います。
参考実装リポジトリ
https://github.com/PortalNetwork/portal-network-browser-extension
このリポジトリには、実際に機能する拡張機能のコードが含まれており、IPFS-ENSのマッピングの仕組みが具体的に実装されています。
開発者はこれを参考にして、独自のユースケースにも応用可能です。
引用
Phyrex Tsai phyrex@portal.network, Portal Network Team, "ERC-1062: Formalize IPFS hash into ENS(Ethereum Name Service) resolver [DRAFT]," Ethereum Improvement Proposals, no. 1062, May 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1062.
最後に
今回は「IPFSのハッシュをENSに登録・取得できるようにする仕組みを提案しているERC1062」についてまとめてきました!
いかがだったでしょうか?
質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!
他の媒体でも情報発信しているのでぜひ他も見ていってください!