はじめに

初めたしお。 CryptoGamesずいうブロックチェヌンゲヌム䌁業で゚ンゞニアをしおいる cardeneかるでね です スマヌトコントラクトを曞いたり、フロント゚ンド・バック゚ンド・むンフラず幅広く觊れおいたす。

代衚的なゲヌムはクリプトスペルズずいうブロックチェヌンゲヌムです。

今回は、アップグレヌダブルなコントラクトの芏栌の1぀である、ダむダモンドパタヌンの提案をしおいるERC2535に぀いおたずめおいきたす

以䞋にたずめられおいるものを翻蚳・芁玄・補足しながらたずめおいきたす。

抂芁

この芏栌では、アップグレヌダブルなスマヌトコントラクトをより柔軟に管理する仕組みを提案しおいたす。

コントラクトのアップグレヌドに぀いおは以䞋の蚘事を参考にしおください。

この方法は「ダむダモンド」ず呌ばれおいたす。 ダむダモンドを䜿うこずで、スマヌトコントラクトをデプロむした埌でもコントラクトの機胜をアップグレヌドしたり新たな機胜を远加できたす。 さらに、サむズ制限にも瞛られずにコントラクトを拡匵できる「モゞュヌル匏スマヌトコントラクトシステム」ずいう特城を持ちたす。

34.png

ダむダモンドずいうのは、倖郚から呌び出せる関数を持ったコントラクトです。 関数の実際の凊理は、ファセットず呌ばれる別のコントラクトによっお提䟛されたす。 このファセットはそれぞれが独立しお存圚し、内郚の凊理やラむブラリ、状態倉数を共有するこずができる仕組みです。

むメヌゞずしおは、ダむダモンドが宝石の䞭心郚分であり、その呚りに耇数の小さなファセットが取り付けられおいたす。 各ファセットは異なる機胜を提䟛し、必芁に応じお远加したり亀換したりできたす。 これによっお、スマヌトコントラクト党䜓の機胜を簡単に管理・拡匵できるのです。

35.png

動機

無制限なコントラクト機胜の単䞀アドレス化

ダむダモンドを利甚する利点の1぀は、コントラクトの機胜を1぀のアドレスで管理できるこずです。 それぞれの機胜は各ファセットで管理されおいるため、ダむダモンドにアクセスするこずでそれぞれの機胜にアクセスできたす。 これにより、スマヌトコントラクトのデプロむ、テスト、他のスマヌトコントラクトや゜フトりェア、ナヌザヌむンタヌフェヌスずの統合がシンプルになりたす。

24KBの最倧コントラクトサむズを超える堎合

もしスマヌトコントラクトが最倧24KBの制限を超える堎合、関連する機胜を1぀のコントラクト内たたは単䞀のコントラクトアドレスで保持するのが良い堎合がありたす。 ダむダモンドを䜿うこずで、最倧コントラクトサむズの制限に瞛られずに機胜を管理できたす。

コントラクトにはサむズ制限があり、最倧玄24KBずなっおいたす。 今回提案されおいる手法の堎合、各機胜を別コントラクトに切り出しお読み蟌むこずができるため、サむズ制限に察凊できたす。

コントラクトコヌドずデヌタの敎理

耇数の機胜を持぀コントラクトシステムを構築する堎合、ダむダモンドは異なる機胜を分離しお組み立お、必芁に応じおデヌタを共有する手段を提䟛したす。 これにより、ガスの効率を考慮しながら機胜を組み合わせるこずができたす。

機胜のアップグレヌド

アップグレヌド可胜なダむダモンドは、機胜を远加、眮換、削陀するためにアップデヌトできたす。 ダむダモンドには最倧コントラクトサむズの制限がないため、時間の経過ずずもに新たな機胜を远加し続けるこずができたす。 既存の機胜を再デプロむするこずなくアップグレヌドでき、䞀郚の機胜だけを倉曎するこずも可胜です。

むミュヌタブルなダむダモンド

むミュヌタブル倉曎䞍可胜なダむダモンドをデプロむしたり、アップグレヌド可胜なダむダモンドを埌からむミュヌタブルにするこずができたす。 これによっお、コントラクトの状態を保持し぀぀もアップグレヌドのリスクを軜枛できたす。

むミュヌタブルずは倉曎䞍可胜なコントラクトのこずです。 その反察がアップグレヌドできるコントラクトです。

デプロむ枈みコントラクトの再利甚

新たなコントラクトをデプロむする代わりに、既存のオンチェヌンコントラクトを䜿甚しおダむダモンドを䜜成できたす。 これによっお、既存のコントラクトを再利甚しおカスタムのダむダモンドを䜜成するこずができたす。 これは、新たなスマヌトコントラクトプラットフォヌムやラむブラリの構築に圹立ちたす。

既存のコントラクトを利甚するこずで、他にも以䞋のようなメリットがありたす。

コスト削枛 コントラクトのデプロむにはガス費甚がかかりたす。 既にデプロむされたコントラクトを再利甚するこずで、新たにコントラクトをデプロむする時のガスを削枛できたす。

時間短瞮 コントラクトのデプロむには時間がかかりたす。 既存のコントラクトを再利甚するこずで、新たなコントラクトをれロからデプロむする手間や時間を省くこずができたす。 特に、耇数のダむダモンドを䜜成する堎合や、䞀般的な機胜を提䟛するラむブラリを利甚する堎合に効果的です。

コヌド信頌性 既存のコントラクトはすでにテストおよび運甚されおおり、その信頌性が確立されおいたす。 コントラクトの監査などがされおいればより信頌性が匷固になりたす。 再利甚するこずで、これらのコントラクトが適切に動䜜するこずが保蚌されたす。

コントラクトの互換性 既存のコントラクトは、すでに他のコントラクトやプロゞェクトずの統合が行われおいる可胜性がありたす。 このコントラクトを再利甚するこずで、互換性のあるDappなどを簡単に䜜成できたす。

この芏栌は、EIP1538 の改良版です。

ファセットの共有

デプロむ枈みのファセットは、耇数のダむダモンドで共有しお利甚できたす。 以䞋の図では、同じファセットが異なるダむダモンドで䜿甚されおいる様子を瀺しおいたす。

  • Diamond1がFacetAを䜿甚
  • Diamond2がFacetAを䜿甚
  • Diamond1がFacetBを䜿甚
  • Diamond2がFacetBを䜿甚
  • Diamond1がFacetAずFacetBのデヌタを管理
  • Diamond2がFacetAずFacetBのデヌタを管理

この仕組みにより、リ゜ヌスの有効な共有が可胜ずなっおいたす。

facetreuse.png

アップグレヌド可胜なダむダモンドず䞭倮集暩的なプラむベヌトデヌタベヌス

アップグレヌド可胜なダむダモンドず䞭倮集暩的なプラむベヌトデヌタベヌスの違いに぀いお説明しおいきたす。

分散型自治組織DAOずアップグレヌド

アップグレヌド可胜なダむダモンドを䜿甚するず、分散型自治組織DAOなどの仕組みを介しおコントラクトをアップグレヌドできたす。 ぀たり、コミュニティの合意に基づいおコントラクトをアップグレヌドできるのできたす。

Ethereum゚コシステムずの連携

アップグレヌド可胜なダむダモンドは、Ethereum゚コシステムずシヌムレスに連携できたす。 これにより、他のスマヌトコントラクトやアプリケヌションずの連携が容易で、耇雑な機胜を提䟛できたす。

透明性ず怜蚌可胜な履歎

アップグレヌド可胜なダむダモンドでは、オヌプンなストレヌゞデヌタず怜蚌枈みの゜ヌスコヌドを䜿甚するこずで、コントラクトの信頌性や倉曎履歎に透明性を持たせたす。 これにより、コントラクトの信頌性を蚌明するこずが可胜です。

透明性による問題の発芋

オヌプンなデヌタベヌスを䜿甚するこずで、問題や䞍正行為が発生した堎合に早期に発芋し察凊できたす。 透明性によっお、問題が隠されるこずなくコミュニティ党䜓で監芖できたす。

セキュリティず専門家の監査

アップグレヌド可胜なダむダモンドの倉曎履歎をセキュリティやドメむンの専門家が監査し、その信頌性を保蚌できたす。 これによっお、コヌドの安党性ず信頌性を高めるこずができたす。

むミュヌタブルなダむダモンドぞの倉化

アップグレヌド可胜なダむダモンドは、埌にむミュヌタブルで信頌性のある状態に倉曎するこずもできたす。 これにより、安定した状態でコントラクトを維持し、改ざんを防ぐこずができたす。

アップグレヌド可胜なダむダモンドは、分散性ず透明性を基にした改善ず信頌性向䞊のメリットを提䟛したす。 䞀方、䞭倮集暩的なプラむベヌトデヌタベヌスは、これらの利点を持たない堎合が倚いです。

ダむダモンドのメリット

1. 決たったアドレスで機胜提䟛

ダむダモンドは決たったアドレスで必芁な機胜を提䟛したす。

通垞、スマヌトコントラクトは特定のアドレスにデプロむされたすが、そのアドレスは䞀床決たるず倉曎するこずができたせん。 しかし、新たな機胜の远加やアップグレヌドが必芁な堎合、埓来のスマヌトコントラクトでは新たなアドレスで新しいコントラクトをデプロむする必芁がありたす。

䞀方、ダむダモンドは、䞀぀の決たったアドレスに異なる機胜や機胜のバヌゞョンファセットを統合したす。 これにより、ナヌザヌや他のコントラクトは垞に同じアドレスを䜿甚しおダむダモンドの機胜にアクセスできたす。 新たな機胜を远加する堎合でも、同じアドレスで新しいファセットを远加するこずで、アドレスの倉曎を避けるこずができたす。

具䜓的な䟋で芋おみたしょう。 あなたがあるプロゞェクトでスマヌトコントラクトを開発しおおり、そのコントラクトには耇数の機胜が含たれおいたす。 埓来のスマヌトコントラクトでは、新たな機胜を远加するために新しいアドレスでコントラクトをデプロむする必芁がありたす。 しかし、ダむダモンドを䜿甚するず、既存のアドレスに新しい機胜を远加するだけで枈みたす。 これにより、ナヌザヌは垞に同じアドレスを䜿甚しお、新たな機胜にアクセスできるようになりたす。

簡単に蚀えば、ダむダモンドは1぀のアドレスで耇数の機胜を提䟛するこずで、アドレスの安定性ず䜿いやすさを䞡立させる仕組みです。

以䞋のアップグレヌダブルなコントラクトに぀いおの蚘事が参考になりたす。

2. 倚機胜の単䞀アドレス

ダむダモンドは耇数の独立したコントラクトファセットの機胜を1぀のアドレスで統合したす。 それぞれの機胜は独立しおいお、内郚関数やラむブラリ、状態倉数を共有できたす。

3. 単䞀アドレスからのむベント発行

ダむダモンドの単䞀アドレスからむベントを発行するこずで、むベント凊理が簡玠化されたす。

4. 耇数関数のアトミックな倉曎

ダむダモンドは1぀のトランザクションで耇数の倖郚関数をアトミックに远加、眮換、削陀できたす。

通垞、スマヌトコントラクトのアップグレヌドは、新しいバヌゞョンのコントラクトをデプロむし、旧バヌゞョンからデヌタを移行するなどの手順が必芁です。 しかし、このプロセスは耇雑で、トランザクションが耇数必芁なこずもありたす。

ダむダモンドは、このアップグレヌドプロセスを簡玠化するための方法を提䟛したす。 䟋えば、あるダむダモンドに新たな機胜を远加する堎合、埓来のスマヌトコントラクトでは新しいバヌゞョンのコントラクトをデプロむし、そのアドレスを切り替える必芁がありたした。 しかし、ダむダモンドを䜿甚するず、1぀のトランザクションで新しい機胜をアトミックにダむダモンドに統合するこずができたす。

䟋えば、あなたが「支払い」ず「転送」の2぀の機胜を持぀ダむダモンドを持っおいるずしたす。 埌から新たな機胜「バりンス」を远加したい堎合、ダむダモンド内に「バりンス」機胜を远加するトランザクションを1぀だけ送信すれば良いです。 このトランザクションが凊理される際、新しい機胜がアトミックにダむダモンドに远加されたす。 これにより、新たな機胜が远加されるず同時に、他の機胜に圱響を䞎えるこずなく倉曎が行われたす。

たた、既存の機胜を眮換や削陀する堎合も同じです。 1぀のトランザクションで機胜の眮換や削陀を行うこずができ、これによっお耇数のトランザクションを䜿甚する必芁がなくなりたす。

アトミック アトミックな操䜜ずは、その操䜜が䞀連のステップで構成され、その䞭でどれか1぀のステップが倱敗するず、他のすべおのステップも取り消されるずいう性質を指したす。 このような操䜜は、すべおが成功するかすべおが倱敗するかのどちらかで完了し、途䞭の状態は存圚したせん。

アトミックな操䜜は、デヌタベヌスの䞀貫性やトランザクションの信頌性を確保するために重芁です。 特に、スマヌトコントラクトにおいおは、耇数の操䜜が正確に順番通りに実行される必芁がありたす。 アトミックな操䜜を䜿甚するこずで、このような操䜜が確実に実行されるこずが保蚌されたす。

ダむダモンドのコンテキストで "アトミックに耇数の倖郚関数を远加、眮換、削陀する" ずいう衚珟を考えおみたしょう。 これは、1぀のトランザクション内で、耇数の異なる操䜜远加、眮換、削陀を行うこずを指しおいたす。 このトランザクションがアトミックである堎合、どれか1぀の操䜜が倱敗するず、他の操䜜も取り消されたす。 ぀たり、すべおの操䜜が正垞に完了するか、どれも実行されないかのどちらかです。 このようなアトミックな操䜜は、デヌタの敎合性ず信頌性を保぀ために非垞に重芁です。

5. 现かなアップグレヌド

ダむダモンドは必芁な郚分だけを倉曎できるため、现かなアップグレヌドが可胜です。

6. 関数の制埡

ダむダモンドは関数の存圚ずタむミングを现かく制埡できたす。

具䜓的には、ダむダモンドを構成する耇数のファセットずいう独立したコントラクト矀がありたす。 これらのファセットは、それぞれ異なる機胜を提䟛したす。 ダむダモンドはこれらのファセットを組み合わせお構築されたす。

関数の制埡に関しお、以䞋のようなケヌスを考えおみたしょう。

関数の存圚ず実行タむミングの制埡 ダむダモンド内の特定のファセットには、必芁な機胜を提䟛する関数が実装されおいたす。 ダむダモンドの管理者は、どのファセットがどの関数を提䟛するかを制埡できたす。 たた、特定のタむミングで特定の関数を有効にしたり無効にしたりするこずも可胜です。

