Deploy Any Contract Using Proxy
Neeraj Choubisa
Posted on June 14, 2023
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;
}
}
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;
}
}
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");
}
}
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);
}
}
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)`
Give your valuable comments to improve learning
Posted on June 14, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.