UserOperation InitCode
The initCode field on a UserOperation encodes instructions on how to deploy the sender's smart account on-chain.
In the last section on UserOperation Sender we discussed the rationale of using factories to deploy a smart account to the sender
address. In this part, we discuss how this is done within the ERC-4337 standard through the User Operation initCode
.
Creating the initCode
initCode
The User Operation initCode
is simply a hex concatenation of two values:
- The factory address.
- The encoded call data to send to the factory.
In practice, using SimpleAccount.sol as an example:
const initCode = ethers.utils.hexConcat([
factory.address,
factory.interface.encodeFunctionData("createAccount", [
await instance.signer.getAddress(),
ethers.BigNumber.from(0),
]),
]);
From initCode
to deployed smart account
initCode
to deployed smart accountIf this is the user's first transaction and there is no code
located at the sender
address, the EntryPoint will use the User Operation initCode
to send the encoded call data to the factory contract.
To continue the SimpleAccount
example, the above initCode
will execute the function createAccount
on the SimpleAccountFactory.
function createAccount(address owner,uint256 salt) public returns (SimpleAccount ret) {
address addr = getAddress(owner, salt);
uint codeSize = addr.code.length;
if (codeSize > 0) {
return SimpleAccount(payable(addr));
}
ret = SimpleAccount(payable(new ERC1967Proxy{salt : bytes32(salt)}(
address(accountImplementation),
abi.encodeCall(SimpleAccount.initialize, (owner))
)));
}
Assuming no errors, the function returns a newly deployed SimpleAccount
with the exact same address as the User Operation sender
.
Updated about 1 year ago