Skip to content

Conversation

dkent600
Copy link
Contributor

@dkent600 dkent600 commented Mar 26, 2019

Adds new verify contracts script. See Verify.md for instructions on how to use.

Note: The Etherscan API 'verifysourcecode' method in some cases returns success even when it has failed to verify the contract. The returned GUID is not helpful, as for any given GUID, the 'checkverifystatus' method always returns "Error! Missing Or invalid Module name", regardless of verification success or failure.

I have submitted a ticket on this to etherscan, they have responded with a request for further info, which I have provided. See https://etherscancom.freshdesk.com/public/tickets/582fc02dfc53677ce6d9a02bbeb788fcf8111b6fc5f61b16556570d05da8a276

@dkent600 dkent600 changed the title package-lock Adds new verify contracts script. See Verify.md for instructions on how to use. Has some issues: 1. The Etherscan API 'verifysourcecode' method in some cases returns success even when it has failed to verify the contract. The returned GUID is not helpful, as for *any* given GUID, the 'checkverifystatus' method always returns "Error! Missing Or invalid Module name", regardless of verification success or failure. 2. some contracts are not verifying in the latest instance of the repo, that were verifying in earlier releases. I suspect something has changed in how those contracts are being compiled or migrated. Will continue to investigate. Mar 26, 2019
@dkent600 dkent600 changed the title Adds new verify contracts script. See Verify.md for instructions on how to use. Has some issues: 1. The Etherscan API 'verifysourcecode' method in some cases returns success even when it has failed to verify the contract. The returned GUID is not helpful, as for *any* given GUID, the 'checkverifystatus' method always returns "Error! Missing Or invalid Module name", regardless of verification success or failure. 2. some contracts are not verifying in the latest instance of the repo, that were verifying in earlier releases. I suspect something has changed in how those contracts are being compiled or migrated. Will continue to investigate. Adds new verify contracts script Mar 26, 2019
@dkent600
Copy link
Contributor Author

package.json Outdated
"prune-arc-build": "node ./pruneArcBuild.js",
"postinstall": "npm run prune-arc-build"
"postinstall": "npm run prune-arc-build",
"verify.initialize": "cd ./node_modules/@daostack/arc && npm install openzeppelin-solidity && cd ../infra && npm install openzeppelin-solidity",
Copy link
Contributor

Choose a reason for hiding this comment

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

perhaps npm explore @doastack/arc -- npm install openzeppelin-solidity is a bit more robust.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea, forgot about that ability

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Verify.md Outdated

## Verify

### Verify all of the migrated contracts
Copy link
Contributor

Choose a reason for hiding this comment

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

So what does this mean exactly? There are different contract versions on chain, and different versions of arc etc.
I'd expect "very the migrated contracts" means: take the current versino of arc (from package.json), take the addresses from migration.json, and check if the compiled code of arc corresponded to the deployed bytecode.

Is that what is happening?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, there is some codce in the migartion script that compares bytecodes, perhaps you can look at that as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What we are doing is, for each contract whose address appears in migration.json (and therefore is a "migrated contract"), we send the contract's solidity code to etherscan.io which will attempt to "verify" that the given code corresponds to the deployed bytecodes.

I will explain this in the md file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@ben-kaufman
Copy link
Contributor

@dkent600 can you please add this to the prepare-release.sh or the release.sh so it's done automatically when publishing a new version?

@dkent600
Copy link
Contributor Author

dkent600 commented Apr 2, 2019

@ben-kaufman

can you please add this to the prepare-release.sh or the release.sh

I added to prepare-release.sh

