matter-labs / foundry-zksync

Fork of Foundry tailored for zkSync environment
Apache License 2.0
302 stars 130 forks source link

feature request: being able to save/load bytecode + hash without relying on `.zkout` directory #715

Closed oveddan closed 2 weeks ago

oveddan commented 2 weeks ago

Component

Forge

Have you ensured that all of these are up to date?

What version of Foundry are you on?

forge 0.0.2 (953a180 2024-11-05T00:24:47.804587000Z)

What command(s) is the bug in?

forge script --zksync

Operating System

None

Describe the bug

I'm having an issue when deterministically deploying a contract using zksync.

Here is my script:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Script.sol";
import {ZkImmutableCreate2Factory, IContractDeployer, ZK_IMMUTABLE_CREATE2_FACTORY_SALT, L2ContractHelper} from "@zoralabs/shared-contracts/deployment/ZkImmutableCreate2Factory.sol";

contract DeployImmutableCreate2FactoryZkScript is Script {
    function run() external {
        vm.startBroadcast();

        bytes32 hash = 0x01000089c6e02a1540447967ce42eaffd4be394a7e6f444965bae41f129f6d4b;

        IContractDeployer contractDeployer = IContractDeployer(0x0000000000000000000000000000000000008006);
        address deploymentAddress = contractDeployer.create2(ZK_IMMUTABLE_CREATE2_FACTORY_SALT, hash, "");

        console.log("Deployment address:", deploymentAddress);

        vm.stopBroadcast();
    }
}

To get the hash, I went to zkout/ZkImmutableCreate2Factory/ZkImmutableCreate2Factory.json and grabbed the hash value, and copied and pasted it into the script above.

When I run the script I get the error "script failed: revert: The code hash is not known"

However, in general I want to be able to save the bytecode and bytecode hash, so that in future versions of my code, lets say the foundry version changes and compilation changes, I can load the original bytecode and hash so that I can deploy deterministically to another chain at the same address without working about a recompilation changing the bytecode.

How does foundry zksync look for matching bytecode for a hash? is there a way to pass it in manually so that it doesn't have to rely on compiled contracts in zkout?

oveddan commented 2 weeks ago

ok nevermind i figured out what my issue is! the contract with that bytecode hash must be already deployed before using its hash to deploy deterministically. pretty cool :)

Karrq commented 2 weeks ago

Hey @oveddan, glad you found a solution, but I think you'd be interested in knowing that you could still do this type of deployment directly from within foundry, without needing the contract to be already deployed (1) or fetching the bytecode hash manually (2).

For issue number 1, you can use zkUseFactoryDep cheatcode, by specifying the hash of the contract to be deployed. Meanwhile, for issue number 2, you could either use getCode to retrieve the bytecode hash and hash it afterwards, or use readFile & parseJsonBytes to retrieve the bytecodeHash from the artifact, like what you did initially, but this one will always have the right hash even across different compilations ;)


While writing this, I noticed that you are attempting to do a CREATE2 deployment, in that case you could just simply use new ZkImmutableCreate2Factory{salt: ZK_IMMUTABLE_CREATE2_FACTORY_SALT}();, this will use the Create2Factory present on ZKsync Era for your deployment (which essentially does the same thing as the contract deployer)

Hope that improves your experience using foundry-zksync! :)