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

foundry: separate out your contract deployments #898

Merged
merged 4 commits into from
Aug 1, 2024

Conversation

technophile-04
Copy link
Collaborator

Description:

Separate your contract deploy script from so that we enforce people to follow a pattern.

The reason we need to enforce this pattern is because exportDeployments() should be called only once and too after all the deployments are done.

So basically Deploy.s.sol file is the main file which import different deploy script of different contracts and in the end it calls the exportDeployments() which creates all the necessary files for generateTsAbi.js fucntion.

Checkout second part of this for more details : #781 (comment)

CC @jrcarlos2000 feel free suggest some cleanups / better practices in foundry.

Some notes:

@jrcarlos2000
Copy link
Collaborator

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

import { YourContract } from "../contracts/YourContract.sol";
import { ScaffoldETHDeploy, console } from "./DeployHelpers.s.sol";

contract DeployScript is ScaffoldETHDeploy {
  error InvalidPrivateKey(string);

  modifier deploymentExporter() {
    _;
    exportDeployments();
  }

  function run() external deploymentExporter {
    address deployer = _startBroadcast();
    YourContract yourContract = new YourContract(deployer);
    console.logString(
      string.concat(
        "YourContract deployed at: ", vm.toString(address(yourContract))
      )
    );
    _stopBroadcast();
  }

  function test() public { }
}

we can avoid having users explicitly calling exportDeployments() by using this modifier which will execute after function run()

@jrcarlos2000
Copy link
Collaborator

another way could be having abstract contract for each deploy script.
we can share the deployments array for named contracts, for example when deploying multiple instances of a same contract so that we can export all of them with different names. This is currently available and is useful, hardhat used to have a similar functionality.

  • Deploy script 1
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

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

abstract contract DeployYourContract is ScaffoldETHDeploy {
  function run() public virtual {
    uint256 deployerPrivateKey = setupLocalhostEnv();
    vm.startBroadcast(deployerPrivateKey);

    YourContract yourContract = new YourContract(vm.addr(deployerPrivateKey));
    deployments.push(Deployment("YourContract0", address(yourContract)));
    console.logString(
      string.concat(
        "YourContract deployed at: ", vm.toString(address(yourContract))
      )
    );

    vm.stopBroadcast();
  }
}
  • Deploy script 2
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

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

abstract contract DeployYourContract1 is ScaffoldETHDeploy {
  function run() public virtual{
    uint256 deployerPrivateKey = setupLocalhostEnv();
    vm.startBroadcast(deployerPrivateKey);

    YourContract yourContract = new YourContract(vm.addr(deployerPrivateKey));
    deployments.push(Deployment("YourContract1", address(yourContract)));
    console.logString(
      string.concat(
        "YourContract deployed at: ", vm.toString(address(yourContract))
      )
    );

    vm.stopBroadcast();
  }
}
  • main deploy script
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { DeployYourContract } from "./00_deploy_your_contract.s.sol";
import { DeployYourContract1 } from "./01_deploy_your_contract.s.sol";

contract DeployScript is DeployYourContract, DeployYourContract1 {
  uint256 deployerPrivateKey;

  error InvalidPrivateKey(string);

  modifier scaffoldEthDeployer() {
    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"
      );
    }
    _;
    exportDeployments();
  }

  function run()
    public
    override(DeployYourContract, DeployYourContract1)
    scaffoldEthDeployer
  {
    DeployYourContract.run();
    DeployYourContract1.run();
  }
}

@jrcarlos2000
Copy link
Collaborator

another way could be having abstract contract for each deploy script.
we can share the deployments array for named contracts, for example when deploying multiple instances of a same contract so that we can export all of them with different names. This is currently available and is useful, hardhat used to have a similar functionality.

The current approach doesnt support this shared state of deployments for named contracts @technophile-04

@technophile-04
Copy link
Collaborator Author

Ohh I see, so with current approach people are not able to same contract(name) multiple times it gets override by most recent one?

I think we kind of the same problem with current setup of hardhat-deploy(where you are not able to keep track of contract with same names)

Yeah your approach makes sense! The only thing which I don't like is people in their own contract deploy script has to remember to do :

deployments.push(Deployment("YourContract1", address(yourContract)));

but yeah I am not sure what's other way to handle this either, something not that important for now but we should def tackle this in future! Thanks @jrcarlos2000 for all the suggestions!!

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.

2 participants