The proxy can’t just “deploy it for him” after StarkNet introduces fees (very soon?) though. The user would have to pay, one way or another. This can be implemented as an L1 (not necessarily Ethereum!) service that can be used with a Web3 wallet.
I imagine SN dApps would check for account contract deployment first for users using these wallets, and if not found, instruct them to use such a service.
This is looking good! If I understand correctly, this design requires almost no changes on our current Account contract implementation aside from using Ethereum’s ecdsa, right?
Since this is definitely a hard UX problem for many parties: users, wallet developers, and frontend/dapp developers; I’d like to address a few UX issues we might face:
This solution definitely works. But a big problem for users is going to be the split between “their address” (what they see in metamask, the EOA) and their account contract address. This could open the door for user mistakes such as sending/receiving tokens to EOA addresses instead of account addresses).
Another common error is to send tokens to the right address on the wrong network (e.g. send to polygon instead of eth mainnet). With the EOA/account contract address split, funds sent to the right user on the wrong network could result in loss of funds.
It would also be very confusing for users to understand the difference between these addresses (which they will definitely encounter in different places such as web dapps, Metamask, tx metadata, etc) and this confusion could be also exploited by attackers. This is also highlighted on the getBalance/send ERC20 section of the OP.
To minimize risk, reduce cognitive overhead for users, and simplify overall adapters, I’d like to suggest adding a special CREATE opcode to deploy accounts to an EOA-derived address. Without taking into account contract code, salts, etc. Only proving EOA ownership once. This way, if you own an ethereum private key that controls a given EOA, you can deploy an account contract to the same address. This should be feasible since ethereum addresses are 20bytes long, smaller thus representable in Starknet’s >31bytes.
There’s also the issue of how tx metadata is shown to the user, since every tx is in a way a meta-transaction (all txs are redundantly calling execute on the same account contract, always). Solving this issue will probably require wallet-side development.
I think we should leverage wallet-side nonce management. The RPC endpoint could expose a method for getting the nonce of a given account, then use that to build the transaction. Did you have anything in mind regarding this?
When should account be created? Who’s going to pay for it? Maybe this is something the dapps could cover, but it still bears the UX issue of requiring users to sign an account creation transaction, which will not always be obvious/easy to explain. I think we should think about this flow too.
I love the idea and would vote for it. Notice that we could also have this for StarkKeys as it would enable stateless wallets like Ledger to be aware of their own address.
The main concern is what happens if a contract has already been deployed at the said address.
Should we overwrite the contract or not? We have an idea to solve it using a proxy that can then changes its instantiation without needing to overwrite the said contract
Yes I was also thinking that deploying proxies could be an option, but I’d leave the CREATE opcode as a one-off thing, meaning it would only work once. I wouldn’t impose “account addresses” to be proxies either, although it will probably be the most common thing.
Hmm although I don’t think user onboarding should be handled by the RPC, it’s true that someone, whoever is onboarding the user, has the power to influence what account contract will be associated to the user’s keys.
So it makes sense to have an upgradeable proxy associated to a pair of ethereum keys for the reasons stated above, but there’s the problem of some party (e.g. uniswap, coinbase, infura) choosing your account contract for life. I’m buying into forcing that this CREATE method instantiates a proxy, to protect users from tying themselves to a given contract unknowingly.
Yes, and storing the Ethereum address in the contract.
We are considering this approach, which I agree provides better UX, with the proxy as was discussed above. However, this requires changes to the SN OS, which should be considered carefully and will add development time and delay the web3 wallet’s support. We can start with the described approach at first in order to do this faster and consider adding this as second phase.
Again, I agree with you, this is an important issue. We thought of using EIP-712, just trying to figure out if this is a standard supported by most wallets? but even using this, the user will only be able to see the destination address and selector of the meta transaction and not the full parsing of the calldata.
One thing that needs to be implemented if we use EIP712 is that we still need to mimic an RPC change if we want to keep the same “changing network approach” that all other chains use.
Not a blocking thing just something to have in mind
Got it, makes sense. I assume that most people wouldn’t want to pay L1 gas, even though it’s better trust-wise. So probably the second way would be more popular. A third option is that applications would subsidize the deployment in order to onboard users and potentially profit later. Anyway this service is still required.
In that case it would really help if there’s a de facto (maybe even official/semi-official) account contract factory on SN that dApps can just invoke to deploy a certain type of account contract, instead of having dApps deploy directly.
I mean you can’t really stop dApps from going with raw deploy, but at least there should be a widely accepted option for those who want to do things right.
This is exactly why I think that if we go with a special CREATE opcode for EOAs, the default should be a proxy. Otherwise the dapp would have final influence on the user’s account contract and we shouldn’t assume the users will always be aware of this. The best protection is to force proxy deployments on these contracts (and if the user wants to opt-out from proxies, they can just upgrade to a non-upgradeable one).
Agreed. I think it makes sense to have one default implementation that all accounts deployed thru the factory are forced to use. Users can then opt in to upgrade to other implementations (or remove upgradeability to become immutable).
This is just like how in L1 you have a “default” account implementation (EOA with ECDSA), except you can’t opt out of it on L1.