-
Notifications
You must be signed in to change notification settings - Fork 31
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
Make the deployment chain-aware, if possible #777
Comments
This is a great point. How should modules deal with differences between chains. |
I was thinking about some alternatives, all of them considering the premise: A single deployment of a module being against a single chain (and thus making specific additions to the journal, so the integrity / reproducibility / reconciliability of the journal remains a property of ignition, while also doing per-chain logic):
Later, I'll properly clone the repo and try some tweaks for either alternative (and, if able, I'll propose the changes in a PR). I'll keep you updated if I succeed. |
Although just a workaround, you can pass different parameters or even call different deploy scripts entirely from your CI, so you could have |
I was thinking about a small change in terms of code but big change in terms of what is publicly available (perhaps to make a minor or even major version change - not sure).
There are three places where the big deploy() core function is invoked:
1.
The CLI tool.
2.
hardhat-ignition-ethers' deploy() method.
3.
hardhat-ignition-viem's deploy() method.
When they invoke the core deploy method, they pass the instance of the module to deploy, along everything needed. And... they have access to the chainId as well. So what I thought is to:
1.
Normalize the chainId. This means: convert it to a base10-stringification of itself.
2.
If the module is an instance of IgnitionModule, the logic doesn't change at all: the core deploy will be invoked as of today.
3.
Otherwise, the module will be treated as, actually, a mapping. The keys must be:
*
One which we deem as default (e.g. "", "0" or "default") when the current normalized chainId is not set in the mapping. This stands for the general case and makes sense for local networks (31337).
*
Others which are base10 numbers of chain ids where things will go differently.
*
Then, retrieval is easy: const finalModule = (module instanceof IgnitionModule) ? module : (module[chainId.toString()] || module.default).
This is just an idea and I'm aware that most of you might not be that comfortable with allowing something like this, but at least as a concept could have the job done.
|
This is a great feature for us to keep our projects more organized. I would like to add about deployment parameters. For deploying a contract to different chains which has a dependency contract which has different addresses in different chains, I should add Hardhat Configuration Variables as follows: {
"mainnet": {
"Apollo": {
"name": "Saturn V"
}
},
"goerli": {
"Apollo": {
"name": "Mercury V"
}
},
"avalanche": {
"Apollo": {
"name": "Jupiter V"
}
}
} For further improvement I can offer something like, getting configuration parameters (ie. secrets) from {
"mainnet": {
"Apollo": {
"deployer": "PK_MAINNET"
}
},
"goerli": {
"Apollo": {
"deployer": "PK_GOERLI"
}
},
"avalanche": {
"Apollo": {
"deployer": "PK_AVALANCHE"
}
}
} Now I made to work the workaround more convenient (for demostration), I have added const Parameters = {
goerli: {
NewTokenModule: { dependencyTokenAddress: '0x01' },
},
mainnet: {
NewTokenModule: { dependencyTokenAddress: '0x02' },
},
avalanche: {
NewTokenModule: { dependencyTokenAddress: '0x03' },
},
} as const; Then I've used in the deployment script import hre, { ignition } from 'hardhat';
import NewTokenModule from '../ignition/modules/NewTokenModule';
import { NewToken } from '../typechain-types';
async function main() {
const { newToken }: { newToken: NewToken } = (await ignition.deploy(NewTokenModule, {
parameters: {
NewTokenModule: {
dependencyTokenAddress: Parameters.goerli.NewTokenModule.dependencyTokenAddress,
},
},
})) as any;
console.log(`New Token deployed to: ${await newToken.getAddress()}`);
}
main().catch(console.error); |
Describe the feature
Sometimes the deployment of certain features depends on contracts that do not fully belong to us. For example:
What happens in this case? Not all the networks are the same. Just to start, contract A (this also applies to B and C) will have a different address in the testnet(s) vs. the mainnet(s). Also, contract A will not exist on local networks ("localhost" to manually play with, and "hardhat" to run the tests against). In these cases, the user that develops D might have either the full source code of A to locally deploy (if in-company this might be the case) or at least some sort of mock (specially if not being part of the same company).
For example, in my case I wanted to seamlessly interact with Chainlink's Price Feeds (ONE of them in particular) in localhost, testnet, and mainnet. My intention was to create something like this, but I'm aware this is not supported:
Please note: certain parts of the code do not exist and are made up but precisely the idea is for these parts to exist.
In this case, I'd reference a contract when using external networks, but would deploy a local contract (most likely, a mock) when using local.
The idea is to only rely on these kinds of things to make the structure and invariants of the deployment depend on the chosen network.
Search terms
No response
The text was updated successfully, but these errors were encountered: