Create2.sol 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. pragma solidity ^0.5.0;
  2. /**
  3. * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.
  4. * `CREATE2` can be used to compute in advance the address where a smart
  5. * contract will be deployed, which allows for interesting new mechanisms known
  6. * as 'counterfactual interactions'.
  7. *
  8. * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more
  9. * information.
  10. */
  11. library Create2 {
  12. /**
  13. * @dev Deploys a contract using `CREATE2`. The address where the contract
  14. * will be deployed can be known in advance via {computeAddress}. Note that
  15. * a contract cannot be deployed twice using the same salt.
  16. */
  17. function deploy(bytes32 salt, bytes memory bytecode) internal returns (address) {
  18. address addr;
  19. // solhint-disable-next-line no-inline-assembly
  20. assembly {
  21. addr := create2(0, add(bytecode, 0x20), mload(bytecode), salt)
  22. }
  23. require(addr != address(0), "Create2: Failed on deploy");
  24. return addr;
  25. }
  26. /**
  27. * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the `bytecode`
  28. * or `salt` will result in a new destination address.
  29. */
  30. function computeAddress(bytes32 salt, bytes memory bytecode) internal view returns (address) {
  31. return computeAddress(salt, bytecode, address(this));
  32. }
  33. /**
  34. * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
  35. * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
  36. */
  37. function computeAddress(bytes32 salt, bytes memory bytecodeHash, address deployer) internal pure returns (address) {
  38. bytes32 bytecodeHashHash = keccak256(bytecodeHash);
  39. bytes32 _data = keccak256(
  40. abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHashHash)
  41. );
  42. return address(bytes20(_data << 96));
  43. }
  44. }