@dkent600 dkent600 force-pushed the verify-contracts branch 4 times, most recently from 9611bf7 to c247dd7 Compare April 8, 2019 14:09
Verify.md Outdated
## Setup
1. In the project root, create an ".env" file (or use the existing one) that contains:
```
APIKEY=[API key from etherscan.io]
Copy link
Contributor

Choose a reason for hiding this comment

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

please add a link to etherscan api key ..how too.
https://etherscan.io/apis

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

package.json Outdated
"prune-arc-build": "node ./pruneArcBuild.js",
"postinstall": "npm run prune-arc-build"
"postinstall": "npm run prune-arc-build",
"verify.initialize": "npm explore @daostack/arc -- npm install openzeppelin-solidity && npm explore @daostack/arc/node_modules/@daostack/infra -- npm install openzeppelin-solidity && npm explore @daostack/arc-hive -- npm install openzeppelin-solidity",
Copy link
Contributor

@orenyodfat orenyodfat Apr 15, 2019

Choose a reason for hiding this comment

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

why we need to re install ? migration repo already deploy arc , openzeppelin ,infra, arc-hive
And if there is a need(not sure) , which versions it is install ? it need to be aligned with the migration packages version.no?

Copy link
Contributor Author

@dkent600 dkent600 Apr 15, 2019

Choose a reason for hiding this comment

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

Need to reinstall because truffle-flattener explicitly requires that it be run from within a folder that contains the truffle project that contains the contract being flattened. Otherwise truffle-flattener won't work.

npm will install whatever version the package says needs to be installed. I'm not sure how this could not be aligned with what the migration package is expecting.

Copy link
Contributor Author

@dkent600 dkent600 Apr 16, 2019

Choose a reason for hiding this comment

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

@orenyodfat OK, I think I see how there can be misalignment. The only way I can see to fix this is to change, for example, "openzeppelin-solidity": "^2.2.0" to "openzeppelin-solidity": "2.2.0" in the arc package. This would avoid picking up 2.2.1 when the contracts were compiled with 2.2.0.

Copy link
Contributor

Choose a reason for hiding this comment

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

which version it will install on npm install openzeppelin-solidity ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@orenyodfat

which version it will install on npm install openzeppelin-solidity ?

It depends on the project and what is the current version available.

According to the package.json files:

Arc: ^2.1.3
Infra: ^2.1.3
arc-hive: ^2.2.0

These are the versions being installed today.

But what if openzeppelin-solidity releases a new version and suddenly there is a 2.2.1, and suppose this happens after the release of arc-hive. So arc-hive will have been compiled with 2.2.0, but will be flattened with 2.2.1, which could prevent the verification from succeeding.

The only reasonable way to solve this, that I see, is to remove the '^' from the openzeppelin-solidity version specification in the package.json files.

Copy link
Contributor

Choose a reason for hiding this comment

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

but the script does that without version .
how about edit the script to do npm install openzeppelin-solidity 2.2.1 ?

Copy link
Contributor Author

@dkent600 dkent600 Apr 17, 2019

Choose a reason for hiding this comment

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

@orenyodfat

but the script does that without version
how about edit the script to do npm install openzeppelin-solidity 2.2.1 ?

How is the script supposed to know what is the correct version? I could write some code to parse the three package.json files to obtain the version number for openzeppelin-solidity in each package, but that would not be robust. It would fail to obtain the correct version in the following case:

  1. Assume Arc has ^2.2.0 in package.json
  2. Assume the current version of openzeppelin-solidity is 2.2.1.
  3. The user runs truffle compile on Arc prior to creating an NPM package for Arc.

RESULT:
The contracts are compiled with 2.2.1 but the package.json remains unchanged, still referring to ^2.2.0.

Then when the verify script parses the package.json, it will get 2.2.0, which is the wrong version, and thus verification may fail.

I think it is the right thing for us to do in general, not just for verify, to be explicit in the Arc, etc package.json files about exactly what version the contracts are compiled with.

Verify.md Outdated
### Verify all of the migrated contracts

```script
npm run verify
Copy link
Contributor

@orenyodfat orenyodfat Apr 15, 2019

Choose a reason for hiding this comment

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

need to set network ?
Running this produce : 'network' is required. Run 'npm run help' for cli information.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

