Skip to content

Instantly share code, notes, and snippets.

@DeviateFish
Created February 21, 2019 09:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DeviateFish/6241c6ab0c8cfc9221d3a40f3e0cd9ba to your computer and use it in GitHub Desktop.
Save DeviateFish/6241c6ab0c8cfc9221d3a40f3e0cd9ba to your computer and use it in GitHub Desktop.
A "real" `create2` replacement.
pragma solidity >=0.4.22 <0.5.0;
// Machine.sol
/// @title A widget
contract Machine {
// This is our contract that does stuff. We'll be committing to deploying this contract in the future.
// At this point, this only exists to be compiled for our init code
bytes32 secret;
constructor(bytes32 _secret) public {
secret = _secret;
}
function legit() public view returns(bytes32) {
return secret;
}
function loaded() public view returns(uint256) {
return address(this).balance;
}
}
// init_code:
// 0x608060405234801561001057600080fd5b506040516020806101478339810180604052810190808051906020019092919050505080600081600019169055505060fa8061004d6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063196e045d14604e57806331cb3e48146076575b600080fd5b348015605957600080fd5b50606060a6565b6040518082815260200191505060405180910390f35b348015608157600080fd5b50608860c5565b60405180826000191660001916815260200191505060405180910390f35b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600080549050905600a165627a7a72305820218e7c306082a003a9df8b5201000d276868b2bbdb01f9ea192736b1cb45b2520029eff4e33d28bea8798db60d81c90b51de39ef00ddbf7cbd0522a79790c1435330
// code hash:
// 0xa831b55fc59fa950cc4c7a3233e6a723f5066e9e2a1711d2f40652d01aed6b4d
// secret will be:
// 0xeff4e33d28bea8798db60d81c90b51de39ef00ddbf7cbd0522a79790c1435330
// Create2.sol
/// @title A commitment to future code at deterministic addresses
contract Create2 {
bytes32 codeHash;
constructor(bytes32 _codeHash) public {
codeHash = _codeHash;
}
function committedAddress() public view returns(address) {
return address(keccak256(uint8(0xd6), uint8(0x94), address(this), uint8(0x01)));
}
function commit(bytes code) public payable {
// require that this be the committed code.
require(keccak256(code) == codeHash);
address futureAddress = committedAddress();
if (msg.value > 0) {
futureAddress.transfer(msg.value);
}
address newContract;
assembly {
newContract := create(0, add(code, 0x20), mload(code))
let codeSize := extcodesize(newContract)
if eq(codeSize, 0) { revert(0, 0) }
}
selfdestruct(msg.sender);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment