3分钟Solidity: 9.6 部署任何合约

17 阅读1分钟

欢迎订阅专栏3分钟Solidity--智能合约--Web3区块链技术必学

如需获取本内容的最新版本,请参见 Cyfrin.io 上的“部署任意合同(代码示例)”

通过调用 Proxy.deploy(bytes memory _code)来部署任何合约。

在这个例子中,你可以通过调用 Helper.getBytecode1和 Helper.getBytecode2来获取合约的字节码。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

contract Proxy {
    event Deploy(address);

    receive() external payable {}

    function deploy(bytes memory _code)
        external
        payable
        returns (address addr)
    {
        assembly {
            // create(v, p, n)
            // v = 发送的ETH数量
            // p = 指向代码起始位置的内存指针
            // n = 代码大小
            addr := create(callvalue(), add(_code, 0x20), mload(_code))
        }
        // 出错时返回地址0
        require(addr != address(0), "部署失败");

        emit Deploy(addr);
    }

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

contract TestContract1 {
    address public owner = msg.sender;

    function setOwner(address _owner) public {
        require(msg.sender == owner, "非所有者");
        owner = _owner;
    }
}

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

    constructor(uint256 _x, uint256 _y) payable {
        x = _x;
        y = _y;
    }
}

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

    function getBytecode2(uint256 _x, uint256 _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);
    }
}

Remix Lite 尝试一下