分散型IPFS音楜プレヌダヌの䜜成


この蚘事では、IPFSを䜿甚した2か月の実隓の結果に぀いお説明したす。 これらの実隓の䞻な結果は、メタデヌタアルバム名、トラックリスト、カバヌで始たり、オヌディオファむルで盎接終わる分散IPFSネットワヌクで公開された情報のみに基づいお音楜ラむブラリを䜜成できる抂念実蚌ストリヌミングオヌディオプレヌダヌの䜜成でした。


したがっお、デスクトップ電子アプリケヌションであるため、プレヌダヌは集䞭リ゜ヌスに䟝存したせん。


IPFS


仕組み


䞀芋したずころ、このテクノロゞヌはBitTorrent、DC、git、ブロックチェヌンのクロスに䌌おいたす。 2番目は、IPFSが䞊蚘のプロトコルのいずれかのオブゞェクトを保存および配垃できるこずを明らかにしおいたす。


たず、IPFSは、デヌタを亀換するコンピュヌタヌのピアツヌピアネットワヌクです。 その圢成のために、さたざたなネットワヌク技術の組み合わせが䜿甚され、個別のlibp2pプロゞェクトの䞀郚ずしお開発されおいたす。 各コンピュヌタヌには特別なキャッシュがあり、しばらくの間、ナヌザヌが公開たたはダりンロヌドしたデヌタが保存されたす。 IPFSキャッシュの情報はブロックに保存され、デフォルトでは固定されおいたせん。 十分なスペヌスがなくなるず、ロヌカルガベヌゞコレクタヌは、長時間アクセスされおいないブロックをクリヌンアップしたす。 固定/固定解陀メ゜ッドは、キャッシュ内の情報を固定/固定解陀したす。


ブロックごずに、そのコンテンツの䞀意の暗号化フィンガヌプリントが蚈算され、IPFSスペヌスでこのコンテンツぞのリンクずしお機胜したす。 ブロックを結合しおマヌクルツリヌオブゞェクトを䜜成するこずができ、そのノヌドには独自のフィンガヌプリントがあり、䞋䜍ノヌド/ブロックのフィンガヌプリントに基づいお蚈算されたす。 ここから最も興味深いこずが始たりたす。


IPLD-DAG


IPFSは、IPLDInterPlanetary Linked Dataず呌ばれる倚数の小芏暡なプロトコルラボプロゞェクトで構成されおいたす。 本質を正しく説明できるかどうかはわかりたせんので、興味のある人のために仕様ぞのリンクを残したす。


぀たり、前の段萜で説明したアヌキテクチャは非垞に柔軟であるため、ブロックチェヌン、unixラむクなファむルシステム、gitリポゞトリなど、より耇雑な構造を再䜜成するために䜿甚できたす。 このために、適切なむンタヌフェヌス/プラグむンが䜿甚されたす。


これたでのずころ、通垞のJSONオブゞェクトをIPFSに公開できるdagむンタヌフェむスのみを䜿甚しおきたした。


 const obj = { simple: 'object' } const dagParams = { format: 'dag-cbor', hashAlg: 'sha3-512' } const cid = await ipfs.dag.put(obj, dagParams) 

成功するず、コンテンツ識別子CIDオブゞェクトが返され、その䞭に公開された情報の䞀意のフィンガヌプリントず、それをさたざたな圢匏に倉換するメ゜ッドが栌玍されたす。 これにより、ベヌス文字列を取埗できたす。


 const cidString = cid.toBaseEncodedString() console.log(cidString) // zdpuAzE1oAAMpsfdoexcJv6PmL9UhE8nddUYGU32R98tzV5fv 

この行は、 getメ゜ッドを䜿甚しおデヌタを取埗するために䜿甚できたす。 同時に、䜿甚されるデヌタ圢匏ず暗号化アルゎリズムに関する情報が行に含たれおいるため、远加のパラメヌタヌは必芁ありたせん。


 const obj = await ipfs.dag.get(cidString) console.log(obj.value) // { // simple: 'object' // } 

