[General] How to deploy contracts under reproducible addresses? #824
-
Team or ProjectDrips EnvironmentMainnet L2 block numberNo response Provide a brief description of the functionality you're trying to implement and the issue you are running into.I need a stable address derivation scheme, so on EVM I would deploy the logic contract and then CREATE2 clones of them, which gives me a known derivation path. On zkSync I can't use clones, but I can cheaply re-deploy an existing contract to a new address, which is comparably good. I do it by obtaining the codehash of the "master copy" of the contract and then by passing it to ContractDeployer.create2. It works fine, but in the Foundry tests context it only works in the top-level tests contracts. Invoking this routine from any other contract causes the This method require system call flag error. I couldn't find anything about the system call flag in the docs or in the help channels. What is this and how to work this issue around? Is my Foundry tests contract a system contract? Repo Link (Optional)No response Additional DetailsNo response |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 11 replies
-
In ZKsync, the deployment of contracts, especially using the Here are a few points to consider and steps you might take to resolve this issue:
This approach should help you address the specific error and continue with your contract deployment strategy on ZKsync. Your feedback helps us serve you better. If this fully addresses your question, please give it a thumbs up. If it doesn't, please give it a thumbs down. This will inform the community and team so we can improve our support. |
Beta Was this translation helpful? Give feedback.
-
How do I achieve that? |
Beta Was this translation helpful? Give feedback.
-
I asked one of our protocol engineers 👇 : By default zksolc compiler has the same behavior as EVM. However to enable zksync-specific features we use so called "eravm extensions". You can read more about them there. These are special features of our compiler, which roughly look like that: if you use a constant address inside the yul call (and the constant is one from the list here , then yes a special opcode will be invoked). Note, that not all opcodes are available for users for the sake of security, but some are. E.g. this is how EfficientCall library works. For security reasons these extensions are disabled by default, to enable them, you need to provide a special flag to our compiler. An example for foundry zksync. To sum it up:
|
Beta Was this translation helpful? Give feedback.
Hopefully this min-example provides additional clarity when working with factory contracts.
In that min-example:
Parent Deployment Without Child Bytecode:
In the example, the
ChildFactory
contract (the parent) is deployed first, but we do not attach the child's bytecode to the factory at this stage. The factory constructor only stores the known bytecode hash, not the full bytecode itself.First Child Deployment (Providing Bytecode):
When we run the
DeployChild
script, you see that only at the moment we callfactory.deployChild(...)
for the first time we usevmExt.zkUseFactoryDep("Child")
. This command includes the child's bytecode in the transaction.Afterward, Only the Hash Is Needed: