Solidity——Create2
介绍
君士坦丁堡硬升级中引入了一个新操作码 CREATE2 ,它使用新的方式来计算常见的合约地址,让生成的合约地址更具有可控性。
具体内容
在 CREATE2 以前,CREATE指令创建的合约地址是通通过交易发起者(sender)的地址以及交易序号(nonce)来计算确定的。sender 和 nonce 进行 RLP 编码,然后用 Keccak-256 进行 hash 计算(伪码):
keccak256(rlp([sender, nonce]))
而 CREATE2 指令则主要是根据创建合约的初始化代码(init_code)及盐(slat) 生成(伪码):
一般而言init_code==bytecode,就是编译生成的字节码,借此让地址变成了对合约代码的验证
keccak256(0xff + sender + salt + keccak256(init_code))
使用
pool = address(new UniswapV3Pool{salt: keccak256(abi.encode(token0, token1, fee))}());
function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) {
require(key.token0 < key.token1);
pool = address(
uint256(
keccak256(
abi.encodePacked(
hex'ff',
factory,
keccak256(abi.encode(key.token0, key.token1, key.fee)),
POOL_INIT_CODE_HASH
)
)
)
);
优点
-
可以在链下计算出已经创建的交易池的地址 -
其他合约不必通过 UniswapV3Factory 中的接口来查询交易池的地址,可以节省 gas -
合约地址不会因为reorg (区块重组、分叉) 而改变 -
如果一个合约自毁了,那么新合约未来可以再次部署到这个地址上 -
在未部署前可以提前获取合约地址
|