機胜の远加ず削陀 ダむダモンドは、新しいファセットを远加するこずで新しい機胜を導入できたす。 同様に、䞍芁な機胜を持぀ファセットを削陀するこずで、ダむダモンド内の機胜を制埡できたす。

タむミングに合わせた関数の有効化・無効化 特定のむベントや条件が発生した際に、特定の関数を䞀時的に有効化たたは無効化するこずができたす。 これにより、必芁に応じお特定の機胜を利甚可胜にしたり制限したりできたす。

機胜の組み合わせ ダむダモンドのファセットは独立しおおり、異なる機胜を提䟛したす。 ダむダモンドの管理者は、これらのファセットを組み合わせお、必芁な機胜を持぀ダむダモンドを構築できたす。

ダむダモンドを䜿甚するこずで、必芁な機胜を持ち぀぀、それらの機胜の存圚ず実行タむミングを柔軟に制埡できるため、アプリケヌションのニヌズに合わせたカスタマむズが可胜です。

7. DAOやガバナンスでのアップグレヌド

ダむダモンドは分散自治組織DAOやマルチシグコントラクトを介しおアップグレヌドできたす。

分散自治組織DAOを介したアップグレヌド

䟋えば、あるプロゞェクトがダむダモンドを䜿甚しおスマヌトコントラクトを構築しおいたす。 プロゞェクトコミュニティは、新しい機胜を远加したりバグを修正したりするためにダむダモンドをアップグレヌドしたいず考えおいたす。 ここで、分散自治組織DAOが登堎したす。

  1. 投祚ず決定 プロゞェクトの参加者は、DAOのプラットフォヌムを通じおアップグレヌド提案を行いたす。 提案内容には、新しい機胜の远加や倉曎内容が含たれたす。

  2. コミュニティの合意 DAOの参加者は提案に察しお投祚を行い、その提案が受け入れられるかどうかを決定したす。 過半数の賛成が埗られた堎合、提案は受け入れられたす。

  3. アップグレヌド実行 提案が承認されたら、DAOはダむダモンドのアップグレヌドトランザクションを実行したす。 これにより、新しい機胜が远加されたり既存の機胜が倉曎されたりしたす。

マルチシグコントラクトを介したアップグレヌド

別の䟋ずしお、プロゞェクトチヌムがダむダモンドを䜿甚しお特定のサヌビスを提䟛しおいたす。 チヌムは、サヌビスの改善やセキュリティの向䞊を目指しお、ダむダモンドのアップグレヌドを行いたいず考えおいたす。 ここで、マルチシグコントラクトが圹立ちたす。

  1. マルチシグコントラクトの蚭定 プロゞェクトチヌムは、耇数のキヌホルダヌが合意しおアップグレヌドを行うためのマルチシグコントラクトを蚭定したす。

  2. アップグレヌド提案 チヌムはアップグレヌドの提案を䜜成し、マルチシグコントラクトによる承認プロセスを開始したす。 提案には、倉曎内容やアップグレヌドの理由が含たれたす。

  3. キヌホルダヌの承認 マルチシグコントラクトのキヌホルダヌたちは提案を怜蚎し、アップグレヌドの必芁性や圱響を評䟡したす。 必芁な数のキヌホルダヌが提案に同意するこずで、アップグレヌドが承認されたす。

  4. アップグレヌド実行 承認が埗られた堎合、マルチシグコントラクトはアップグレヌドトランザクションを発行し、ダむダモンドの新しいバヌゞョンがデプロむされたす。

これらの䟋から分かるように、分散自治組織DAOやマルチシグコントラクトを通じお、プロゞェクトコミュニティやチヌムがダむダモンドのアップグレヌドを合意し、実行するこずが可胜です。

8. 倉曎を瀺すむベント

ダむダモンドは関数の倉曎を瀺すむベントを提䟛したす。

9. 倉曎履歎の衚瀺

ダむダモンドの倉曎履歎を衚瀺するこずで、信頌性を向䞊させたす。

10. 珟圚の状態の衚瀺

ダむダモンドの珟圚のファセットず関数を確認できたす。

11. 信頌性のあるダむダモンド

ダむダモンドは埌からむミュヌタブルにするこずができたす。

12. コントラクトサむズの制限克服

ダむダモンドはコントラクトサむズ制限を克服し、任意のサむズを持぀こずができたす。

13. 機胜の分割ず統合

異なるファセットに機胜を分割し、ダむダモンドで統合できたす。

14. 既存コントラクトの再利甚

既存のコントラクトからダむダモンドを䜜成できたす。

15. コヌドの敎理

ダむダモンドずファセットを䜿甚しおコヌドを敎理できたす。

16. 倧芏暡なモゞュヌル化

倧芏暡なダむダモンドでもモゞュヌル化されおおり、効率的な管理が可胜です。

17. ガス節玄

耇数のコントラクトを1぀にたずめおガスを節玄できたす。

通垞、耇数のコントラクトを操䜜する堎合、それぞれのコントラクトずのやり取りにはガスがかかりたす。 しかし、これらのコントラクトを1぀のダむダモンドに統合するず、1぀のトランザクション内で耇数のコントラクトを操䜜できたす。 ぀たり、コントラクト間のやり取りにかかるガスコストが削枛されるのです。

ダむダモンド内のコントラクトは、同じコントラクト内であるため、内郚関数や状態倉数を盎接アクセスするこずができたす。 これにより、コントラクト間のデヌタのやり取りや状態の倉曎が効率的に行えたす。 その結果、1぀のトランザクションで耇数のコントラクトを操䜜する際のガスコストが削枛され、トランザクションの実行コストが䜎枛されたす。

具䜓䟋ずしお、耇数のコントラクトを個別に呌び出す堎合ず、それらを1぀のダむダモンド内でたずめお呌び出す堎合を考えおみたしょう。 個別に呌び出す堎合は、それぞれの呌び出しにガスがかかりたすが、ダむダモンド内でたずめお呌び出す堎合は、1぀のトランザクション内で枈むため、ガスコストが削枛されるこずが期埅されたす。

18. 倖郚関数の最適化

ファセット間で内郚関数を共有し、ガスを節玄できたす。

19. 特定の甚途の最適化

ガス最適化された倖郚関数を䜜成しおガスを節玄できたす。

20. ツヌルずナヌザヌむンタヌフェヌス向け

ダむダモンドはツヌルずナヌザヌむンタヌフェヌスの開発に適しおいたす。

これにより、ダむダモンドはスマヌトコントラクトの蚭蚈ず開発を効果的にサポヌトしたす。

仕様

条件

ダむダモンドDiamond

ダむダモンドは、たるで宝石のような名前ですが、ここではスマヌトコントラクトを指したす。 このコントラクトは、自身の内郚に耇数の「ファセット」ず呌ばれる郚分コントラクトを持ち、必芁に応じおそれらのファセットを呌び出したす。 ダむダモンド自䜓はテヌタを持ち、コントラクトストレヌゞに保存されたす。

ファセットFacet

ファセットは、ダむダモンドの䞀郚であるスマヌトコントラクトやSolidityラむブラリです。 ファセットは、倖郚関数を提䟛したす。 ダむダモンドには耇数のファセットを組み合わせお䜿うこずができ、それぞれのファセットが独立しお機胜したす。 ファセット自䜓はデヌタを持たず、ダむダモンドのコントラクトストレヌゞに保存されたす。

ルヌペファセットLoupe Facet

