0
0
Blockchain / Solidityprogramming~10 mins

Minimal proxy (clone) pattern in Blockchain / Solidity

Choose your learning style9 modes available
Introduction

The minimal proxy pattern helps create many copies of a smart contract cheaply by sharing code. It saves gas and storage on the blockchain.

When you want to deploy many similar smart contracts without repeating all code.
When you want to save blockchain storage and reduce deployment costs.
When you want to upgrade logic in one place and have all clones use it.
When you want to create lightweight contract instances quickly.
When you want to keep your contract system modular and efficient.
Syntax
Blockchain / Solidity
contract Clone {
    address public implementation;

    constructor(address _implementation) {
        implementation = _implementation;
    }

    fallback() external payable {
        address impl = implementation;
        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }
}

The proxy contract stores the address of the original contract (implementation).

Calls to the proxy are forwarded to the implementation using delegatecall, preserving context.

Examples
This example shows a minimal proxy forwarding all calls to the implementation contract.
Blockchain / Solidity
contract MinimalProxy {
    address public implementation;

    constructor(address _impl) {
        implementation = _impl;
    }

    fallback() external payable {
        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), sload(0), 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }
}
This example uses a library to create minimal proxy clones easily.
Blockchain / Solidity
// Using OpenZeppelin's Clones library
import "@openzeppelin/contracts/proxy/Clones.sol";

contract Factory {
    address public implementation;

    constructor(address _impl) {
        implementation = _impl;
    }

    function createClone() external returns (address) {
        return Clones.clone(implementation);
    }
}
Sample Program

This program shows a logic contract and a minimal proxy that forwards calls to it. The proxy stores data separately but uses logic from the original contract.

Blockchain / Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Logic {
    uint public x;

    function setX(uint _x) public {
        x = _x;
    }
}

contract MinimalProxy {
    address public implementation;

    constructor(address _impl) {
        implementation = _impl;
    }

    fallback() external payable {
        address impl = implementation;
        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }
}

// Deployment steps (not in code):
// 1. Deploy Logic contract.
// 2. Deploy MinimalProxy with Logic's address.
// 3. Call setX on MinimalProxy to set x in proxy's storage.

// After calling setX(42) on MinimalProxy, reading x from MinimalProxy returns 42.
OutputSuccess
Important Notes

The proxy uses delegatecall to run code in the context of the proxy's storage.

Minimal proxies are very cheap to deploy compared to full contracts.

Be careful with storage layout to avoid conflicts between proxy and implementation.

Summary

Minimal proxy pattern creates cheap clones by forwarding calls to a shared implementation.

It saves gas and storage on the blockchain.

Useful for deploying many similar contracts efficiently.