はじめに
コントラクトコードは一度ブロックチェーンにdeployされると変更ができません。
サービスのアップデートと共に、機能追加やバグの改修などの必要性に迫られた場合、
コントラクトを新しく作り直し、向き先を変更する必要がありますが、
solidity-proxyというproxyコントラクトを間に挟むことで、update可能なコントラクトを作ることができます。
イメージ
クライアントは、proxyのcontractに向けて、メソッドをcallしますが、実際には、deleatecallで、
ロジックを記述したコントラクトを制御しています。
このため、クライアントの向き先は常にproxy contractをcallし、proxyの向き先をver.1からvers.2に変更することで、新しいロジックをclientに提供することができます。
実践
remixを用いて、これらの一連の流れを確認することができます。
使用するコードはこちらから利用させていただきました。
https://hackernoon.com/ethereum-smart-contract-upgradeability-hands-on-ceaf98be070f
一応全体抜き出したもの。
https://gist.github.com/oggata/02a86fd43a45ddc4e5bf4df103f7393f
1.TokenVersion1をdeployします.
2.TokenVersion2をdeployします
3.Proxyをdeployして、TokenVersion1のcontractAddressをupgradeToに入れて実行します.
4.ProxyのcontractAddressをAtAddressに入力して、TokenVersion1を読み込みます。
これでProxyとTokenVersion1が紐づけられます.
5.mintにアドレス、100と入力して、balanceOfを見ると200となっています.
(元の解説では、これはVersion1のバグと言う設定で、本来は100入力すると100と出てくるのが正しく、Version2でこれを改修すると言う流れになっています。)
6.次に、ProxyのupgradeToに、TokenVersion2のcontractaddressを入力します。
implementationを見ると、TokenVersion1のコントラクトアドレスから、2のアドレスに変わっていることがわかります。
7.proxyのcontractaddressをTokenVersion2で実行します
8.balanceOfをすると、先ほどVersion1で実行した200が残高として残っています。
9.アドレス、30とmintに入力して実行すると、残高に30足されています。
これはVersion1のバグで、入力値が2倍に増えていたと言うバグが修正され、入力値がそのままaddされると言う正常の挙動に戻っていることを意味しています。
おしまい
参考
「Ethereum Smart Contract Upgradeability: Hands-On」
https://hackernoon.com/ethereum-smart-contract-upgradeability-hands-on-ceaf98be070f
「アップグレード可能なスマートコントラクトを実現する具体的なアプローチ」
https://zoom-blc.com/how-to-develop-upgradable-contracts