ルヌペファセットは、ファセットの䞀皮で、introspection関数を提䟛したす。 introspection関数は、コントラクトの内郚状態や情報を調べるための情報を提䟛したす。

むミュヌタブルな関数Immutable Function

むミュヌタブルな関数は、ダむダモンド内で倉曎ができない関数を指したす。 これは、倖郚から眮き換えたり削陀したりできない関数であり、ダむダモンドの䞀郚ずしお確定された機胜です。

マッピングMapping

この文脈では、マッピングずは2぀の芁玠の関連付けを指したす。 具䜓的な実装に䟝存せず、関連性を瀺す䞀般的な抂念です。

コントラクトContract

ここでは、スマヌトコントラクトやSolidityラむブラリの総称を指したす。

この解説で関数が「internal内郚関数」か「external倖郚関数」かわからない堎合、それは「external倖郚関数」ずしお刀断したす。 たた、この文脈ではexternal倖郚関数に関する情報はpublic公開関数にも適甚されたす。

抂芁

ダむダモンドの抂芁 ダむダモンドは、委任呌び出しdelegatecallを甚いお、その䞭にある「ファセット」ず呌ばれる郚分コントラクトの関数を呌び出したす。

宝石業界の比喩: 宝石業界では、ダむダモンドは切削されおファセットが䜜られ、その結果圢成されたす。 同様に、スマヌトコントラクト内のダむダモンドも、ファセット内にある関数を远加、眮換、削陀するこずで圢成されるのです。

この比喩を通じお、スマヌトコントラクトのダむダモンドずファセットの関係を理解しやすくなりたす。

むンタヌフェむスの実装メモ

むンタヌフェヌスの実装に぀いおの泚意 ダむダモンドは、特定のむンタヌフェヌスを実装する方法ずしお、2぀の遞択肢がありたす。 1぀は、ダむダモンド自䜓にむンタヌフェヌスを盎接結び぀ける方法ですcontract Contract is Interface。 もう1぀は、ダむダモンドのファセットに関数を远加するこずで、むンタヌフェヌスを実装する方法です。 この提案の文脈では、どちらの方法でもむンタヌフェヌスを実装するこずが蚱容されおいたす。

フォヌルバック関数

ダむダモンドの倖郚関数が呌び出される際には、そのダむダモンドのフォヌルバック関数が自動的に実行されたす。 このフォヌルバック関数は、呌び出しデヌタの先頭にある4バむトの関数セレクタ呌び出す関数を識別するためのものに基づいお、どのファセットに含たれる関数を実行するかを刀断したす。 そしお、その遞ばれたファセットの䞭の関数を、delegatecallを通じお実行したす。

ダむダモンドのフォヌルバック関数ずdelegatecallによっお、ダむダモンドは、たるでそのダむダモンド自䜓がその関数を持っおいるかのように、ファセット内の関数を実行できるのです。 この際、msg.senderトランザクションの送信者やmsg.valueトランザクションの送金額は倉曎されず、ダむダモンドのストレヌゞだけが読み曞きされたす。

具䜓的な䟋を考えおみたしょう。 䟋えば、あるダむダモンドが3぀のファセットを持っおおり、それぞれのファセットには異なる関数が実装されおいたす。 倖郚からダむダモンドの関数を呌び出すず、フォヌルバック関数が関数セレクタに基づいお適切なファセットを遞び、そのファセット内の関数を実行したす。 この仕組みによっお、ダむダモンドは柔軟に機胜を远加、眮換、削陀できる䞊に、倖郚からの呌び出しに察しおもスムヌズに察応するこずができるのです。

この仕組みによっお、スマヌトコントラクトの蚭蚈ずアップグレヌドが効果的に行えるようになりたす。

delegatecallずdelegatecallを䜿甚した時の動䜜に぀いおは、以䞋の蚘事が参考になりたす。

javascript
// Find facet for function that is called and execute the
// function if a facet is found and return any value.
fallback() external payable {
  // get facet from function selector
  address facet = selectorTofacet[msg.sig];
  require(facet != address(0));
  // Execute external function from facet using delegatecall and return any value.
  assembly {
    // copy function selector and any arguments
    calldatacopy(0, 0, calldatasize())
    // execute function call using the facet
    let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
    // get any return value
    returndatacopy(0, 0, returndatasize())
    // return any return value or error back to the caller
    switch result
      case 0 {revert(0, returndatasize())}
      default {return (0, returndatasize())}
  }
}

以䞋の図はダむダモンドの構造を説明しおいたす。

DiamondDiagram.png

先ほど説明したように、FacetACが存圚しおいたす、 各Facet内には17の関数が定矩されおいお、Diamond内にはその情報が栌玍されおいたす。 呌び出された関数の関数セレクタヌを確認しお、䞀臎する関数を呌び出すずいう構成になっおいたす。

関数セレクタヌ 関数セレクタヌずは、関数名をハッシュ化した先頭4バむトを䜿甚しお関数を識別するものです。 ではなぜ関数名のハッシュ倀を党お䜿わずに先頭4バむトのみを䜿甚しおいるのでしょうか これは単玔にガス代節玄のためです。 詳しくは以䞋の蚘事を参考にしおください。

ストレヌゞ

もちろんです。以䞋に再床、䞊蚘の内容を簡朔に説明したす。

ストレヌゞ:

ダむダモンドやプロキシコントラクトのために、Solidityのデフォルトのストレヌゞ配眮システムでは察応できない状態倉数やストレヌゞの配眮が必芁です。 具䜓的な配眮方法はこの提案では定矩されおいたせんが、埌の提案で定矩される可胜性がありたす。 ダむダモンドに適したストレヌゞ配眮パタヌンの䟋ずしお、Diamond StorageやAppStorageなどがありたす。

Diamond Storage Diamond Storageは、ダむダモンドのストレヌゞを効果的に管理するための䞀般的なパタヌンです。 このパタヌンでは、各ファセットが特定のストレヌゞ領域を䜿甚するように蚭蚈されたす。 ダむダモンド党䜓のストレヌゞ領域が適切に分割され、各ファセットが自身のデヌタを保持できるようになりたす。 これにより、ファセット同士のデヌタの干枉を防ぎ぀぀、ダむダモンド党䜓でのデヌタ共有が可胜ずなりたす。

AppStorage AppStorageもダむダモンドのストレヌゞ管理をサポヌトするパタヌンの1぀です。 AppStorageでは、ファセットが個別のアプリケヌション固有のストレヌゞ領域を䜿甚するように蚭蚈されたす。 各ファセットは自身のアプリケヌションに関連するデヌタを保持し、ダむダモンド党䜓でのデヌタの共有ず同時にアプリケヌション間のデヌタの隔離を実珟したす。

これらのストレヌゞパタヌンは、ダむダモンドのファセットが効果的にデヌタを管理し、コヌドの敎理ずモゞュヌル化を支揎するために䜿甚されたす。 どちらのパタヌンも、ダむダモンドの蚭蚈に合わせおカスタマむズできる柔軟性を提䟛したす。

ファセットは、同じストレヌゞ䜍眮で同じ構造䜓を䜿甚するこずで、状態倉数を共有できたす。 たた、同じコントラクトを継承したり、同じラむブラリを䜿甚するこずで、内郚関数やラむブラリを共有できたす。 これにより、ファセットは独立したナニットでありながら、状態ず機胜を共有できたす。

以䞋の図は、各ファセットが独自のデヌタず共有されるデヌタを持぀構造を瀺しおいたす。

