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: automate etherscan verification #1918

Merged
merged 9 commits into from
Sep 3, 2020

Conversation

kendricktan
Copy link
Contributor

@kendricktan kendricktan commented Aug 28, 2020

Motivation

This PR includes a way to automate the etherscan verification process.

Summary

To automate the verification process on etherscan, we need to do two additional things:

  1. Capture the constructor args during deployment/migrations
  2. Save the constructor args into a file.

Details

This PR adds the feature to save constructor args into a separate file (networkid_args.json) in the networks directory. Upon deployment it'll use that those args to verify the contracts on etherscan.

For example:

truffle migrate --reset --network kovan
# There is now a file `42_args.json` in the `networks` directory

# Gets the files prefixed with `42` in the `networks` directory
# and attempts to verify them
npx buidler etherscan-verification --network-id 42

Known Issues
Unable to verify ExpiringMultiPartyLib, DesignatedVotingFactory, TokenFactory, and Governor via the API, however uploading the solc-input.json via the web interface works. A support ticket with etherscan has been made.

Issue(s)

#1807
Fixes #1854.

@kendricktan kendricktan requested review from a team, daywiss and nicholaspai and removed request for a team August 28, 2020 01:17
Signed-off-by: Kendrick Tan <[email protected]>
@nicholaspai
Copy link
Member

Drive by comment

Unable to verify ExpiringMultiPartyLib via the API, however uploading the solc-input.json via the web interface works. A support ticket with etherscan has been made.

Does this work without. modifications to solc-input.json?

});

// Save to file
fs.writeFileSync(tvrPath, JSON.stringify({ ...tvrData, [address]: argsFixed }, null, 4));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain what the null and 4 args passed to JSON.stringfy do and why they're needed? Seems like a bit of a magic number

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The null and 4 are there to make it human readable, otherwise it'll flatten the whole thing.

The null is the replacer function, which intends to replace key-value pairs.

4 is number of spacing. 4 was chosen as thats the standard number of indented spaces.