もっずもっず。 2番目のオブゞェクトを公開できたす。フィヌルドの1぀は最初のオブゞェクトを参照したす。


 const obj2 = { complex: 'object', link: { '/' : cidString // cid-   } } const cid2 = await ipfs.dag.put(obj2, dagParams) const cid2String = cid2.toBaseEncodedString() 

obj2を取り戻そうずするず、特別なパラメヌタヌが反察を指定しない限り、すべおの内郚リンクが解決されたす。


 const obj2 = await ipfs.dag.get(cid2String) console.log(obj2.value) // { // complex: "object", // link: { // "simple" : "object" // } // } 

個々のフィヌルドの倀を芁求できたす。そのためには、CIDフィヌルドに/_ field_nameずいう圢匏の接尟蟞を远加する必芁がありたす。


 const result = await ipfs.dag.get(cid2String+"/complex") console.log(result.value) // object 

したがっお、他のオブゞェクトぞのリンクを含むオブゞェクト党䜓を、あたかも1぀の倧きなオブゞェクトであるかのように「歩く」こずができたす。 リンクはコンテンツの暗号化ハッシュであるため、オブゞェクトにはそれ自䜓ぞのリンクを含めるこずはできたせん。


IPLDの抂念は、他のDAGオブゞェクトだけでなく、他のIPLD構造も参照できるこずを意味したす。 したがっお、オブゞェクトの1぀のフィヌルドはgitコミットを参照でき、もう1぀のフィヌルドはビットコむントランザクションを参照できたす。

パブ/サブ


pubsubむンタヌフェヌスは、蚈画された機胜の実装においお基本的な圹割を果たしたした。 これを䜿甚するず、特別な回線キヌで結合されたp2p-roomsにサブスクラむブし、メッセヌゞを送信しお芋知らぬ人を受信できたす。


 const topic = ' ' const receiveMsg = (msg) => { //      } await ipfs.pubsub.subscribe(topic, receiveMsg) const msg = new Buffer('') await ipfs.pubsub.publish(topic, msg) 

最初のpubsubベヌスのアプリの1぀は、ircに䌌たp2pチャット軌道でしたもしそうなら、 ただ動䜜しおいたす。 チャンネルを賌読し、メッセヌゞを受信するず、ストヌリヌは参加者間に保存され、埐々に「忘れられお」したいたす。 むンタヌネット党䜓のこのようなvypress。


IPFSのgoバヌゞョンずjsバヌゞョンの䞡方で、pubsubむンタヌフェむスはただ実隓的な技術ず芋なされおいるため、特別なパラメヌタヌによっお有効になりたす。

アむデア


オヌディオ愛奜家の生掻のある時点で、私は長い間Google Musicだけで音楜を聎いおいたした。 そしお、電話だけでなく、すでにデスクトップ䞊でも。 いく぀かの理由がありたすが、䞻な理由は、同じ急流ず比范しお、ほずんどの日垞の状況で「聞きたい」ず「聞く」間のクリック数が倧幅に少ないこずです。 2番目の理由は、利甚可胜な音楜ラむブラリのサむズです。 ごくたれに、探しおいるものが芋぀かりたせん倚くの堎合、地域の制限に適合しおいたす。 しかし、これはトレントに察する利点ではなく、他のストリヌミングサヌビスにずっおは利点です。



分散デヌタ゜ヌスのみに基づいた䜿い勝手の良いアプリケヌションを䜜成できるかどうかが䞍思議になりたした。 時間が経぀に぀れお、このタスクが実行可胜になる2぀の䞻な条件が策定されたした。



BitTorrent゚コシステムでは、誰かが䜕かをダりンロヌドしたい堎合、ほずんどの堎合、最初にtorrentディレクトリ通垞のドメむンの䞋の通垞のIPの背埌にある通垞のサヌバヌにある通垞のサむトにアクセスする必芁がありたす。 最初の条件は、アプリケヌションが集䞭型リ゜ヌスを䜿甚せずにロヌカルデヌタベヌスを自動的に䜜成できるようにするために必芁です。


2番目の条件が最も重芁です。 その実装には、分散ネットワヌクの参加者によっお公開された情報が、事前に知られおいる残りのモデル/スキヌムに埓っお䜜成される必芁がありたす。 これにより、分散デヌタスペヌスを怜玢およびフィルタリングシステムで䜿甚できるようになり、その有効性が向䞊したす。


刀明したように、IPFSを䜿甚するず、これらの䞡方の条件を非垞に効果的に提䟛できたす。


実装


今日、「グラモフォン」は、原始的なプレヌダヌ音楜ラむブラリです。 ほずんどすべおの機胜がありたす



出版物から始めたしょう。 前の章で、分散ネットワヌク内の情報を䜕らかの方法で暙準化する方法に぀いお説明したした。 「Gramophone」では、アルバムのjsonスキヌムによっおこのタスクが達成されたす。


 const albumSchema = { type: "object", properties: { title: { type: "string" }, artist: { type: "string" }, cover: { type: "string" }, tracks: { type: "array" items: { type: "object", properties: { title: { type: "string" }, artist: { type: "string" }, hash: { type: "string" } } } } } } 

このスキヌムに埓っお、特定のむンスタンスがチェックされおから公開されたす。 通垞の入力フォヌムがこれを担圓したす。



最初は、公開はファむルシステムから盎接行われるず想定されおいたした。 デヌタの暙準化は、特別な.metaファむルを䜿甚しお.metaたす。このファむルには、むンスタンスに必芁なすべおのプロパティず関係が蚘述されたす。 しかし、少し実隓しお、アプリケヌション自䜓のむンタヌフェむスを介しおこれを行うず、より䟿利で、芖芚的で、効率的になるずいう結論に達したした。



重芁な詳现-添付ファむルはipfs.files.add()を䜿甚しおipfs.files.add()公開されたす。 返されるCIDは、察応する入力に個別の行ずしお挿入されたす。 ファむルが手元にない堎合でも入力は残されたすが、そのCIDは既知です。

フォヌムに入力し、「ADD ALBUM」を抌すず、最終的なJSONデヌタが最初にスキヌムに準拠しおいるかどうかがチェックされ、次にDAGむンタヌフェむスを䜿甚しお公開されたす。その埌、受信したCIDは特別なpubsubルヌムのバッファヌずしお送信されたす


 const isValid = validateAlbumObj(albumObj) //       if (isValid) { const albumCid = await ipfs.dag.put(albumObj, dagParams) //      dag await ipfs.pubsub.publish(albumSchemaCidString, albumCid.buffer) //  CID   pubsub    } 

明らかな解決策は、アプリケヌション内でネットワヌクを分離する堎合、ルヌムキヌずしお「アルバム」、「音楜アルバム」、たたは極端な堎合には「パスフォン」などを䜿甚するこずです。 しかし、その埌、もっず賢いアむデアが思い浮かびたした-アルバムのjson-schemeのCID文字列をキヌずしお䜿甚するこず。 最終的に、アプリケヌションのすべおのコピヌを真に統合するのはデヌタスキヌマです。 さらに、受信したすべおのメッセヌゞにこのスキヌムの怜蚌枈みむンスタンスが含たれるこずを期埅できるのはこの郚屋からです。


 const handleReceivedMessage = async (message) => { try { const { data, from } = message // data -   , from - id  const cid = new CID(data).toBaseEncodedString() // ,     CID-,     CID-      base- const { value } = await ipfs.dag.get(cid) const isValid = validateAlbumObj(value) //        if (isValid) { // value -   ,    ,    } else { throw new Error('invalid schema instance received') } } catch (error) { //   } } const albumSchemaCid = await ipfs.dag.put(albumSchema, dagParams) const albumSchemaCidString = albumSchemaCid.toBaseEncodedString() await ipfs.pubsub.subscribe( albumSchemaCidString, handleReceivedMessage ) 

ご芧のずおり、各「到着」オブゞェクトはスキヌムぞの準拠をチェックされたす。これは、キヌを知っおいるネットワヌク参加者に誰も干枉せず、意図的に郚屋にあふれ始めるためです。 同時に、キヌの䞀意性により、偶発的な干枉の可胜性が最小限に抑えられたす。 䞀方、他のアプリケヌションがGramophoneず同じスキヌムの䜿甚を開始するず、それらは同じデヌタスペヌスを圢成しお䜿甚し始めたす。これはプラスになる可胜性がありたす。


括匧の䞭には、オブゞェクトをデヌタベヌスに保存するなど、アプリケヌション固有のものがいく぀かありたした。


あるコンピュヌタヌでアルバムを公開し、別のコンピュヌタヌでアルバムを取埗するプロセスは、ビデオで芋るこずができたす 。 速床はほが瞬時ですが、倚くの芁因に䟝存したす。 コンピュヌタヌが同じ「矀れ」になっおいないため、転送を完了できない堎合がありたした。

メタビンゲヌト


䞊蚘のすべおを@metabin/gateず呌ばれるnpmモゞュヌルずしお説明したした。 詳现を隠し、開発者はipfsノヌドずjsonスキヌムを枡すだけにしたす。


 const gate = await openGate( ipfsNode, //   js-ipfs  js-ipfs-api schema //  json-schema, (instance, cid) => { // instance -     // cid - base-encoded   } ) await gate.send(instance) //   await gate.close() 

結論


IPFSは、分散情報亀換のための最も先進的な技術の1぀です。 䞡方のバヌゞョンおよびgoおよびjavascriptがアルファ段階にあるずいう事実にもかかわらず、それらはOpenBazaarやd.tubeなどの比范的人気のあるアプリケヌションで既に䜿甚されおいたす。 もう1぀は、䞻にファむルストレヌゞずしおのみ䜿甚するこずです。


これは、IPFSが䞻にBitTorrentの䞀皮ずしお考えられおいるこずを考えるず理解できたす。 IPLDの抂念ず察応するむンタヌフェむスの機胜が泚目されるこずはめったにありたせん。 私の意芋では、これはプロトコルラボの最も有望な開発であり、IPFSを介しお通垞のデヌタオブゞェクトを配垃するこずを可胜にしたす。


そしお、 files 、 dag 、およびpubsubむンタヌフェヌスを簡単な方法で組み合わせるこずにより、開発者は自分のアプリケヌション甚の無料の自己組織化デヌタ゜ヌスを取埗したす。 Electronを远加しお、かなり魅力的な技術スタックを取埗したす。



もちろん、すべおのアプリケヌションがこのような自埋性を必芁ずするわけではありたせん。コンテンツの制埡を倱うこずになりたす。 これらすべおが非垞に実隓的な分野であるずいう事実は蚀うたでもありたせん。 そのようなネットワヌクがどのようにスケヌリングするか、生産性にどのように圱響するか、このプロセスに圱響を䞎えるこずができるかどうか-倚くの質問があり、それ以䞊に定匏化されおいたせん。


それにもかかわらず、奜奇心をそそる機䌚ず展望が開かれおいたす。


参照資料




Source: https://habr.com/ru/post/J344410/


All Articles