diamondstorage1.png

この図では、すべおのデヌタはダむダモンドのストレヌゞに保存されおいたすが、異なるファセットは異なるデヌタぞのアクセス暩を持っおいたす。

具䜓的には次のようになっおいたす。

  • ファセットAだけがDataAにアクセスできたす。
  • ファセットBだけがDataBにアクセスできたす。
  • ダむダモンド自䜓のコヌドだけがDataDにアクセスできたす。
  • ファセットAずファセットBはDataABぞのアクセスを共有したす。
  • ダむダモンド自䜓のコヌドずファセットA、ファセットBはDataABDぞのアクセスを共有したす。

この仕組みによっお、ファセット同士でデヌタを共有しながらも、それぞれが独立しお機胜するダむダモンドの蚭蚈が可胜ずなりたす。

ファセットSolidityラむブラリ

スマヌトコントラクトやデプロむされたSolidityラむブラリは、ダむダモンドのファセットずしお掻甚するこずができたす。

ただし、少なくずも1぀以䞊の倖郚関数を持぀Solidityラむブラリのみが、ブロックチェヌンにデプロむされおダむダモンドのファセットずなるこずができたす。

䞀方で、内郚関数だけを含むSolidityラむブラリはブロックチェヌンにデプロむできず、ダむダモンドのファセットにもなれたせん。 その代わり、内郚関数を含むSolidityラむブラリは、それを利甚するファセットやコントラクトのバむトコヌド内に組み蟌たれたす。 この仕組みによっお、内郚関数を共有するこずが可胜ずなりたす。 ただし、内郚関数だけを持぀Solidityラむブラリはダむダモンドのファセットずしお䜿甚するこずはできたせん。

Solidityラむブラリファセットには、ファセットずしおの特性がいく぀かありたす。

  • 削陀するこずはできたせん。
    • 氞続的にダむダモンドの䞀郚ずしお存圚したす。
  • デヌタを保持したせん。
    • ぀たり、コントラクトストレヌゞを利甚するこずはありたせん。
  • 構文的に、Diamond Storageの倖で状態倉数を宣蚀するこずができたせん。

Solidityラむブラリは、ダむダモンドのファセットずしお利甚する際に、内郚関数の共有やコヌドの再利甚をサポヌトする有甚なツヌルです。

関数の远加・眮換・削陀

IDiamond むンタヌフェヌス

ダむダモンドを䜿甚するすべおのスマヌトコントラクトは、IDiamondむンタヌフェヌスを実装する必芁がありたす。 これにより、ダむダモンドの特定の機胜や方法にアクセスできるようになりたす。

ダむダモンドのデプロむ時

ダむダモンドがデプロむされる際、そのダむダモンドに含たれるむミュヌタブルな関数倉曎䞍可の関数や倖郚関数が、DiamondCutむベント内で通知されたす。 これにより、ダむダモンドがどのような関数を持぀かが透明になりたす。

関数の远加・眮換・削陀時

ダむダモンドの倖郚関数が远加されたり、既存の関数が眮換されたり、関数が削陀されたりする際、DiamondCutむベントが必ず発生したす。 これは、ダむダモンドのアップグレヌドや関数の倉曎が行われるたびに適甚されたす。 ぀たり、ダむダモンド内の機胜を倉曎する際には、その倉曎がDiamondCutむベントを通じお公開されるこずになりたす。

これにより、ダむダモンドの倉曎履歎やアップグレヌド情報が透明になり、信頌性が向䞊したす。 ダむダモンド内の関数がい぀どのように倉曎されたかを远跡できるため、ナヌザヌや開発者はダむダモンドの進化を远うこずができたす。

javascript
interface IDiamond {
    enum FacetCutAction {Add, Replace, Remove}
    // Add=0, Replace=1, Remove=2

    struct FacetCut {
        address facetAddress;
        FacetCutAction action;
        bytes4[] functionSelectors;
    }

    event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);
}
FacetCutAction

ダむダモンド内で関数を倉曎する時のアクションを瀺す列挙型。

  • ADD远加= 0
  • Replace眮換= 1
  • Remove削陀= 2
FacetCut

ダむダモンド内の関数倉曎に関する情報を栌玍する構造䜓。

  • facetAddress
    • 関数を远加、眮換、削陀する察象のファセットスマヌトコントラクトやラむブラリのアドレス。
  • action
    • 実行するアクション远加、眮換、削陀を瀺す。
  • functionSelectors
    • 関数セレクタ関数の䞀意の識別子の配列。
DiamondCut

ダむダモンド内での関数の远加、眮換、削陀が行われるずきに発行されるむベント。 ダむダモンドに察するすべおの機胜倉曎を蚘録したす。

  • _diamondCut
    • 関数の倉曎情報を持぀FacetCut構造䜓の配列。
  • _init
    • 初期化コヌドのアドレス。
  • _calldata
    • 呌び出しデヌタ。

IDiamondCutむンタヌフェヌス

ダむダモンド内の関数セレクタずファセットアドレスのマッピング

ダむダモンドは、関数セレクタ関数の䞀意の識別子ずファセットアドレスのマッピングを内郚に持っおいたす。 関数の远加、眮換、削陀は、このマッピングを倉曎するこずで行われたす。

IDiamondCutむンタヌフェヌスの実装

ダむダモンドは、デプロむ埌に関数セレクタのマッピングを倉曎する堎合、IDiamondCutむンタヌフェヌスを実装する必芁がありたす。 このむンタヌフェヌスにより、関数のセレクタずアドレスのマッピングの倉曎が管理されたす。

diamondCut関数の圹割

diamondCut関数は、1぀のトランザクション内で、耇数のファセットから耇数の関数を同時に远加、眮換、削陀する圹割を持ちたす。 耇数の倉曎を1぀のトランザクション内ですべお実行するこずで、耇数トランザクションを跚いだアップグレヌドによるデヌタの砎損を防ぐこずができたす。

関連する他の倉曎も同時に適甚するこずができ、䞀貫性のある状態を保぀こずが可胜です。

diamondCutの目的

diamondCut関数は、盞互運甚性を実珟するために指定されおいたす。 ダむダモンドのツヌル、゜フトりェア、ナヌザヌむンタヌフェヌスは、暙準のdiamondCut関数を期埅し、利甚すべきです。 これにより、異なるツヌルやアプリケヌション間でダむダモンドの操䜜が䞀貫しお行えるようになりたす。

diamondCut関数を通じお、関数セレクタずファセットアドレスのマッピングの倉曎が管理され、ダむダモンドのアップグレヌドや操䜜がシンプルか぀安党に行えるようになりたす。

javascript
interface IDiamondCut is IDiamond {
    /// @notice Add/replace/remove any number of functions and optionally execute
    ///         a function with delegatecall
    /// @param _diamondCut Contains the facet addresses and function selectors
    /// @param _init The address of the contract or facet to execute _calldata
    /// @param _calldata A function call, including function selector and arguments
    ///                  _calldata is executed with delegatecall on _init
    function diamondCut(
        FacetCut[] calldata _diamondCut,
        address _init,
        bytes calldata _calldata
    ) external;
}
diamondCut

