freecoding.school100% FREE · NO SIGNUP
The EVM CoreISSUE #18 of 48

create vs create2 · deterministic addresses

SoliaVSThe Reentrancy Reaper
Solia saysCREATE derives a contract’s address from sender + nonce; CREATE2 derives it from sender + salt + init-code hash — letting you compute the address before deployment.

CREATE assigns keccak256(rlp(sender, nonce))[-20:] as the address, which changes every time the sender deploys (nonce increments). CREATE2 uses keccak256(0xff ‖ sender ‖ salt ‖ keccak256(initcode))[-20:] — fully deterministic in sender, salt, and code, regardless of nonce. That means you can compute a contract address before it is deployed.

This unlocks two patterns: counterfactual contracts (people interact with an address before it exists, and the contract is deployed when needed) and salt-mined vanity addresses. The demo computes both with a toy hash; the determinism property holds the same way under real keccak256.

Power-ups you unlock

The Reentrancy Reaper attacks — common mistakes

Boss battleCompute CREATE and CREATE2 addresses for the same sender and show CREATE2 stays the same across redeploys.

Example code

<!doctype html><html><head><meta charset="utf-8"></head>
<body style="background:#06040d;color:#e6e0ff;font-family:monospace;padding:20px"><pre id="o"></pre>
<script>
// toy hash for runnable demo; real EVM uses keccak256.  the DETERMINISM property holds the same way.
const H = (s) => { let h=2166136261>>>0; for(const c of s){ h^=c.charCodeAt(0); h=Math.imul(h,16777619); } return (h>>>0).toString(16).padStart(8,'0'); };
const createAddr  = (sender, nonce)              => '0x' + H('rlp:' + sender + ':' + nonce);
const create2Addr = (sender, salt, initcode)     => '0x' + H('ff:' + sender + ':' + salt + ':' + H(initcode));
const sender = '0xAlice';
const c0 = createAddr(sender, 0);
const c1 = createAddr(sender, 1);
const cc1 = create2Addr(sender, 'salt-123', 'contract-bytecode');
const cc2 = create2Addr(sender, 'salt-123', 'contract-bytecode');
const cc3 = create2Addr(sender, 'salt-XYZ', 'contract-bytecode');
document.getElementById('o').textContent = [
  'CREATE (nonce-dependent):',
  '  sender=' + sender + ' nonce=0 → ' + c0,
  '  sender=' + sender + ' nonce=1 → ' + c1 + '   (different — nonce changed)',
  '',
  'CREATE2 (deterministic in salt + initcode):',
  '  sender=' + sender + ' salt=salt-123 → ' + cc1,
  '  same inputs again            → ' + cc2 + '   (' + (cc1 === cc2 ? 'identical ✓' : 'different ✗') + ')',
  '  different salt               → ' + cc3 + '   (different)',
  '',
  '→ unlocks counterfactual contracts and vanity-address mining'
].join('\n');
</script></body></html>
▶ Open the interactive comic issue
‹ Precompiles · Ecrecover · Modexp · PairingsDelegatecall · Context Preservation ›