Account Initialization
Counterfactual account initialization
Users create keystore accounts by counterfactually initializing them offchain without making a keystore transaction. This process will be facilitated by wallet interfaces and parallels the creation of an Ethereum EOA by offline generation of an ECDSA keypair before use.
To counterfactually initialize a keystore account, users should choose an arbitrary bytes32 salt
and the desired bytes data
and bytes vkey
for the account. The account’s keystoreAddress
can then be computed as keccak256(salt, keccak256(data), keccak256(vkey))
.
To understand how this works, recall that the keystore state is a mapping keystoreAddress -> (data, vkey)
, where vkey
is the verification key for a circuit governing the update rules for keystoreAddress
while data
represents arbitrary input interpreted according to the logic specified by the vkey
. Together, (data, vkey)
represent the authentication data that encapsulates the update rule for the state at keystoreAddress
. To support counterfactual initialization, the keystore interprets the state in two ways:
- If the keystore account at
keystoreAddress
is not initialized, the authentication data(data, vkey)
with the ability to updatekeystoreAddress
is interpreted as(initData, initVkey)
wherekeccak256(salt, keccak256(initData), keccak256(initVkey)) == keystoreAddress
andsalt
is the 32-byte salt used to initialize the keystore account. - Otherwise, the authentication data is simply the
(data, vkey)
atkeystoreAddress
in the keystore state.
Example Account Initialization
We will give an example of how to generate a keystore address and signing data for a 1-of-2 ECDSA multisig. The vkey
we will use is a verification key for a ZK proof which verifies that at least 1 signer from a group of 2 has produced an ECDSA signature. This vkey
expects the structure of data
to be:
Let’s unpack the inputs there.
0x00
andcodehash
are for compatibility with the Keystore Validator.threshold
is the number of signers that must sign a message for it to be valid.signers
is the list of allowed signers (associated with thekeystoreAddress
).
We will use the following values:
codehash
=0x0b2f6abb18102fa8a316ceda8a3f73b5eab33bb790d5bd92ff3995a9364adf97
threshold
=1
signers
=[0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266, 0x70997970C51812dc3A010C7d01b50e0d17dc79C8]
The hash of our vkey
is 0xa53fe8d9f71ced9b27711b393df4d425ea68ee941b625a1c4cbcbd773811d8df
.
The salt we will use is 0x000000000000000000000000000000000000000000000000000000001a1c6a5e
.
So then we have our counterfactual keystoreAddress
as
which is 0xa1ac2bbfda5f73c7c4bbafc08f0629040d2941c69e70243b22d7ed5384c5dd74
.
In the next section, we discuss using a keystore account on an L2 smart contract wallet.