{ name: 'check', alias: 'g', type: String, description: 'Given verify GUID, check contract verification status. Ignores other options.' },
{ name: 'outputFlattened', alias: 'f', type: String, description: 'When verifying, absolute path where to save the flattened .sol file to flattened.["contractName"].sol.' },
];
// tslint:enable: max-line-length
Copy link
Contributor

Choose a reason for hiding this comment

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

is that not enable by default ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

just a few lines above it is disabled

verify.ts Outdated
} else {
if (options.contractName) {
if (!allAddresses[options.contractName]) {
// tslint:disable-next-line: max-line-length
Copy link
Contributor

Choose a reason for hiding this comment

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

why to disable that here?

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 removed it and split the following line.

verify.ts Outdated

try {

// tslint:disable-next-line: max-line-length
Copy link
Contributor

Choose a reason for hiding this comment

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

why to disable that here?

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 removed it and split the following line.

verify.ts Outdated
// tslint:disable-next-line: max-line-length
const etherscanUrl = `https://api${options.network === 'main' ? '' : ('-' + options.network)}.etherscan.io/api`;

// const flattenedFake = fs.readFileSync('./flattened.sol', 'UTF-8');
Copy link
Contributor

Choose a reason for hiding this comment

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

please remove this commented code

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

verify.ts Outdated
fs.writeFileSync(path.join(options.outputFlattened, `flattened.${contractName}.sol`), flattened);
}

// tslint:disable-next-line: max-line-length
Copy link
Contributor

Choose a reason for hiding this comment

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

why to disable that here?

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 removed it and split the following line.

verify.ts Outdated
sourceCode: flattened,
};

// console.dir(Object.assign({}, apiConfig, { sourceCode: `${flattened.substr(0, 50)}...` }));
Copy link
Contributor

Choose a reason for hiding this comment

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

please remove this commented code line

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

verify.ts Outdated
// tslint:disable-next-line: max-line-length
spinner.fail(`${contractName} at ${addresses[contractName]} ${verifyResult.result}, GUID: ${result.result}`);
} else {
// tslint:disable-next-line: max-line-length
Copy link
Contributor

Choose a reason for hiding this comment

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

why to disable that here?

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 removed it and split the following line.

@dkent600
Copy link
Contributor Author

dkent600 commented May 1, 2019

@orenyodfat

#127 (comment) breaks this line:

[options.network === 'mainnet' ? '0xd3BA32dd207Db75f535001FAC749c925423D8A6f' : // DAOstack multisig :

Need to change the address for mainnet to: '0x85e7fa550b534656d04d143b9a23a11e05077da3' and change 'multisig' to 'controlled account'

@orenyodfat
Copy link
Contributor

@orenyodfat

#127 (comment) breaks this line:

[options.network === 'mainnet' ? '0xd3BA32dd207Db75f535001FAC749c925423D8A6f' : // DAOstack multisig :

Need to change the address for mainnet to: '0x85e7fa550b534656d04d143b9a23a11e05077da3' and change 'multisig' to 'controlled account'

the verifier should not depend on constructor params.
you should read the deployed byte code from the blockchain , derived the constructor params and then verify.

@dkent600
Copy link
Contributor Author

dkent600 commented May 1, 2019

@orenyodfat

you should read the deployed byte code from the blockchain , derived the constructor params and then verify.

Having to access the chain adds a whole new dimension to the script. Just FYI this will take a little more time...

@dkent600 dkent600 force-pushed the verify-contracts branch from e663a88 to a6bdf5a Compare May 1, 2019 18:28
verify.ts Outdated
constructorArguments =
abi.rawEncode(['address'],
[options.network === 'mainnet' ? '0xd3BA32dd207Db75f535001FAC749c925423D8A6f' : // DAOstack multisig :
[options.network === 'mainnet' ? '0x85e7fa550b534656d04d143b9a23a11e05077da3' : // DAOstack controlled account
Copy link
Contributor

Choose a reason for hiding this comment

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

how this is related to the verifier ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When you verify a contract you have to supply the arguments (if there are any) by which it was constructed at the given address.

Copy link
Contributor

Choose a reason for hiding this comment

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

right. as comment above you should read the deployed byte code from the blockchain , derived the constructor params and then verify.

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 is done. It adds a new "-p" option to the command line to supply a provider url for web3.

The technique I used is simple but presumes to know the types (not the values) of contructor parameters in order to know how to parse the bytecodes to obtain the param values.

@tsuberim
Copy link
Contributor

tsuberim commented May 3, 2019

I think the verification should just happen during migration just after deploying a contract. Why does it have to be a whole set of new commands?
This also solves the previous question of how to get the constructor parents (they are available in the deploy script).

@dkent600
Copy link
Contributor Author

dkent600 commented May 3, 2019

@tsuberim

think the verification should just happen during migration just after deploying a contract.

It can, but there are use cases where it may need to be doable outside of that process as well.

@dkent600
Copy link
Contributor Author

dkent600 commented May 3, 2019

@tsuberim

PS -- the verify scripts are automatically run as part of the "release" process.

"prune-arc-build": "node ./pruneArcBuild.js",
"postinstall": "npm run prune-arc-build"
"postinstall": "npm run prune-arc-build",
"verify.initialize": "npm explore @daostack/arc -- npm install openzeppelin-solidity @daostack/infra --no-save && npm explore @daostack/infra -- npm install openzeppelin-solidity --no-save && npm explore @daostack/arc-hive -- npm install openzeppelin-solidity --no-save",
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems weird to install a package inside an installed package on an npm-script. Why is'nt this part of devDeps

Copy link
Contributor Author

Choose a reason for hiding this comment

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

truffle-flattener won't work otherwise

Copy link
Contributor

@tsuberim tsuberim May 6, 2019

Choose a reason for hiding this comment

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

weird, I don't understand the details but at the very least we can move this into postinstall to avoid having to remember to invoke this step manually if we can't get rid of it entirely.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

verify.initialize and verify.build are already run in prepare-release, prior to running verify.

"postinstall": "npm run prune-arc-build"
"postinstall": "npm run prune-arc-build",
"verify.initialize": "npm explore @daostack/arc -- npm install openzeppelin-solidity @daostack/infra --no-save && npm explore @daostack/infra -- npm install openzeppelin-solidity --no-save && npm explore @daostack/arc-hive -- npm install openzeppelin-solidity --no-save",
"verify.build": "node node_modules/typescript/bin/tsc verify.ts -sourceMap",
Copy link
Contributor

Choose a reason for hiding this comment

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

there's ts-node that you could use that executes typescript directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

what is there is sufficient without adding another tool

Copy link
Contributor

Choose a reason for hiding this comment

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

but it saves you the mental headache of remembering to do the build step.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

verify.initialize and verify.build are already run in prepare-release, prior to running verify.

"postinstall": "npm run prune-arc-build",
"verify.initialize": "npm explore @daostack/arc -- npm install openzeppelin-solidity @daostack/infra --no-save && npm explore @daostack/infra -- npm install openzeppelin-solidity --no-save && npm explore @daostack/arc-hive -- npm install openzeppelin-solidity --no-save",
"verify.build": "node node_modules/typescript/bin/tsc verify.ts -sourceMap",
"verify.help": "node verify.js -h",
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is redundant, everyone knows how to use -h or --help

Copy link
Contributor Author

Choose a reason for hiding this comment

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

they don't know to how to run node verify.js -h

Copy link
Contributor

Choose a reason for hiding this comment

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

npm run verify -- -h or yarn verify -h

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 don't see any reason not to have this helpful shortcut. risk-wise it is trivial

"verify.initialize": "npm explore @daostack/arc -- npm install openzeppelin-solidity @daostack/infra --no-save && npm explore @daostack/infra -- npm install openzeppelin-solidity --no-save && npm explore @daostack/arc-hive -- npm install openzeppelin-solidity --no-save",
"verify.build": "node node_modules/typescript/bin/tsc verify.ts -sourceMap",
"verify.help": "node verify.js -h",
"verify.lint": "tslint -c tslint.json verify.ts",
Copy link
Contributor

Choose a reason for hiding this comment

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

Could be more than just about verify.ts (all typescript files in the project)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sorry, I don't understand the suggestion. are you suggesting to convert all scripts to ts?

Copy link
Contributor

@tsuberim tsuberim May 6, 2019

Choose a reason for hiding this comment

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

no, but there's no particular reason to limit this to only verify.ts, there's also no particular reason to expand it to all typescript files (as of yet, but there might be in the future).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

for now, verify is all there is. we can cross the wider bridge when we come to it.

"verify.help": "node verify.js -h",
"verify.lint": "tslint -c tslint.json verify.ts",
"verify.lint.andFix": "npm run verify.lint -- --fix",
"verify": "node verify.js"
Copy link
Contributor

Choose a reason for hiding this comment

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

can be replaced with ts-node as I mentioed (take a look at this for a solution to a problem you might encounter)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On your suggestion, I looked into using ts-node, but it seems there are a lot of issues with it and using source maps in debuggers. Since the current soluton works for now, I'm not inclined to going down that rabbit hole.

@@ -0,0 +1,265 @@
const commandLineArgs = require('command-line-args');
Copy link
Contributor

Choose a reason for hiding this comment

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

other scripts uses yargs already

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 understand the desire to have only one system here, though it is not a huge deal. I think command-line-args has superior output and would use it instead of yargs.

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 took another look at this and find that migrate.js is using functionality from yargs that is not available in command-line-args, but the yargs funtionality comes at the cost of ugly and difficult-to-parse output. The verify code doesn't need the extra functionality of yargs, and by using command-line-args has much nicer output. So I am leaving well-enough alone here.

@tsuberim
Copy link
Contributor

tsuberim commented May 6, 2019

@dkent600

  1. When did this need last occur (that is not satisfied by just having it as part of regular migration)?
  2. I just think there might be a little extra complexity around initializing, building, having another set of commands related to verifying when it could just be a simple one-liner (with a helper function if necessary) in the migration itself.
  3. Having it inside the migration solves the problem of getting the constructor args (there's no need to)

@dkent600 dkent600 force-pushed the verify-contracts branch 2 times, most recently from c13e9ac to 44761dc Compare May 16, 2019 16:46
working (on Bash)

working except for contracts with constructor args

constructor params

added 'check'

update package-lock

lint

added verify.md.  -f for writing flattened .sol

fix status message

package-lock

PR suggestions, support for arc-hive contracts

corrected little readme typo

another .md typo fix

install infra so universal schemes will flatten

package-lock


run automatically in prepare-release

do npm install from scratch

"press any key" before verifying in prepare-releas

fix verify of DAORegistry

fix verify status check

rebase, fix breakage due to infra moving

requested PR changes

fix web3, fix infra reference

update package-lock

fix initialize script

main => mainnet

fix npm install adding '^' to package.json files.

controlled account against mainnet for DAORegistry

more flexible means of obtaining constructor args

readme for provider option
Copy link
Contributor

@ben-kaufman ben-kaufman left a comment

Choose a reason for hiding this comment

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

Looks good now. Let's merge and maybe later make further improvements if we need to.

@ben-kaufman ben-kaufman dismissed jellegerbrandy’s stale review June 25, 2019 07:46

This is an old review...

@ben-kaufman ben-kaufman merged commit 87c732e into master Jun 25, 2019
@ben-kaufman ben-kaufman deleted the verify-contracts branch June 25, 2019 07:47
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.

5 participants