Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deployment and verification abstraction #781

Closed
wants to merge 8 commits into from
Closed

Deployment and verification abstraction #781

wants to merge 8 commits into from

Conversation

JacobHomanics
Copy link
Contributor

Rationale

In a personal project, I faced a challenge and experienced confusion and errors when I needed more than just the Deploy.s.sol script, and made a DeployDemo.s.sol script. However there were a large number of changes to my project that I needed to do.

Original Process:

  1. Copy and rename the yarn commands deploy, deploy:verify, and verify yarn commands to deployDemo, deployDemo:verify, and verifyDeployDemo.
  2. Update the references in the the new yarn commands from Deploy.s.sol to DeployDemo.s.sol.
  3. Duplicate and rename the file generateTsAbis.ts to generateTsAbis_Demo.ts.
  4. Duplicate and rename the file VerifyAll.s.sol to VerifyAll_Demo.s.sol.
  5. Update the references in generateTsAbi_Demo.ts from Deploy.s.sol to DeployDemo.s.sol.
  6. Update the references in VerifyAll_Demo.ts from Deploy.s.sol to DeployDemo.s.sol.
  7. Return to the new yarn commands and change all references of generateTsAbis.ts to generateTsAbis_Demo.ts and VerifyAll.s.sol to VerifyAll_Demo.s.sol.

New Process

  1. Copy and rename the yarn commands deploy, deploy:verify, and verify yarn commands to deployDemo, deployDemo:verify, and verifyDeployDemo.
  2. Update the references in the the new yarn commands from Deploy.s.sol to DeployDemo.s.sol.

Description

Simplifies the process of creating and running additional deploy scripts and verifications.

Additional Information

Your ENS/address: JacobHomanics.eth

@technophile-04
Copy link
Collaborator

Hey thanks @Hotmanics, as I assume in general people might use multiple deploy scripts for deploying different contracts with different scripts.

For example, two contracts YourContract.sol, MyContract.sol and their corresponding deploy scripts Deploy.s.sol, DeployMyContract.s.sol respectively.

With your changes I copy-pasted script and created deployMyContract, So I would run:

  1. yarn deploy: To deploy YourContract.sol
  2. yarn deployMyContract: To deploy MyContract.sol

But the problem with this approach is that it ovverrides abi's generated in deployedContracts.ts and keep only MyContract (since it was run last).


I think a better approach if people wants to have multiple files of different contract is to maybe do something like this :

Deploy.s.sol => For handling general deployment and calling exportDeployments() function
DeployYourContract.sol => Only for deploying YourContract.sol
DeployMyContract.sol => Only for deploying MyContract.sol

Deploy.s.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "./DeployHelpers.s.sol";
import "./DeployYourContract.sol";
import "./DeployMyContract.s.sol";

contract DeployScript is ScaffoldETHDeploy {
    error InvalidPrivateKey(string);

    function run() external {
        DeployYourContract yourContractScript = new DeployYourContract();
        yourContractScript.run();

        DeployMyContractScript myContractScript = new DeployMyContractScript();
        myContractScript.run();

        /**
         * This function generates the file containing the contracts Abi definitions.
         * These definitions are used to derive the types needed in the custom scaffold-eth hooks, for example.
         * This function should be called last.
         */
        exportDeployments();
    }

    function test() public {}
}
DeployYourContract.s.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "../contracts/YourContract.sol";
import "./DeployHelpers.s.sol";

contract DeployYourContract is ScaffoldETHDeploy {
    error InvalidPrivateKey(string);

    function run() external {
        uint256 deployerPrivateKey = setupLocalhostEnv();
        if (deployerPrivateKey == 0) {
            revert InvalidPrivateKey(
                "You don't have a deployer account. Make sure you have set DEPLOYER_PRIVATE_KEY in .env or use `yarn generate` to generate a new random account"
            );
        }
        vm.startBroadcast(deployerPrivateKey);
        YourContract yourContract = new YourContract(
            vm.addr(deployerPrivateKey)
        );
        console.logString(
            string.concat(
                "YourContract deployed at: ",
                vm.toString(address(yourContract))
            )
        );
        vm.stopBroadcast();
    }
}
DeployMyContract.s.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "../contracts/MyContract.sol";
import "./DeployHelpers.s.sol";

contract DeployMyContractScript is ScaffoldETHDeploy {
    error InvalidPrivateKey(string);

    function run() external {
        uint256 deployerPrivateKey = setupLocalhostEnv();
        if (deployerPrivateKey == 0) {
            revert InvalidPrivateKey(
                "You don't have a deployer account. Make sure you have set DEPLOYER_PRIVATE_KEY in .env or use `yarn generate` to generate a new random account"
            );
        }
        vm.startBroadcast(deployerPrivateKey);
        MyContract myContract = new MyContract(vm.addr(deployerPrivateKey));
        console.logString(
            string.concat(
                "MyContract deployed at: ",
                vm.toString(address(myContract))
            )
        );
        vm.stopBroadcast();
    }
}

This simplifies the process a lot, you just need to run yarn deploy and this will do the job of deploying both contracts nicely also nicely handling frontend export of abi's

Also now, if people want to just deploy YourContrac.sol they would just comment out 2 line (calling of MyContractScript) in Deploy.s.sol and this will only deploy YourContract.sol.

Also, maybe it's good idea to have this example default in SE-2 foundry repo with Deploy.s.sol & DeployYourContract.s.sol to push people in this direction instead of copy-pasting the scripts in package.json (cc @jrcarlos2000 for his views too 🙌)

Lol I am not very well versed with foundry and not sure if its really good pattern to follow, but we should create an issue / discussion first and discuss their 🙌

Closing this for now, but thanks so much !! for trying tackling it, lets brainstorm a bit and see if we can find a better soution 🙌

@jrcarlos2000
Copy link
Collaborator

Thanks for the good comment @technophile-04. This is one way to approach the issue, something that i see more in foundry would be using inheritance and internal functions that you can run from the main Deploy.s.sol thus you dont need to deploy an instance of deployMyContract & deployYourContract. However the underlying idea keeps the same : keeping all executions and exportDeployments() inside the main script.

The are some other ways to approach this too 🫡.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants