問題一覧に戻る
上級高度なパターン
問題89: プロキシパターン
Solidityのプロキシパターンを学習 - delegatecallでコントラクトアップグレードを可能に。プロキシはロジックとストレージを分離し、状態を保持しながらコード更新を可能にします。プロキシはdelegatecallで実装コントラクトコードを自身のストレージコンテキストで実行。このパターンはコントラクトアップグレード、バグ修正、デプロイ後の機能追加を可能にします。プロキシパターンの理解は、保守可能でアップグレード可能なスマートコントラクトシステム構築に重要です。
pragma solidity ^0.8.0;
contract Proxy {
address public implementation;
address public admin;
modifier onlyAdmin() {
require(msg.sender == , "Not admin");
_;
}
constructor(address _implementation) {
implementation = ;
admin = msg.sender;
}
// 実装コントラクトをアップグレード
function upgrade(address newImplementation) external {
implementation = ;
}
// 呼び出し転送用fallback関数
fallback() external payable {
address impl = ;
// 実装へのdelegatecall
assembly {
calldatacopy(0, 0, calldatasize())
let result := (gas(), impl, 0, calldatasize(), 0, 0)
returndatacopy(0, 0, returndatasize())
switch result
case 0 { revert(0, ) }
default { return(0, returndatasize()) }
}
}
}
contract Implementation {
address public implementation; // Slot 0
address public admin; // Slot 1
uint256 public value; // Slot 2
// ビジネスロジック実装
function setValue(uint256 _value) external {
value = ;
}
function getValue() external view returns (uint256) {
return ;
}
}