@@ -1,66 +1,66 @@
[
{
"contractName": "Migrations",
"address": "0xB851449bC030F08E0f1Aa57A0a7cAEFE73030De0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should remove all changes to 42.json from this PR, as we already support a set of contracts that are integrated into emp-tools for example. However, were these contracts all verified on Etherscan via your script?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do, this is more to show-case the automation side of it. I can revert it back to the original contracts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll revert the contract addresses once the PR comes to a consensus. I left it here just to showcase how the process works.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM!

},
{
"contractName": "Governor",
"address": "0xca4575EE197308c9D2aBF813A5f064f44898b7a4"
"address": "0x94c99c8Ce915ddd77a556eA81caa3A9aB86f5642"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Governor does not look verified

{
"contractName": "WETH9",
"address": "0xd0A1E359811322d97991E03f863a0C30C2cF029C"
"address": "0xac065bB2C954dCf2f76Fa0092e2bc997fc261B4f"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WETH9 is not verified

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this might be DesignatedVotingFactory

},
{
"contractName": "TestnetERC20",
"address": "0xbF7A7169562078c96f0eC1A8aFD6aE50f12e5A99"
},
{
"contractName": "TokenFactory",
"address": "0x4bb1B6F3e028195373A85bd30869aEeC8A7C2671"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TokenFactory not verified

},
{
"contractName": "ExpiringMultiPartyLib",
"address": "0x9C53D9f4E959b1cd2eE25C45f50aFf45dca471CE"
"address": "0x46C1790fdE1F44cdf052735a4Fac4152a51Cae04"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one not verified, but I see you pointed this out in PR description

Copy link
Member

@nicholaspai nicholaspai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really useful! A few changes I'd like to see:

  • Don't commit changes to 42.json as this is the list of supported Kovan contracts which we've already verified. However, please do post as a comment a list of contracts that were verified via this method
  • I noticed that some contracts still were not verified

@daywiss
Copy link
Contributor

daywiss commented Aug 28, 2020

im prob not the best to review this, but i will look it over. you might want to get @mrice32 or @chrismaree as a review as well

@kendricktan
Copy link
Contributor Author

kendricktan commented Aug 30, 2020

Drive by comment

Unable to verify ExpiringMultiPartyLib via the API, however uploading the solc-input.json via the web interface works. A support ticket with etherscan has been made.

Does this work without. modifications to solc-input.json?

Yeap ExpiringMultiPartyLib can be verified via the web-interface with 0 edits to solc-input.json. The one that needs modification is the ExpiringMultiPartyCreator, which gets automatically verified for some reason...

I noticed that some contracts still were not verified
Some contracts that are not added by the truffle-registry (e.g. WETH) won't automatically get verified as there is no constructor args.

The API feels a bit flaky, its only able to verify SOME contracts through the API. However if you were to manually upload solc-input.json via the web portal, it verifies successfully.

Some contracts that are affected by this as you've discovered (you'll have to manually upload it via the web portal):

  1. Governor
  2. TokenFactory
  3. DesignatedVotingFactory
  4. ExpiringMultiPartyLib

I didn't mention 1, 2, and 3 as I presumed the ones that were causing the biggest issues on verification were the Voting, EMPCreator, and EMPLib contracts

@nicholaspai
Copy link
Member

Drive by comment

Unable to verify ExpiringMultiPartyLib via the API, however uploading the solc-input.json via the web interface works. A support ticket with etherscan has been made.

Does this work without. modifications to solc-input.json?

Yeap ExpiringMultiPartyLib can be verified via the web-interface with 0 edits to solc-input.json. The one that needs modification is the ExpiringMultiPartyCreator, which gets automatically verified for some reason...

I noticed that some contracts still were not verified
Some contracts that are not added by the truffle-registry (e.g. WETH) won't automatically get verified as there is no constructor args.

The API feels a bit flaky, its only able to verify SOME contracts through the API. However if you were to manually upload solc-input.json via the web portal, it verifies successfully.

Some contracts that are affected by this as you've discovered (you'll have to manually upload it via the web portal):

  1. Governor
  2. TokenFactory
  3. DesignatedVotingFactory
  4. ExpiringMultiPartyLib

I didn't mention 1, 2, and 3 as I presumed the ones that were causing the biggest issues on verification were the Voting, EMPCreator, and EMPLib contracts

Why do you think those didn't get auto verified? Is it a buidler issue, since the manual solc.json upload works? Overall I support this approach, my only suggestions are to figure out (if possible) how to auto verify ALL contracts and secondly to auto-detect the user's network so we have fewer .env vars

@kendricktan
Copy link
Contributor Author

Why do you think those didn't get auto verified? Is it a buidler issue, since the manual solc.json upload works?

I don't think its a buidler issue, technically speaking, I'm only writing it as a builder plugin because I need buidler to generate solc-input.json. Apart from using builder to generate solc-input.json, everything else is API calls.

It is likely an issue on etherscan's end as:

  1. Files are identical
  2. The only difference is that files are uploaded via the API instead of the web UI
    • They're using a different processes for verification via the web ui and verification via the API

@kendricktan
Copy link
Contributor Author

@mrice32 @nicholaspai @chrismaree @daywiss I'm changing the coverage to use truffle run converage instead of buidler as it keeps hanging, PR can't be merged unless all the checks passes.

@coveralls
Copy link

coveralls commented Aug 31, 2020

Coverage Status

Coverage remained the same at 92.71% when pulling 5f9989e on feat/etherscan-automate-verification into c210f03 on master.

@nicholaspai
Copy link
Member

Why do you think those didn't get auto verified? Is it a buidler issue, since the manual solc.json upload works?

I don't think its a buidler issue, technically speaking, I'm only writing it as a builder plugin because I need buidler to generate solc-input.json. Apart from using builder to generate solc-input.json, everything else is API calls.

It is likely an issue on etherscan's end as:

  1. Files are identical

  2. The only difference is that files are uploaded via the API instead of the web UI

    • They're using a different processes for verification via the web ui and verification via the API

Ok, I think before approving this let's revert the changes in 42.json and 42.args.json, and then can you try to figure out a way to automate the remaining contract verifications? Otherwise you should make a note somewhere which contracts get verified and which do not (or maybe console.log each successful verified contract) so the user knows which ones to manually verify.

@kendricktan
Copy link
Contributor Author

kendricktan commented Aug 31, 2020

Ok, I think before approving this let's revert the changes in 42.json and 42.args.json, and then can you try to figure out a way to automate the remaining contract verifications? Otherwise you should make a note somewhere which contracts get verified and which do not (or maybe console.log each successful verified contract) so the user knows which ones to manually verify.

It console.logs the whole process (success, failed, in-progress), with color coding 😛

@nicholaspai
Copy link
Member

Ok, I think before approving this let's revert the changes in 42.json and 42.args.json, and then can you try to figure out a way to automate the remaining contract verifications? Otherwise you should make a note somewhere which contracts get verified and which do not (or maybe console.log each successful verified contract) so the user knows which ones to manually verify.

It console.logs the whole process (success, failed, in-progress), with color coding 😛

Beautiful. Just revert the 42.json files then LGTM

Signed-off-by: Kendrick Tan <[email protected]>
module.exports = {
solc: {
version: "0.6.12",
version: solcVersion,
optimizer: {
enabled: true,
runs: 199
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should you change the networks config to the user's connected network?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This networks is a config when buidler runs tests, e.g. npx buidler test --network localhost/buidlerevm.

What do you mean by "user connected network"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if I want to use Kovan or Mainnet network would it work for that? Sorry I don't have much familiarity with buidler

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you'd like to run tests for the kovan network, you'll need to add the network config to the "networks" section. This PR is about a separate topic - verifying contracts, please keep it at that.

To verify the contracts, you need to files to be saved in the truffle-registry (i.e. in networks/ directory). So for example, if you've deployed the kovan contracts, it will appear as networks/42.json. This PR also captures the constructor args for each deployed contract, and saves them into networks/42_args.json.

To verify the deployed contracts for kovan you'll run npx buidler verify-etherscan --network-id 42. It'll try and find the files 42.json and 42_args.json in the network directory, and combined them with solc-input.json before uploading them to etherscan.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you'd like to run tests for the kovan network, you'll need to add the network config to the "networks" section. This PR is about a separate topic - verifying contracts, please keep it at that.

Sorry I think i am confused. You're saying that the networks object has no impact on verification? Only affects the tests?

Copy link
Contributor Author

@kendricktan kendricktan Aug 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@mrice32 mrice32 Sep 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to tie this thread off, I think what you're saying @kendricktan is that the verification does not require buidler to have any non-test networks set up (like we have for truffle). The verification task is independent of (and doesn't rely on) the declared networks in the buidler config. All it needs is to be able to compile (network agnostic) and see the networks/ files.

SGTM!

Copy link
Member

@nicholaspai nicholaspai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! 2 things:

  • Would like a second set of eyes from this so I've requested @mrice32 @daywiss and @chrismaree
  • Is your networks param in the buidler.config.js meant to be pointed at localHost?

Copy link
Member

@mrice32 mrice32 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM!

Two PR nits:

Title should be feat: automate etherscan verification to conform to conventional commits.

And I think this PR should fix #1854, so please add Fixes #1854 to the issues section of the description.

module.exports = {
solc: {
version: "0.6.12",
version: solcVersion,
optimizer: {
enabled: true,
runs: 199
Copy link
Member

@mrice32 mrice32 Sep 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to tie this thread off, I think what you're saying @kendricktan is that the verification does not require buidler to have any non-test networks set up (like we have for truffle). The verification task is independent of (and doesn't rely on) the declared networks in the buidler config. All it needs is to be able to compile (network agnostic) and see the networks/ files.

SGTM!

@mrice32 mrice32 changed the title Feat/etherscan automate verification feat: automate etherscan verification Sep 1, 2020
Copy link
Member

@chrismaree chrismaree left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty awesome. pitty it does not work in all cases but seeing we can upload the output file directly to the Etherscan UI it's still a massive step up.

@nicholaspai nicholaspai merged commit f2d47a4 into master Sep 3, 2020
@mrice32 mrice32 deleted the feat/etherscan-automate-verification branch September 3, 2020 12:55
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.

Coverage is flaky in ci
6 participants