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

buidler-deployments plugin #381

Closed
alcuadrado opened this issue Sep 20, 2019 · 21 comments
Closed

buidler-deployments plugin #381

alcuadrado opened this issue Sep 20, 2019 · 21 comments

Comments

@alcuadrado
Copy link
Member

alcuadrado commented Sep 20, 2019

We should offer some functionality to preserve deployments' information between Buidler executions.

One possible solution is to create a plugin that extends the Buidler Runtime Environment with an object containing (at least) these two methods:

  • getDeployedContracts: Receives a TruffleContract and returns an array of contract instances. This method should warn if the deployed contract's bytecode doesn't match the local's one.

  • saveDeployedContract: Receives a contract instance, and saves its address. This method should warn if the contract was deployed to a testing/temporal network.

Under the hood, these methods should work with a JSON file looking something like this:

interface DeploymentsFile {
  [chainId: number]: {
    [contractName:string]: string[] // the addresses 
  }
}

Any operation involving reading & updating that file has to be synchronous, and, if possible, atomic.

Once we have this plugin, deployment scripts could be written in this fashion:

let [token] = await deployments.getDeployedContracts(Token);
if (token === undefined) {
   token = await Token.new();
   await deployments.saveDeployedContract(token);
}

let [other] = await deployments.getDeployedContracts(Other);
if (other === undefined) {
   other = await Other.new(123, token.address);
   await deployments.saveDeployedContract(other);
}

Writing them this way has the advantage of the scripts being resumable. If, for example, deploying Other fails because 123 wasn't a valid parameter, you can correct it and re-run the script without having to re-deploy the Token`.

Finally, other things that we should consider:

  • We should also have some methods to "forget" about a certain contract.
  • Should we store the deployment parameters?
@wighawag
Copy link
Contributor

Hey,
You might want to checkout rocketh (https://github.com/wighawag/rocketh) it was optimized for a seamless deployment flow.

I am starting to look at buidler to see if i could implement the same functionality in plugins but I am not sure yet

rocketh supports the following thing :

  • stages (aka migrations in truffle parlance) that are run both for tests and deployment
    in test mode you can re-run them so your test can always act on a blank state. No need to duplicate code.
  • namedAccounts allow you to configure special account with name for each network.. Your tests can use them too. This make test more readable while preserving compatibility with deployment with real addresses.
  • when a failure happen while waiting for a deployment to be mined, rocketh save the tx hash so you can resume even for this case. When the stages are re-run It will wait for that transaction to complete. If this tx never finish, you currently have to delete the pending state. planning to add a prompt.
  • it saves a deployment file (only in non-test chain) that contains the solc output as well as the metadata. It also create a separate file for code verification that can be used as input for solc. These are meant to be stored on git and are used to check whether you want to redeploy a contract or not
  • Indeed it supports redeploy only if changes were made (checking arguments and/or bytecode) allowing you to feel confident in running the whole stages on the mainnet.
  • it supports bitski app wallet for deployment. You can have different wallet for the different networks

@wighawag
Copy link
Contributor

Oh forgot to mention that it also support a keepRunning mode (running ganache or geth) using these features with the extra possibility of exporting the contract info (abi, address, [bytecode]) to an external file (path specified by user)

Very useful for local webapp development as you run it and then your contract are deployed and the info is available to your webapp

@pcowgill
Copy link
Contributor

This feature is the main thing gating my project moving from Truffle over to Buidler.

@fvictorio
Copy link
Member

Some thoughts on this.

Addresses location

One open question is where the addresses will be saved. I guess saving them in the artifacts directory makes sense. An alternative is to have a specific file for this. For example, the Gnosis team has a networks.json file in many of their projects (example). This file is versioned and also published to npm, which makes it easier to use in a different project:

const networks = require('my/project/networks.json')

console.log(networks["MyContract"]["1"].address

Of course, this can also be done with artifacts if you commit and publish them.

Multiple instances

The other question I have is how to manage multiple instances of the same contract. In the current proposal, it seems like each new address is added to an array. My problem with that is that working with that seems a little cumbersome: you are relaying on the order in which your original deploy script was written.

The other problem with this, in my opinion, is that it defaults to a complex object when in most cases contracts have only one instance. So I think a nice alternative approach would be using some kind of map, and returning a single address for the given key:

let token = await deployments.getDeployedContracts(Token);
if (token === undefined) {
   token = await Token.new();
   await deployments.saveDeployedContract(token);
}

let anotherToken = await deployments.getDeployedContracts(Token, 'otherToken');
if (token === undefined) {
   anotherToken = await Token.new();
   await deployments.saveDeployedContract(anotherToken, 'otherToken');
}

(This is just to illustrate the idea; I don't like that API for a couple of reasons that I won't detail because this is getting long enough already.)

The next question here is how to represent this on the artifacts/networks file.

Truffle

There's a feature request for this in Truffle since 2016, see trufflesuite/truffle#237. They are also working on a proposal to solve this and other related issues. I haven't read this document in depth; the analysis looks interesting, but the proposal seems unnecessarily complex. I think the approach proposed in this issue covers a lot of ground and it's flexible enough.

@wighawag
Copy link
Contributor

I started to work on a deployment plugin that already have most of the feature https://rocketh.io had :
https://github.com/wighawag/buidler-deploy

It override the builtin task to provide extra features. See github repo for more details

It is still work in progress and would be happy to get feedback,

@nfurfaro
Copy link

The "Deploying your Contracts" page of the Hardhat site says "When it comes to deploying, there are no plugins that implement a deployment system for Hardhat yet..."
https://hardhat.org/guides/deploying.html#deploying-your-contracts

This is misleading as you list Hardhat-deploy under the list of available Plugins.
Perhaps this could be updated?

@hashparty1
Copy link

Yes it almost makes it seem like Hardhat is discouraging the use of hardhat-deploy because it's so prevalent yet they act like it doesn't exist.

@Madeindreams
Copy link

Well I found that deploying contracts with ethers was fairly easy. So far I like how hardhat works with ethers. So I think it would only be a matter of passing the contract name down the line. I'm looking for a complete solution from compiling => deploying => verifying as well.

@alcuadrado
Copy link
Member Author

I totally missed this, @nfurfaro, sorry about that. A lot changed since we first wrote that, and never updated it. How wants to send a PR updating it?

@outdoteth
Copy link

So is the consensus to use hardhat-deploy?

feuGeneA added a commit that referenced this issue Jun 29, 2021
aspiers added a commit to aspiers/hardhat that referenced this issue Sep 4, 2021
The Truffle migrations page was out of date, incorrectly claiming that
no plugins yet exist which implement a deployment system for Hardhat.
However since that was written, hardhat-deploy has emerged, and
the same text in /guides/deploying.md was already updated accordingly.

So update the paragraph in truffle-migration.md to match, and
cross-link to /guides/deploying.md.

This is relevant to the discussion in NomicFoundation#381.
aspiers added a commit to aspiers/hardhat that referenced this issue Sep 4, 2021
The Truffle migrations page was out of date, incorrectly claiming that
no plugins yet exist which implement a deployment system for Hardhat.
However since that was written, hardhat-deploy has emerged, and
the same text in /guides/deploying.md was already updated accordingly.

So update the paragraph in truffle-migration.md to match, and
cross-link to /guides/deploying.md.

This is relevant to the discussion in NomicFoundation#381.
@aspiers
Copy link
Contributor

aspiers commented Sep 4, 2021

@hashparty1 commented on April 6, 2021 5:28 AM:

Yes it almost makes it seem like Hardhat is discouraging the use of hardhat-deploy because it's so prevalent yet they act like it doesn't exist.

Yes, this seems a bit odd to me too. I've submitted #1852 to fix the Truffle migrations guide to be consistent with @feuGeneA's change in 953f21f, but I think it would make more sense if the docs were changed to recommend using hardhat-deploy over rolling your own solution. What do you think @fvictorio and @alcuadrado?

@aspiers
Copy link
Contributor

aspiers commented Sep 4, 2021

Also, can we rename this issue to "hardhat-deployments plugin"?

alcuadrado pushed a commit that referenced this issue Oct 21, 2021
The Truffle migrations page was out of date, incorrectly claiming that
no plugins yet exist which implement a deployment system for Hardhat.
However since that was written, hardhat-deploy has emerged, and
the same text in /guides/deploying.md was already updated accordingly.

So update the paragraph in truffle-migration.md to match, and
cross-link to /guides/deploying.md.

This is relevant to the discussion in #381.
@banshee
Copy link

banshee commented Mar 4, 2022

So is the consensus to use hardhat-deploy?

I would have said the consensus is to not use hardhat-deploy.

@aspiers
Copy link
Contributor

aspiers commented Mar 24, 2022

@banshee commented on March 4, 2022 7:09 PM:

So is the consensus to use hardhat-deploy?

I would have said the consensus is to not use hardhat-deploy.

Which consensus are you referring to - within Nomic Foundation, or from a community perspective?

hardhat-deploy is the only reasonable solution I'm personally aware of.

@fvictorio
Copy link
Member

Hi everyone, thanks a lot for all the comments here, they've been really useful!

We are going to close this issue now because we are already working on Ignition, which we think will satisfy this need.

If someone is interested in Ignition and wants to participate as an early tester or contribute in any other way (feedback about the design, feature requests, etc.), please DM me or leave a comment here.

@KholdStare
Copy link

@fvictorio I took a look at https://github.com/NomicFoundation/hardhat-ignition , and there haven't been any commits since July 2021. There is only a single release on npm https://www.npmjs.com/package/hardhat-ignition from a year ago. Is there another repository or package I am unaware of?

I think it's really sad that hardhat-deploy seems to be actively shunned. I understand there is a long-term vision, but then there's the reality of developers needing a working deployment process now. So instead of compromising and supporting hardhat-deploy while Ignition is in development, the alternative is to tell developers to ignore that project and do everything manually with scripts?

This is an opportunity to work with creators of existing tools, and also create a clear migration path for users who have already chosen to use hardhat-deploy. Perhaps the author of hardhat-deploy can contribute to Ignition and collaborate. If hardhat-deploy is ignored, you're just leaving that part of the community behind. 🤷

If I'm blowing this out of proportion then some clearer messaging on the current status of Ignition would be nice.

@fvictorio
Copy link
Member

I took a look at https://github.com/NomicFoundation/hardhat-ignition , and there haven't been any commits since July 2021.

That was an early prototype, the current version is in a private repository for now. We should hide that other repo because it's not the first time that it's confusing for someone, sorry about that!

I think it's really sad that hardhat-deploy seems to be actively shunned.

I don't think we are actively shunning it, hardhat-deploy has been incredibly valuable for the Hardhat ecosystem. We just try to make a clear distinction between our official plugins and the ones created by the community, because if it's an official recommendation then it becomes (partially) our responsibility too, and we are already understaffed for our current projects.

Perhaps the author of hardhat-deploy can contribute to Ignition and collaborate.

We are on really good terms with @wighawag (or at least I would like to think we are!) and he has contributed some very useful feedback for Ignition from his experience with hardhat-deploy.

If hardhat-deploy is ignored, you're just leaving that part of the community behind.

It's not our plan to leave that part of the community behind. We are going to have both clear migration guides, and also Ignition is being developed in a way that should let anyone build on top of it, so there's a possibility that hardhat-deploy could use it as its engine under the hood for people that prefer its approach to deployments.

I know we've not done a great job at communicating our relationship with hardhat-deploy. It's likely that we've been too conservative in order to not have extra work to do, but to be fair even doing this we still get a lot of support questions from people that don't realize that hardhat-deploy is a separate project. But, again, I really think we could've handled that without making it look like we are shunning it.

@lukehutch
Copy link

Just wanted to point out that the hardhat-deploy documentation is woefully incomplete. I can't figure out how to do even the most basic of things with the documentation in the project's README.md file. I found a 3rd party tutorial that is much better, but hardhat-deploy is not a good entry point for people unless it becomes much better at demonstrating how to address the most basic usecases. (That's what brought me here looking for other options.)

@lukehutch
Copy link

By the way probably these two pages of Hardhat documentation need to be combined, or at least the first one should reference the other:

https://hardhat.org/guides/deploying

https://hardhat.org/tutorial/deploying-to-a-live-network

@mingxin-yang
Copy link

Hello, I am a newbie in blockchain, I need to deploy contracts to different networks, and when I switch networks in the project, I can automatically switch to use different abi and json files. Can I use hardhat-deploy? Does the plugin do my job?

@fvictorio @wighawag

@mok0230
Copy link

mok0230 commented Sep 30, 2022

If someone is interested in Ignition and wants to participate as an early tester or contribute in any other way (feedback about the design, feature requests, etc.), please DM me or leave a comment here.

@fvictorio would love to try out Ignition!

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests