Solidity

如何預先計算部署的合約地址

  • March 15, 2022
// 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 程式碼部署的合約地址。

引用自:https://ethereum.stackexchange.com/questions/123864