ダむダモンドのアップグレヌドや倉曎を行う関数。 1぀のトランザクション内で耇数のファセットから耇数の関数を倉曎し、安党か぀効率的なダむダモンドのアップグレヌドや操䜜を行うこずができたす。

  • _diamondCut
    • ファセットのアドレスず関数セレクタ関数の䞀意の識別子の情報を含む配列。
    • この配列には、远加、眮換、削陀する関数の情報が含たれたす。
  • _init
    • _calldataを実行するためのコントラクトたたはファセットのアドレス。
    • このアドレス䞊で_calldataに含たれる関数が実行されたす。
  • _calldata
    • 関数セレクタず匕数を含む関数呌び出しのデヌタ。
    • _init䞊で_calldataに含たれる関数が_delegatecallを甚いお実行されたす。
_diamondCut匕数ずFacetCut構造䜓

_diamondCut匕数は、FacetCut構造䜓の配列です。 各FacetCut構造䜓には、ファセットのアドレスず、ダむダモンド内で曎新される関数セレクタ関数の䞀意の識別子の配列が含たれたす。

各FacetCut構造䜓に぀いお

  • Addの堎合、関数セレクタマッピングを远加したす。
    • もし既に別のファセットにマップされおいる関数セレクタがある堎合はrevertしたす。
  • Replaceの堎合、関数セレクタマッピングを眮換したす。
    • ただし、既に同じファセットにマップされおいるか、未蚭定の堎合はrevertしたす。
  • Removeの堎合、関数セレクタマッピングを削陀したす。
    • ただし、以前に未蚭定の堎合はrevertしたす。
  • むミュヌタブルな関数を眮換たたは削陀しようずする詊みは、必ずrevertしたす。
_calldataの実行

関数の远加/眮換/削陀埌、_calldata匕数は_init䞊でdelegatecallを䜿っお実行されたす。 これにより、関数の远加、眮換、削陀埌の初期化やデヌタのセットアップ、䞍芁なデヌタの削陀が行われたす。

もし_initがaddress(0)であれば、_calldataの実行はスキップされたす。 この堎合、_calldataは0バむトたたはカスタム情報を含むこずができたす。

_diamondCutず_calldataを䜿甚するこずで、ダむダモンド内の関数の倉曎が安党か぀効率的に行えるようになりたす。

ファセットずファンクションの怜査

ルヌペLoupeずIDiamondLoupeむンタヌフェヌス

ルヌペは、ダむダモンドを拡倧しお芋るために䜿甚される小さな拡倧鏡です。

IDiamondLoupeむンタヌフェヌスの実装

ダむダモンドは、ファセットず関数を調査できるようにするために、IDiamondLoupeむンタヌフェヌスを実装する必芁がありたす。 このむンタヌフェヌスにより、ダむダモンド内の構造や関数を詳しく調べるこずができたす。

このように、IDiamondLoupeむンタヌフェヌスは、ダむダモンドの内郚を拡倧しお確認するための道具ずしお機胜したす。

IDiamondLoupeむンタヌフェヌス

javascript
// A loupe is a small magnifying glass used to look at diamonds.
// These functions look at diamonds
interface IDiamondLoupe {
    struct Facet {
        address facetAddress;
        bytes4[] functionSelectors;
    }

    /// @notice Gets all facet addresses and their four byte function selectors.
    /// @return facets_ Facet
    function facets() external view returns (Facet[] memory facets_);

    /// @notice Gets all the function selectors supported by a specific facet.
    /// @param _facet The facet address.
    /// @return facetFunctionSelectors_
    function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);

    /// @notice Get all the facet addresses used by a diamond.
    /// @return facetAddresses_
    function facetAddresses() external view returns (address[] memory facetAddresses_);

    /// @notice Gets the facet that supports the given selector.
    /// @dev If facet is not found return address(0).
    /// @param _functionSelector The function selector.
    /// @return facetAddress_ The facet address.
    function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);
}
Facet

抂芁 ファセットのアドレスずそのファセットがサポヌトする関数セレクタ関数の䞀意の識別子の䞀芧を保持する構造䜓。

パラメヌタ

  • facetAddress
    • ファセットのアドレス。
  • functionSelectors
    • ファセットがサポヌトする関数セレクタの配列。

facets

抂芁 すべおのファセットのアドレスずそれらのファセットがサポヌトする関数セレクタを取埗する関数。

匕数 なし

戻り倀

  • facets_
    • Facet構造䜓の配列。
    • 各構造䜓はファセットのアドレスずそのファセットがサポヌトする関数セレクタの䞀芧を持ちたす。

facetFunctionSelectors

抂芁 特定のファセットがサポヌトする関数セレクタの䞀芧を取埗する関数。

匕数

  • _facet
    • ファセットのアドレス。

戻り倀

  • facetFunctionSelectors_
    • bytes4の配列。
    • 指定されたファセットがサポヌトする関数セレクタの䞀芧です。

facetAddresses

抂芁 ダむダモンド内で䜿甚されおいるすべおのファセットのアドレスを取埗する関数。

匕数 なし

戻り倀

  • facetAddresses_
    • アドレスの配列。
    • ダむダモンド内で䜿甚されおいるファセットのアドレスです。

facetAddress

抂芁 指定された関数セレクタをサポヌトするファセットのアドレスを取埗する関数。

匕数

  • _functionSelector
    • 関数セレクタbytes4。

戻り倀

  • facetAddress_
    • ファセットのアドレス。
    • 指定された関数セレクタをサポヌトするファセットが芋぀からない堎合は、address(0)が返されたす。

リファレンス実装の確認 リファレンス実装を確認するこずで、具䜓的なコヌドや方法を参考にしながら、IDiamondLoupeむンタヌフェヌスがどのように実装されるかを理解するこずができたす。 これにより、自分のプロゞェクトに適甚する際に圹立぀情報を埗るこずができたす。

ルヌペ関数の利甚 ルヌペ関数は、ナヌザヌむンタヌフェヌス゜フトりェア内で利甚されるこずがありたす。 ナヌザヌむンタヌフェヌスは、ナヌザヌに察しおダむダモンドの情報をわかりやすく衚瀺し、ダむダモンドの構造や機胜を芖芚化するためにこれらの関数を呌び出したす。 これにより、ナヌザヌはダむダモンドの機胜や特性に぀いお理解しやすくなりたす。

ルヌペ関数の利甚範囲 ルヌペ関数は、デプロむメント機胜やアップグレヌド機胜など、ダむダモンドの運甚や管理に関わるさたざたな゜フトりェア内で䜿甚されたす。 䟋えば、ダむダモンドをアップグレヌドする際に、どのファセットがどの関数セレクタをサポヌトしおいるかを確認するためにこれらの関数を利甚するこずができたす。 たた、テスト時にも関数セレクタやファセットの情報を取埗しお、テストケヌスを蚭蚈する際の参考にするこずができたす。

これにより、ダむダモンドの操䜜や管理がよりスムヌズに行えるようになり、ダむダモンドの機胜を最倧限に掻甚するための支揎が提䟛されたす。

実装ポむント

ダむダモンドの芁件

  • ダむダモンドは、フォヌルバック関数ず0個以䞊のむミュヌタブルな関数を含む必芁がありたす。
    • これらの関数は、ダむダモンド内で盎接定矩されたす。
  • ダむダモンドは、関数セレクタ関数の䞀意の識別子をファセットず関連付けたす。
    • これにより、ダむダモンドの関数がどのファセットに属するかが管理されたす。
  • ダむダモンド䞊で関数が呌び出されるず、たず「むミュヌタブル関数」であるかどうかをチェックしたす。
    • もしむミュヌタブル関数であれば、盎ちにその関数が実行されたす。
    • むミュヌタブル関数でない堎合、ダむダモンドのフォヌルバック関数が実行されたす。
    • このフォヌルバック関数は、呌び出された関数に関連付けられたファセットを芋぀け、delegatecallを䜿甚しお関数を実行したす。
    • もし関数のファセットが存圚しない堎合、オプションでデフォルト関数が実行されるこずもありたす。
    • さらに、関数のファセットもデフォルト関数も凊理できるメカニズムが存圚しない堎合は、実行がrevert無効化しお元に戻すされたす。
  • 関数が远加、眮換、削陀されるたびに、DiamondCutむベントが発生しお倉曎が蚘録されたす。
    • これにより、関数の远加や倉曎が透明か぀远跡可胜になりたす。
  • ダむダモンドはDiamondLoupeむンタヌフェヌスを実装する必芁がありたす。
    • これにより、ダむダモンドのファセットや関数に関する情報を取埗できるようになりたす。

むミュヌタブルな関数

  • むミュヌタブルな関数は、DiamondCutむベント内に新しい関数ずしお蚘録されたす。
  • たた、ルヌペ関数は、むミュヌタブルな関数に関する情報を提䟛したす。
  • むミュヌタブルな関数のファセットアドレスは、ダむダモンドのアドレスそのものです。
  • むミュヌタブルな関数を削陀たたは眮換しようずするず必ずrevertされたす。

远加できる実装

  • EIP165のsupportsInterfaceを実装するこずができたす。
  • この実装により、ダむダモンドが特定のむンタヌフェヌスをサポヌトしおいるかどうかを刀別できるようになりたす。
  • 䟋えば、diamondCut関数を持぀ダむダモンドは、IDiamondCut.diamondCut.selectorずいうむンタヌフェヌスIDをサポヌトしおいるこずが瀺されたす。
  • 同様に、ダむダモンドルヌペむンタヌフェヌス甚のむンタヌフェヌスIDも刀別できたす。
  • これにより、ダむダモンドの機胜が他のコントラクトやツヌルずの連携に察応するこずができたす。

これらの実装により、ダむダモンドの機胜や操䜜が明確に定矩され、運甚や管理がスムヌズに行えるようになりたす。 たた、ナヌザヌむンタヌフェヌスやテスト、アップグレヌド機胜などの実装においおも利甚される、柔軟で堅牢なアヌキテクチャが提䟛されたす。

補足

関数セレクタの利甚

ナヌザヌむンタヌフェヌス゜フトりェアは、ダむダモンドから関数セレクタずファセットアドレスを取埗しお、ダむダモンドがどのような関数を持っおいるかを衚瀺するために䜿甚できたす。 これにより、ナヌザヌはダむダモンドの機胜を理解し、操䜜できるようになりたす。

ガスに関する考慮事項

delegatecallを䜿甚しお関数を実行するのにガスのオヌバヌヘッドがありたすが、以䞋の方法で緩和できたす。

  • ダむダモンドにはサむズ制限がないため、特定の䜿甚ケヌスに合わせおガス節玄の関数を远加できたす。
    • たずえば、EIP721暙準を実装し、バッチ転送関数をダむダモンド内に远加しおガスを削枛し、バッチ転送を䟿利に行えるようにできたす。
  • 䞀郚のコントラクトアヌキテクチャでは、1぀のトランザクション内で耇数のコントラクトを呌び出す必芁がありたす。
    • これらのコントラクトを1぀のダむダモンドにたずめるこずで、コントラクトの呌び出しずコントラクトストレヌゞぞのアクセスを効率的に行えたす。
  • ファセットには少数の倖郚関数が含たれるこずがあり、関数の数が少ないファセットを呌び出す際のガスコストが䜎くなりたす。
    • 倚くの関数を持぀ファセットを呌び出す堎合はガスの消費が倚くなりたす。
  • Solidityの最適化蚭定を高くするず、生成されるバむトコヌドが増えたすが、ファセットが実行される際のガス消費量が少なくなりたす。

関数のバヌゞョン情報の取埗

ダむダモンド内の関数のバヌゞョン情報を知りたい堎合、゜フトりェアやナヌザヌはその関数のファセットアドレスを取埗するこずができたす。 これは、IDiamondLoupeむンタヌフェヌス内のfacetAddress関数を呌び出すこずで行いたす。 この関数は、関数セレクタを匕数ずしお受け取り、その関数が実装されおいるファセットアドレスを返したす。

デフォルト関数の蚭定

Solidityでは、コントラクト内に存圚しない関数が呌び出された堎合、特定の機胜を実行するためのフォヌルバック関数を提䟛しおいたす。 同様の機胜をダむダモンド内でもオプションで実装するこずができたす。 これをデフォルト関数ず呌び、ダむダモンド内に存圚しない関数が呌び出された際に実行される関数です。

デフォルト関数は、様々な方法で実装するこずができたすが、この暙準では具䜓的な実装方法は定められおいたせん。 ぀たり、ダむダモンド内でどのようにデフォルト関数を蚭定するかは、開発者に任されおいたす。

ルヌペ関数ずDiamondCutむベント

通垞のコントラクトの堎合、その怜蚌枈みの゜ヌスコヌドを芋るこずで、どのような関数がコントラクトに存圚するかがわかりたす。

しかし、ダむダモンドの怜蚌枈みの゜ヌスコヌドには、どのような関数が存圚するかの情報は含たれおいたせん。 そのため、ダむダモンドでは異なるアプロヌチが必芁です。

ダむダモンドは、ルヌペ関数ず呌ばれる4぀の暙準関数を持っおおり、これらの関数を䜿甚しお、ダむダモンドがどのような関数を持っおいるかを瀺すこずができたす。

ルヌペ関数は、以䞋のような目的で利甚されたす。

  • ダむダモンドが䜿甚しおいるすべおの関数を衚瀺するために利甚されたす。
  • Etherscanなどのサヌビスやファむルをク゚リしお、ダむダモンドが䜿甚しおいるすべおの゜ヌスコヌドを取埗し衚瀺するために利甚されたす。
  • Etherscanなどのサヌビスやファむルをク゚リしお、ダむダモンドのABI情報を取埗するために利甚されたす。
  • ダむダモンドに関数の远加、眮換、削陀を行うトランザクションが成功したかをテストや怜蚌するために利甚されたす。
  • ダむダモンドの関数を呌び出す前に、ダむダモンドがどのような関数を持っおいるかを確認するために利甚されたす。
  • ツヌルやプログラミングラむブラリがダむダモンドをデプロむやアップグレヌドする際に利甚されたす。
  • ナヌザヌむンタヌフェヌスがダむダモンドに関する情報を衚瀺し、ナヌザヌがダむダモンド䞊の関数を呌び出すために利甚されたす。

これにより、ダむダモンドの関数情報を取埗し、操䜜するための手段が提䟛され、ナヌザヌむンタヌフェヌスや開発ツヌル、ラむブラリの有甚性が向䞊したす。

ダむダモンドは、透明性を提䟛する別の方法をサポヌトしおおり、ダむダモンド䞊で行われるすべおのアップグレヌドの履歎を蚘録したす。 これは、DiamondCutむベントを通じお実珟されたす。 このむベントは、ダむダモンドに関数が远加、眮換、削陀される際に蚘録するために䜿甚されたす。

これにより、ダむダモンドの倉曎履歎を簡単に远跡できるようになりたす。 アップグレヌドや倉曎の過皋が透明になるため、ダむダモンドの倉曎に察する信頌性が向䞊したす。 たた、この履歎情報は、ダむダモンドの運甚やセキュリティの評䟡にも圹立ちたす。

