logo

ERC7546コードレビュー

〜画像に他意はないです〜
profile photo
TaniguchiAkira

ERC7546ってなに?

コントラクトは実装限界サイズ(24576bytes)が決まっている。それを解決するための提案。

どうやって解決しているの?

通常、1つのコントラクトに複数の関数を実装するが、このERC7546では、1つのコントラクトに1つの関数を実装して運用する設計をしている。
関数セレクタをキーとして実装アドレスを管理し、呼び出される関数ごとにアドレスを切り替え、実行している

どんな構成になってるの?

https://github.com/kaihiroi/ERCs/blob/ucs/ERCS/erc-7546.md
https://github.com/kaihiroi/ERCs/blob/ucs/ERCS/erc-7546.md
コール自体はProxyコントラクトで受け止め、関数実行先を管理しているDictionaryコントラクトから必要な情報を呼び出し、処理している。

コードレビューしてみた

ERC7546Proxy

デリゲートに関しては継承元のProxyコントラクトが責務を負っているので、ERC7546Proxy自体はDictionaryコントラクトのアドレスを管理している。
msg.sigに関数セレクタがセットされているので、それを使ってDictionaryコントラクトから該当する実装アドレスを取得し、返却する機構を実装している。
Dictionaryコントラクトのアドレスは他のデータと競合しないように、ストレージスロットに保存されている(丁寧)。

Dictionary

プロキシに対して関数を実行した際、コールされる関数がセットされている実装アドレスを管理している。
コンストラクタで関数呼び出し設定変更の権限を持つadminの設定をしているが、Ownableをそのまま使わない理由はなんやろか。
supportsInterfaceで関数セレクタの結果をそのまま返しているところが面白い。
コントラクトのinterfaceIdではなく関数セレクタでチェックしているので、賛否分かれそうな雰囲気がする。

思うところ

関数間のデータ受け渡しに関して、通常のコントラクトであれば、内部変数にそのままアクセスすればOKだが、ERC7546に関してはそうはいかない。(だよね?)
やろうと思えばできるだろうが、複数のアドレスを経由する必要があるため、通常の処理よりもガス代が増えると思われる、我々は常にガスと戦っている。
(追記)ご指摘いただきました、Slot使うようです、なるほど
また、ERC7546Proxy経由で普通に関数を呼び出す時も一旦Dictionaryへのアクセスが入るので、それもガス上昇の原因となり得る。
大人しくコントラクトを分けるか、このERCを利用するか。
結局はトレードオフ、銀の弾丸はなし。

参照先リンク

github.com
github.com
Kai🌸 (@kai_hiroi) on X
Diving into EVM🐬
Kai🌸 (@kai_hiroi) on X
Sgさん@極度Solidity書きなさい (@shogochiai) on X
EVM and free LLM maximalist. / en:@_sgtn
Sgさん@極度Solidity書きなさい (@shogochiai) on X
Related posts
post image
日本のソフトウェアに未来はあるのか
post image
Solidity
OpenZeppelin
AA
OpenZeppelin 5.2.0が出るよ
post image
Solidity
Optimism
Arbitrum
L2
Wormhole
Layer0
オレオレインターフェースからERC7802へ
ユニバーサル規格は大事
Powered by Notaku