ERC7546ってなに?
コントラクトは実装限界サイズ(24576bytes)が決まっている。それを解決するための提案。
どうやって解決しているの?
通常、1つのコントラクトに複数の関数を実装するが、このERC7546では、1つのコントラクトに1つの関数を実装して運用する設計をしている。
関数セレクタをキーとして実装アドレスを管理し、呼び出される関数ごとにアドレスを切り替え、実行している
どんな構成になってるの?
独自のProxyコントラクトとDictionaryコントラクトで構成されている。
コール自体はProxyコントラクトで受け止め、関数実行先を管理しているDictionaryコントラクトから必要な情報を呼び出し、処理している。
コードレビューしてみた
ERC7546Proxy
デリゲートに関しては継承元のProxyコントラクトが責務を負っているので、ERC7546Proxy自体はDictionaryコントラクトのアドレスを管理している。
msg.sigに関数セレクタがセットされているので、それを使ってDictionaryコントラクトから該当する実装アドレスを取得し、返却する機構を実装している。
Dictionaryコントラクトのアドレスは他のデータと競合しないように、ストレージスロットに保存されている(丁寧)。
Dictionary
プロキシに対して関数を実行した際、コールされる関数がセットされている実装アドレスを管理している。
コンストラクタで関数呼び出し設定変更の権限を持つadminの設定をしているが、Ownableをそのまま使わない理由はなんやろか。
supportsInterfaceで関数セレクタの結果をそのまま返しているところが面白い。
コントラクトのinterfaceIdではなく関数セレクタでチェックしているので、賛否分かれそうな雰囲気がする。
思うところ
関数間のデータ受け渡しに関して、通常のコントラクトであれば、内部変数にそのままアクセスすればOKだが、ERC7546に関してはそうはいかない。(だよね?)
やろうと思えばできるだろうが、複数のアドレスを経由する必要があるため、通常の処理よりもガス代が増えると思われる、我々は常にガスと戦っている。
(追記)ご指摘いただきました、Slot使うようです、なるほど
また、ERC7546Proxy経由で普通に関数を呼び出す時も一旦Dictionaryへのアクセスが入るので、それもガス上昇の原因となり得る。
大人しくコントラクトを分けるか、このERCを利用するか。
結局はトレードオフ、銀の弾丸はなし。
参照先リンク
github.com
https://github.com/kaihiroi/ERCs/blob/ucs/ERCS/erc-7546.md
github.com
https://github.com/ethereum/ERCs/blob/9d1e9da45bf21212dc7de63483da967b96fadd7e/ERCS/erc-7546.md
Kai🌸 (@kai_hiroi) on X
Diving into EVM🐬
https://twitter.com/kai_hiroi
Sgさん@極度Solidity書きなさい (@shogochiai) on X
EVM and free LLM maximalist. / en:@_sgtn
https://twitter.com/shogochiai