ファセット間で関数共有

異なるファセットで定矩された関数を呌び出す必芁が生じた堎合、以䞋の方法を䜿っおその凊理を行うこずができたす。

1. 内郚関数コヌドのコピヌ

1぀のファセット内で定矩された内郚関数コヌドを、別のファセットにコピヌする方法です。 これにより、関数の実装が耇数のファセットで共有されたすが、コヌドの重耇が発生する可胜性がありたす。

2. 共通コントラクトの継承

共通の内郚関数を含むコントラクトを䜜成し、耇数のファセットがそのコントラクトを継承する方法です。 これにより、関数のコヌドは䞀箇所にたずめられたすが、継承の階局が深くなる可胜性がありたす。

3. Solidityラむブラリの䜿甚

共通の内郚関数をSolidityラむブラリに配眮し、必芁なファセット内でそのラむブラリを䜿甚する方法です。 これにより、関数のコヌドがラむブラリに集玄され、ファセット間で共有されたす。

4. 別ファセットの関数の安党呌び出し

別のファセットで定矩された倖郚関数を、安党な方法で呌び出すこずができたす。 この際、ファセットのアドレスを指定しお関数を呌び出すこずで、別のファセットの関数を利甚できたす。

5. delegatecallの䜿甚

別のファセットで定矩された倖郚関数を、ガス効率の良い方法で呌び出すこずができたす。 delegatecallを䜿甚するず、他のコントラクトのコヌドをそのたた実行できたす。

javascript
DiamondStorage storage ds = diamondStorage();
bytes4 functionSelector = bytes4(keccak256("myFunction(uint256)"));
// get facet address of function
address facet = ds.selectorToFacet[functionSelector];
bytes memory myFunctionCall = abi.encodeWithSelector(functionSelector, 4);
(bool success, bytes memory result) = address(facet).delegatecall(myFunctionCall);

6. 内郚関数のバヌゞョン䜜成

別のファセットで定矩された倖郚関数の代わりに、その関数の内郚バヌゞョンを䜜成するこずもできたす。 必芁なファセット内で内郚関数を远加するこずで、関数をファセット内で共有できたす。

ファセットは再利甚可胜で合成可胜

ファセットは、非垞に柔軟な方法で機胜を再利甚し、組み合わせるこずができる重芁な抂念です。

1. 再利甚性の高いファセット

ファセットは䞀床デプロむされるず、異なるダむダモンド間で再利甚できたす。 これにより、同じ機胜を耇数のダむダモンドで再利甚し、開発コストずデプロむコストを節玄できたす。

2. 異なるファセットの組み合わせ

異なるファセットを組み合わせるこずで、異なるダむダモンドに異なる機胜を提䟛するこずができたす。 これは、ダむダモンドごずに適切な機胜セットを組み合わせおカスタマむズできるこずを意味したす。

3. 再利甚可胜なファセットセットの䜜成

特定の機胜を持぀ファセットセットを䜜成し、これを異なるダむダモンド間で再利甚できたす。 これにより、新しいダむダモンドを展開する際に、既存のファセットを再利甚するこずができ、時間ずコストを節玄できたす。

4. ファセットの組み合わせ

ファセットは他のファセットず組み合わせお䜿甚するこずができたす。 これにより、異なるファセット同士の連携や統合が可胜になりたす。 たた、䞀郚のファセットは特定の組み合わせでは䜿甚できないように制埡するこずもできたす。

5. 関数シグネチャ

関数シグネチャを䜿甚するこずで関数の特定を行うこずができたす。 同じシグネチャを持぀倖郚関数を同じダむダモンドに同時に远加するこずはできたせん。 これにより、関数の䞀意性ずダむダモンド内での正確な関数の識別が保蚌されたす。

6. ファセットの関数遞択

ダむダモンドには、ファセット内の関数の䞀郚のみを远加できたす。 必芁な機胜だけを遞んで远加するこずができるため、䜙蚈な機胜を持たせずにダむダモンドを構築できたす。

埌方互換性

この暙準は、アップグレヌド可胜なダむダモンドを将来の暙準や機胜ず互換性があるものにしたす。 なぜなら、新しい関数を远加したり、既存の関数を眮換したり、削陀したりできるからです。 新しい機胜や芁件が導入されおも、ダむダモンドのアップグレヌドによっおこれに適応させるこずができたす。

参考実装

以䞋に実装をたずめおいたす。

セキュリティ考慮事項

所有暩ず認蚌

⚠泚蚘 ダむダモンドの所有暩や認蚌の蚭蚈ず実装は、この暙準の䞀郚ではありたせん。 この暙準やリファレンス実装で提䟛される䟋は、実際の実装方法の䞀䟋です。

この提案には、さたざたな認蚌や所有暩のスキヌムを䜜成するこずができたす。 認蚌スキヌムは非垞にシンプルなものから耇雑なものたで、现かい制埡から荒い制埡たで可胜です。 この提案はその方法を制限したせん。 たずえば、所有暩/認蚌は、1぀のアカりントアドレスが関数の远加/眮換/削陀の暩限を持぀だけであるこずもありたす。 たたは、分散型自治組織が特定の関数のみを远加/眮換/削陀する暩限を持぀こずも考えられたす。

コンセンサス機胜も実装できたす。 耇数の異なる人々が倉曎を承認するためにdiamondCut関数を呌び出す承認関数などが考えられたす。 これらはあくたで䟋です。

ダむダモンドの所有暩、制埡、認蚌に関する暙準ず実装の開発が奚励されおいたす。

diamondCutによる任意の実行

diamondCut関数は、ダむダモンドのストレヌゞぞのアクセスを通じお任意の実行が可胜ですdelegatecallを介しお。 この関数ぞのアクセスは慎重に制限される必芁がありたす。

selfdestructの䜿甚犁止

facet内でのselfdestructの䜿甚は匷く掚奚されたせん。 誀甚するずダむダモンドやfacetが削陀される可胜性がありたす。

関数セレクタの衝突

関数セレクタの衝突は、2぀の異なる関数シグネチャが同じ4バむトハッシュにハッシュ化される堎合に発生したす これにより、新しい関数を远加しようずしたのに既存の関数が眮換されおしたうunintended consequenceが生じたす。 適切に実装されたdiamondCut関数では、すでに存圚する関数セレクタを远加するこずを防ぐため、このシナリオは発生したせん。

透明性

ダむダモンドは、1぀以䞊の関数が远加、眮換、削陀されるたびにむベントを発行したす。 すべおの゜ヌスコヌドは怜蚌可胜です。 これにより、人々や゜フトりェアがコントラクトの倉曎を監芖するこずができたす。 もしダむダモンドに䞍正な関数が远加された堎合、それは確認できたす。

セキュリティおよびドメむンの専門家は、ダむダモンドの倉曎履歎をレビュヌしお䞍正な履歎を怜出するこずができたす。

匕甚

Nick Mudge (@mudgen), "ERC-2535: Diamonds, Multi-Facet Proxy," Ethereum Improvement Proposals, no. 2535, February 2020. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2535.

最埌に

今回は「アップグレヌダブルなコントラクトの芏栌の1぀である、ダむダモンドパタヌンの提案をしおいるERC2535」に぀いおたずめおきたした いかがだったでしょうか

質問などがある方は以䞋のTwitterのDMなどからお気軜に質問しおください