Solidity
如何預先計算部署的合約地址
// SPDX-License-Identifier: MIT pragma solidity ^0.5.16; import "https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Pair.sol"; contract TestERC20 { address public _pair = address(0); constructor() public { } function getPreAddress() public view returns ( address, address ) { address factory = address(this); address token0 = 0xCAFE000000000000000000000000000000000000; // change me! address token1 = 0xF00D000000000000000000000000000000000000; // change me! address pair = address(uint(keccak256(abi.encodePacked( hex'ff', factory, keccak256(abi.encodePacked(token0, token1)), hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' )))); return (pair, _pair); } function createPair() public { require(_pair == address(0), 'Pair already created'); address token0 = 0xCAFE000000000000000000000000000000000000; // change me! address token1 = 0xF00D000000000000000000000000000000000000; // change me! bytes memory bytecode = type(UniswapV2Pair).creationCode; bytes32 salt = keccak256(abi.encodePacked(token0, token1)); address dep; assembly { dep := create2(0, add(bytecode, 32), mload(bytecode), salt) } _pair = dep; } }
我嘗試部署 UniswapV2Pair 合約並比較計算的地址和部署的地址。
不幸的是,兩個地址不同。
創建 pair by 後
createPair()
,getPreAddress()
返回不同的兩個地址。如何創建配對並預先獲取配對地址?
address pair = address(uint(keccak256(abi.encodePacked( hex'ff', factory, keccak256(abi.encodePacked(token0, token1)), keccak256(type(UniswapV2Pair).creationCode) // hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' ))));
請像這樣更新程式碼。
function getCreate2Address( factoryAddress, [tokenA, tokenB], bytecode ) { const [token0, token1] = tokenA < tokenB ? [tokenA, tokenB] : [tokenB, tokenA] const create2Inputs = [ '0xff', factoryAddress, keccak256(solidityPack(['address', 'address'], [token0, token1])), keccak256(bytecode) ] const sanitizedInputs = `0x${create2Inputs.map(i => i.slice(2)).join('')}` return getAddress(`0x${keccak256(sanitizedInputs).slice(-40)}`) }
可以計算出部署的合約地址。
這是一個 JavaScript JavaScript 函式,用於計算 create2 程式碼部署的合約地址。