Deploy Any Contract Using Proxy

kalidecoder

Neeraj Choubisa

Posted on June 14, 2023

Deploy Any Contract Using Proxy

Let's Create Two Dummy Contracts First ...

TEST-CONTRACT-1
Let's Understand what is happening in this contract . We Declare a variable owner and passing first calling or deploying address as owner . And creating an setOwner function for changing the owner variable only by owner .

contract TestContract1 {
    address public owner = msg.sender;

    function setOwner(address _owner) public {
        require(msg.sender == owner, "not owner");
        owner = _owner;
    }
}
Enter fullscreen mode Exit fullscreen mode

Let's Understand what is happening in this contract . We Declare state of variables owner holding the address of deployer address . Value variable holding amount of ether deposit at the time of deploying .And an x and y variable just for holding uint value .

TEST-CONTRACT-2

contract TestContract2 {
    address public owner = msg.sender;
    uint public value = msg.value;
    uint public x;
    uint public y;

    constructor(uint _x, uint _y) payable {
        x = _x;
        y = _y;
    }
}
Enter fullscreen mode Exit fullscreen mode

Writing Proxy Contract To Deploy This Contracts :-

This is an proxy contract which has three functions

  • receive to hold the ethers ,
  • Deploy function to deploy the test contracts ,
  • execute function to execute the test contract functions from proxy contract it-self .
contract Proxy {
    event Deploy(address);

    receive() external payable {}

    function deploy(bytes memory _code) external payable returns (address addr) {
        assembly {
            `// create(v, p, n)`
            `// v = amount of ETH to send`
            `// p = pointer in memory to start of code`
            `// n = size of code`
            addr := create(callvalue(), add(_code, 0x20), mload(_code))
        }
        // return address 0 on error
        require(addr != address(0), "deploy failed");

        emit Deploy(addr);
    }

    function execute(address _target, bytes memory _data) external payable {
        (bool success, ) = _target.call{value: msg.value}(_data);
        require(success, "failed");
    }
}

Enter fullscreen mode Exit fullscreen mode

There is Another contract as a Helper Contract that provides bytes codes :-

contract Helper {
    function getBytecode1() external pure returns (bytes memory) {
        bytes memory bytecode = type(TestContract1).creationCode;
        return bytecode;
    }

    function getBytecode2(uint _x, uint _y) external pure returns (bytes memory) {
        bytes memory bytecode = type(TestContract2).creationCode;
        return abi.encodePacked(bytecode, abi.encode(_x, _y));
    }

    function getCalldata(address _owner) external pure returns (bytes memory) {
        return abi.encodeWithSignature("setOwner(address)", _owner);
    }
}

Enter fullscreen mode Exit fullscreen mode

Now you are wondering how to call deploy function to deploy test contracts .
So let's start deployment process

- First Deploy Proxy Contract 
- Deploy Helper Contract Then 
- Call `function getBytecode1()` to get the bytecode of contract1 
- Put that bytecode in `function deploy(bytes memory _code)` this function and called 
- You get the deploy contract address of testcontract1 .
- Get the contract details by calling from that address you get .
- Call owner variable you see that proxy contract address is the owner .
- To change the address call this function `function execute(address _target, bytes memory _data) ` give the contract address of test contract1 and give the bytecode of `setOwner` function by calling `function getCalldata(address _owner)`
Enter fullscreen mode Exit fullscreen mode

Give your valuable comments to improve learning

💖 💪 🙅 🚩
kalidecoder
Neeraj Choubisa

Posted on June 14, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Deploy Any Contract Using Proxy
smartcontract Deploy Any Contract Using Proxy

June 14, 2023