問題一覧に戻る
上級高度なパターン
問題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 ;
}
}