Closed xJonathanLEI closed 1 year ago
Damn. I just wanted to jot some notes on the revamp plan but ended up writing an essay lol.
Spamming your inboxes since you guys contributed a lot to this library: @milancermak @fracek haha. Just FYI, can totally ignore, but feedbacks are welcome!
great initiative! not sure what kind of light can I shed but the address it's expected to be 0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf
when deployed from 0 with salt 0.
the verified code can be found on the above link, with the same interface as in the UDC Proposal. further documentation on usage, caveats, and design rationale is on the way.
@martriay Thanks! I was mainly wondering if the interface and address calculation behavior (mainly salt) will change cuz I will be hard-coding it inside the library, along with the address of latest UDC, so it might silently break users at runtime if the interface changes.
But hey, StarkNet itself still makes breaking changes all the time. Maybe at this point it doesn't matter lol. Or maybe a better approach is simply to not ship with an address.
the address is expected to stay, although any future changes to the code will result in a different one. interface changes are even less likely, but it will depend on the ecosystem. what we do in nile is to take an UDC address parameter with a default value for the standard one. this also allows users to use their own deployer contracts even if it's not the UDC
Yeah I figure I wasn't thinking straight and thought it might break people if the default address changes lol. It's actually the opposite: it breaks if users supply their own address and the UDC interface changes. All good now. Thanks!
I agree with this, I was going to suggest a trait for account deployers but I see you already defined it.
Introduction
A lot has changed regarding StarkNet contract deployment since we first implemented
ContractFactory
for deployment contracts:Declare
v0 was introduceddeploy
was added to deploy declared classesDeclare
v1 was introduced, with v0 deprecatedDeployAccount
was introduced, withDeploy
deprecatedSo, it's time for a revamp of the contract deployment process in
starknet-rs
to make it more streamlined and robust. Hopefully this document will serve to explain the design decision behind, and to help make things around StarkNet contract deployment clearer as they're kinda messy right now with everything (new & deprecated) floating around.How contract deployment works
Note that at the moment,
starknet-rs
is not interested in supporting deprecated features (since they will be removed after regenesis anyways). Raw data types for sendingDeploy
andDeclare
v0 transaction types will be kept until they're removed from the network itself, but higher-level constructs won't make use of them. Here we pretend all deprecated features are gone already.The contract deployment process consists of 2 steps:
Declaration
To deploy a contract, you first need to declare its class. The only way to do that is to send a
Declare
v1 transaction from an account contract. This is also the only step where you would need the full contract definition. You only need the class hash for the actual deployment.Deployment
This is the interesting part: there are actually 3 ways of deploying contracts:
deploy
syscall inside anInvoke
v1 transaction. However, this is equivalent toCREATE
in Ethereum, which is mostly none of an SDK's business.starknet-rs
. This needs to go through an account contract.DeployAccount
transaction type, where transaction fees are pre-funded to the target contract address. This will likely be the main way of account contract deployment going forward, so we definitely need to support it. This also needs to go through a (future) account contract.One side note here is that
DeployAccount
transactions can actually be used to deploy any contract. See my little experiment here. However, my current best guess here is that it's not supposed to be used that way. Unless that turns out to be wrong, I don't think we should support it. (Users will still be able to use it that way with the raw data types if they really want to)So it looks like every step to be supported in
starknet-rs
involves an account (withDeployAccount
it's actually a "future" account), which is nice as it makes things consistent.Designing a clean interface
This is just some very rough idea I have in mind. Issues or overlooked use cases might be found when actually implementing these.
Interfaces
Currently, contract declaration is implemented as part of the
Account
trait via thedeclare()
method, which takes aContractDefinition
type. I'm happy with how it works right now. So I'm not gonna touch this part for now, though I definitely want to change the return type into something wait-able and yield something that can be used for deployment directly (instead of the bareboneAddTransactionResult
we have now). But that's a separate task for the future.For deployment, I plan to replace the current
ContractFactory
type with 2 new types:ContractFactory
for deploying contracts through the Universal DeployerThis type will be a wrapper around:
Account
implementationAccountFactory
for deploying contracts through theDeployAccount
transaction typeThis type will be a wrapper around:
AccountDeploymentAdapter
(see rationale below) implementation that will provide calldata and signatureProvider
implementation that will actually send out the network requestBoth types should be able to get "prepared" into an intermediate type where users can adjust parameters like fees, like what you can do with
AttachedAccountCall
right now. Such an intermediate type should also provide an API for calculating the resulting contract address if deployed. This is very especially important forAccountFactory
since users will need to fund the address first.Design rationale
2 types are used instead of one, as they require different data when deploying. Using 2 types allows us to enforce more stuff at compile time.
They're named
ContractXxx
andAccountXxx
even though technically accounts are just contracts too. I think it's helpful for users to think of them differently anyways.We need the new trait
AccountDeploymentAdapter
since different account contract implementations (e.g. OZ vs ArgentX) will have different ways of:__validate_deploy__
entrypoint (OZ and ArgentX are the same on this but we need to be generic enough)starknet-rs
will implement this interface for both OZ and ArgentX so that these can work out of the box.