Get Account Address

Learn the foundational concepts of the CREATE2 opcode and how smart contract wallets generate counterfactual addresses.

The address of ERC-4337 smart accounts are deterministic. This allows you to find the address off-chain, and even send funds to accounts before the account is deployed.


Want an example?

If you want to see a simple script for creating an account address, check out this account address example.

Calculating an address

The CREATE2 opcode is used to create deterministic smart account addresses. A contract address is determined by a fromAddress, salt, and initCodeHash.

const accountAddress = ethers.utils.getCreate2Address(


The fromAddress is the address of the Singleton Factory. This factory receives the salt and initCode as input and uses CREATE2 to deploy the contract on-chain.

Because the factory address is the same on every chain, we can rely on it to also deploy our smart contract code on all networks under the same address too.


For an ERC-4337 account, the salt parameter is the first nonce value. This is 0.


The initCode, which is also a field on the UserOperation, is the smart contract code and arguments used for initializing it. It is hashed using keccak256 to derive the initCodeHash.

Deterministic addresses

With EOAs, the address is consistent across all EVM networks. As long as a user has access to the private key they can access the same address on any network. Ideally we would also like to create the same user experience with contract accounts too.

A user should be able to deterministically know their account address and keep it consistent on every EVM network irrespective of whether the code has been deployed or not. This means they can generate an account and start sending funds to it with full assurance that they'll be able to control those funds at any time given they have the correct verification method.

ERC-4337 does this by using the CREATE2 opcode through a Singleton Factory. Let's break this down to understand what that means in practice.