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

feat: cheatcode to get recent deployments by contract name #4732

Open
mds1 opened this issue Apr 13, 2023 · 7 comments
Open

feat: cheatcode to get recent deployments by contract name #4732

mds1 opened this issue Apr 13, 2023 · 7 comments
Labels
A-cheatcodes Area: cheatcodes Cmd-forge-script Command: forge script T-feature Type: feature
Milestone

Comments

@mds1
Copy link
Collaborator

mds1 commented Apr 13, 2023

Component

Forge

Describe the feature you would like

Add new methods that parse JSON files in the broadcast folder to find contract addresses.

// Returns the most recent deployment for the given contract on `chainId`
function getDeployment(string memory contractName, uint256 chainId) external returns (address);

// Returns the deployment given by `index` for the given contract on `chainId`,
// where index=0 is the first (oldest) deploy, index=1 is the second deploy,
// and index=`type(uint256).max` is the most recent deploy
function getDeployment(string memory contractName, uint256 chainId, uint256 index) external returns (address);

// Returns all deployments for the given contract on `chainId`
function getDeployments(string memory contractName, uint256 chainId) external returns (address[] memory);

// Returns deployments by index for the given contract on `chainId`.
// If the start index is `type(uint256).max`, the end index counts
// backwards to return the most recent contracts. End index is exclusive,
// similar to how most slice methods behave
function getDeployments(string memory contractName, uint256 chainId, uint256 startIndex, uint256 endIndex) external returns (address[] memory);

cc @PatrickAlphaC @karmacoma-eth for thoughts on syntax/UX/cheat names/etc

Additional context

No response

@PatrickAlphaC
Copy link

Would be cool to also add something like hardhat-deploy where I can run:

anvil --deploy

and it runs through a deploy script when you start up anvil. Much easier than having to roll your own makefile for UI stuff

@mds1
Copy link
Collaborator Author

mds1 commented Apr 13, 2023

I'm not sure if we have an issue for this, but a related idea I've had was: when running a forge script, if the RPC URL is localhost, instead of treating cheatcode calls like normal (i.e. they won't work, since they're forge vm specific) automatically change them to be the special RPC calls to the anvil node

@devanoneth
Copy link
Contributor

devanoneth commented May 11, 2023

As mentioned in this twitter thread: https://twitter.com/jj_ranalli/status/1656384664020434949

It would be nice to be able to pull in known deployments, as contract instances, from dependencies so we can easily interact with them in scripts.

For example, assuming we have run forge install someproject/somecoin, we can then easily access the deployed "somecoin" on chain 1 with scripts in our own project as follows:

import "forge-std/Script.sol";
import {Deployments} from "somecoin/deployed/1/Deployments.sol";

contract MyScript is Script {
    function run() public {
        vm.startBroadcast(me);

        Deployments.somecoin.transfer(to, 1 ether);

        vm.stopBroadcast();
    }
}

or maybe this is better?

import "forge-std/Script.sol";
import {Deployments} from "somecoin/deployed/1/Deployments.sol";

contract MyScript is Script, Deployments {
    function run() public {
        vm.startBroadcast(me);

        somecoin.transfer(to, 1 ether);

        vm.stopBroadcast();
    }
}

My proposal would be that we add a new command e.g. forge bind-sol (and then maybe rename forge bind to forge bind-rs) or maybe a flag on forge script? Or a better name altogether? :D

Regardless, this command would create a file such as src/deployed/<chainId>/Deployments.sol based on the most recent broadcast run, exposing contract instances ready to be invoked by scripts.

Happy to hear thoughts on this as an alternative to this design, or as a separate feature completely (because I also like the general idea here from @mds1).

@mds1
Copy link
Collaborator Author

mds1 commented May 12, 2023

That's also a nice UX, I. like the idea. It does feel like being able to pull in deployments/ABIs from dependencies like that is very related to package management ideas that @fubuloubu and @brockelmore have discussed (which I'm not too familiar with, so I have no summary or other info to share)

@jjranalli
Copy link

jjranalli commented May 12, 2023

Chiming in here to add some thoughts on @devanoneth suggestion, originally shared in the twitter post.

I think it would be desirable to have deployments auto-generation:

  • opt-in (for example with a forge script flag as suggested)
  • configurable on a folder/contract basis (to pick which contracts to store deployments for)
  • so that scripts and tests can easily import them based on chain
    • ideally even allow leaving a script unchanged regardless of chain used, by picking correct deployments based on --chain-id and reverting if they don't exist.

I also like @mds1 proposed feature btw. Would be nice to have both, as they can be useful in different circumstances.

@nzjrs
Copy link

nzjrs commented Oct 29, 2023

I feel like #3911 is too big an issue to ever be completed. But adding at least the API suggested above would allow users or foundary to iterate on solutions, solutions that could therefor be used as a specification to finish #3911

AFAICT it would also need a vm.getChainId() or some other way to lookup the currect chainID for the current connected RPC - That way, a forge script could know everything it needed from its execution context and not need any other command line args or env vars passed in, than those which are needed for the deployment of a given contract.

@drinkius
Copy link

If it still makes sense to introduce this change maybe I can take on a challenge. Seems like a useful util to improve scripts UX

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-cheatcodes Area: cheatcodes Cmd-forge-script Command: forge script T-feature Type: feature
Projects
Status: Todo
Development

No branches or pull requests

7 participants