Open this lesson in your favourite AI. It'll walk you through the why, explain the demo, and quiz you on the try-it list.
CREATE deterministically derives a contract address from sender + nonce — useful but unpredictable across networks since nonce depends on prior history. CREATE2 derives the address from sender + salt + init_code_hash, which means you can deploy the SAME address on every chain or deposit funds to a contract that doesn't yet exist. This single capability underpins counterfactual wallets, AA, and most cross-chain deterministic deployments.
Derive a CREATE2 address before deploying the contract.
Use these three in order. Each builds on the one before.
In one paragraph, explain CREATE vs CREATE2 — what each derives addresses from.
Walk me through the address derivation for CREATE2 — the 0xff prefix, the salt, and why this gives counterfactual deployment.
Given an ERC-4337 wallet that doesn't exist yet, explain how a user can receive funds and then later deploy the wallet using CREATE2 to claim them.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Factory {
function predict(bytes32 salt, bytes memory initCode) external view returns (address) {
return address(uint160(uint256(keccak256(abi.encodePacked(
bytes1(0xff),
address(this),
salt,
keccak256(initCode)
)))));
}
function deploy(bytes32 salt, bytes memory initCode) external returns (address addr) {
assembly {
addr := create2(0, add(initCode, 0x20), mload(initCode), salt)
}
require(addr != address(0), "CREATE2 failed");
}
}