// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract TestContract1 {address public owner = msg.sender;function setOwner(address _owner) public {require(msg.sender == owner, "not owner");owner = _owner;}}contract TestContract2 {address public owner = msg.sender;uint public value = msg.value;uint public x;uint public y;/*payable 可以在调用这笔函数的消息中附带以太币*/constructor(uint _x, uint _y) payable{x = _x;y = _y;}}contract Proxy {// 事件:向链外汇报部署的地址event Deploy(address);/*returns 返回新部署的地址*/function deploy(bytes memory _code) external payable returns (address addr){// 内联汇编assembly {// create(v, p, n)// v = 部署合约发送的以太坊主币的数量(msg.value可以代表主币数量,但内联汇编中不能这样使用)// p = 内存中机器码开始的位置// n = 内存中机器码的大小addr := create(callvalue(), add(_code, 0x20), mload(_code))}require (addr != address(0), "deploy failed");emit Deploy(addr); // 触发事件}/*代理合约部署合约1的时候需要设置合约1的所有者*/function execute(address _target, bytes memory _data) external payable {(bool success, ) = _target.call {value: msg.value}(_data);require(success, "failed");}}// 助手合约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));}// 设置管理员,注意return行中字符串为TestContract1设置拥有者的方法签名function getCalldata(address _owner) external pure returns (bytes memory) {return abi.encodeWithSignature("setOwner(address)", _owner);}}
部署代理合约&助手合约


部署合约1
通过助手合约获取合约1的机器码

通过代理合约部署合约1

通过汇报地址加载合约1

设置合约1的所有者
设置前

设置
通过助手合约打包个人地址

通过代理合约设置合约1地址

设置后
设置后的所有者已变更为助手打包的个人地址

部署合约2
通过助手合约获取合约2的机器码

通过代理合约部署合约2


通过汇报地址加载合约2

观察合约2的各项参数

