CREATE2是以太坊的一条EVM指令,用于部署智能合约。与传统的CREATE指令不同,CREATE2允许通过计算得到合约地址,而不是依赖发送方的nonce。这种方式使得合约地址在部署之前就可以被预测,方便一些高级用例,例如「工厂模式」和「合约钱包的预部署地址」。
CREATE2 是以太坊的一条 EVM 指令,用于部署智能合约。与传统的 CREATE 指令不同,CREATE2 允许通过计算得到合约地址,而不是依赖发送方的 nonce。这种方式使得合约地址在部署之前就可以被预测,方便一些高级用例,例如 「工厂模式」 和 「合约钱包的预部署地址」。
address = keccak256(rlp(sender, nonce))[12:]
合约地址依赖部署者的 nonce,在部署前无法预测地址,部署顺序改变时地址也会变化。
address = keccak256(0xFF, deployer, salt, keccak256(init_code))[12:]
「部署流程」
「底层实现(EVM 指令)」
[value, offset, size, salt] -> [new_contract_address]
value:要发送的 ETH 数量
offset 和 size:表示初始化代码在内存中的位置和大小
salt:一个用户定义的 32 字节值,用于唯一标识部署
返回值是新合约的地址。
CREATE2 是 EVM 中的一个指令,操作码为 0xF5
参数栈
address = keccak256(0xFF, deployer, salt, keccak256(init_code))[12:]
「步骤解析」
合约部署时的初始化代码
包括合约构造函数的逻辑
用户提供的一个任意值,用于指定不同的合约部署场景
通常用于生成不同的合约地址。
「固定前缀」 0xFF:防止与 CREATE 生成的地址冲突
「部署者地址」 deployer:当前创建合约的账户地址
「盐值」 salt:
「初始化代码哈希」 keccak256(init_code):
「计算地址:」 整个哈希结果的后 20 字节(即 [12:])被用作最终的合约地址。
pragma solidity ^0.8.0;
contract Factory {
event Deployed(address addr);
function deploy(bytes32 salt, bytes memory bytecode) public returns (address) {
address addr;
assembly {
addr := create2(0, add(bytecode, 0x20), mload(bytecode), salt)
}
require(addr != address(0), "Deploy failed");
emit Deployed(addr);
return addr;
}
function computeAddress(bytes32 salt, bytes memory bytecode) public view returns (address) {
return address(uint160(uint(keccak256(abi.encodePacked(
bytes1(0xFF),
address(this),
salt,
keccak256(bytecode)
)))));
}
}
「调用流程」
「部署新合约:」 调用 deploy 函数,传入 salt 和目标合约的字节码
「计算合约地址」: 使用 computeAddress 提前计算合约地址,确保预测地址正确
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!