-
Notifications
You must be signed in to change notification settings - Fork 25
Verify contracts command #339
Verify contracts command #339
Conversation
Defined required and non-required command parameters.
Basically, network ControllerFor function was used to verify if zOS project was initialized, together with NetworkBaseController checkLocalContractDeployed to verify contract definition, deploy status and source code modification status
Implemented a local controller method to retrieve the contract source code path and also tiny function to flatten the contract source code
Implemented a new model Verifier to manage verifications with etherchain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work @jcarpanelli! There are a few changes needed, but the code makes perfect use of the existing codebase, and seems quite robust. As soon as you implement these changes, and push the integration tests, we're ready to merge this into master.
package-lock.json
Outdated
@@ -9,8 +9,8 @@ | |||
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", | |||
"integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", | |||
"requires": { | |||
"call-me-maybe": "^1.0.1", | |||
"glob-to-regexp": "^0.3.0" | |||
"call-me-maybe": "1.0.1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These diffs are caused by different versions of npm. Please make sure to use the latest one (6.1.0 at the time of this writing), and regen the package-lock using that one.
src/commands/verify.js
Outdated
if (optimizer && !optimizerRuns) { | ||
throw new Error('Cannot verify contract without defining optimizer runs') | ||
} | ||
runWithTruffle(() => verify(contractAlias, options), options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the usage of runWithTruffle has changed recently, since it may alter options
to inject defaults. For instance, in create.js
:
await runWithTruffle(async (opts) => await createProxy({
contractAlias, initMethod, initArgs, force, ... opts
}), options)
src/models/Verifier.js
Outdated
verifyAndPublish(remote, params) { | ||
if (remote === 'etherchain') { | ||
publishToEtherchain(params) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's either hardcode the remote option, or throw an error if we don't match any
const contractName = this.packageFile.contract(contractAlias) | ||
if (contractName) { | ||
const contractDataPath = Contracts.getLocalPath(contractName) | ||
const { compiler, sourcePath } = fs.parseJson(contractDataPath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the resulting sourcePath
does not resolve any import aliases. This means that if the contract is part of a package (such as OpenZeppelin), the source path will be openzeppelin-solidity/contracts/MyContract.sol
, instead of the correct node_modules/openzeppelin-solidity/contracts/MyContract.sol
.
You should be able to distinguish between the two, as local contracts have an absolute path (such as /home/spalladino/Projects/zeppelinos/cli/contracts/mocks/ImplV1.sol
) and the ones in a node module have a relative path.
I'm ok with leaving this as-is now and handling this case in a future PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As truffle-flattener
is using the truffle-resolve
package to resolve dependencies imports, it will automatically prepend the filesystem directory path (i.e., /home/spalladino/Projects/zeppelinos/cli/node_modules/
) to the relative path that is read from the Contract.json
file. This is also the expected behaviour when you flatten contracts that are not inside the project contracts
folder, for example an OpenZeppelin contract.
You can check that implementation here. Please, let me know if I'm misunderstanding you or if I'm wrong.
src/scripts/verify.js
Outdated
@@ -0,0 +1,7 @@ | |||
import ControllerFor from '../models/network/ControllerFor' | |||
|
|||
export default function verify(contractAlias, { network = 'mainnet', txParams = {}, networkFile = undefined, optimizer = false, optimizerRuns = 200, remote = 'etherchain' }) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Down the road, we may want to add a flag to verify all contracts (such as a --all
option, like in the add
command). Let's make sure that we have an issue that capture this, along with any future improvements we may want to work on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! Left a minor comment in the tests, after that, I think we're ready to merge.
test/scripts/verify.test.js
Outdated
networkFile = packageFile.networkFile(network) | ||
await push({ network, networkFile, txParams }) | ||
const contracts = networkFile.contracts | ||
networkFile.contracts = contracts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why these two lines?
test/scripts/verify.test.js
Outdated
let packageFile | ||
let networkFile | ||
let logs | ||
let axiosStub |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use this.VARNAME
in the beforeEach blocks instead of let VARNAME
here, for consistency. This makes sure the tests work if we later abstract them to a behaviour separate from the setup.
Also: could you add an entry to the changelog.md with this new command? |
4f2111c
to
453960d
Compare
- Some function naming enhancement - Removed unused imports in tests
* Start implementing verify command Defined required and non-required command parameters. * Change contract name parameter to contract alias * Implement necessary validations before publication Basically, network ControllerFor function was used to verify if zOS project was initialized, together with NetworkBaseController checkLocalContractDeployed to verify contract definition, deploy status and source code modification status * Tests for verify script validations * Add default remote * Flatten contract sourcecode Implemented a local controller method to retrieve the contract source code path and also tiny function to flatten the contract source code * Retrieve contract sourcecode and compiler version * Request etherchain with axios to verify contract Implemented a new model Verifier to manage verifications with etherchain * Modify optimization parameter handling * Modify variables names * Use more descriptive command options * Fix in contract address parameter * Regenerate package-lock * Fix strings typos * Add integration tests for remote http calls * Inject session options to verify script * Change error message in verify tests * Change some test variables management * Update changelog * Add some final fixes - Some function naming enhancement - Removed unused imports in tests
* Start implementing verify command Defined required and non-required command parameters. * Change contract name parameter to contract alias * Implement necessary validations before publication Basically, network ControllerFor function was used to verify if zOS project was initialized, together with NetworkBaseController checkLocalContractDeployed to verify contract definition, deploy status and source code modification status * Tests for verify script validations * Add default remote * Flatten contract sourcecode Implemented a local controller method to retrieve the contract source code path and also tiny function to flatten the contract source code * Retrieve contract sourcecode and compiler version * Request etherchain with axios to verify contract Implemented a new model Verifier to manage verifications with etherchain * Modify optimization parameter handling * Modify variables names * Use more descriptive command options * Fix in contract address parameter * Regenerate package-lock * Fix strings typos * Add integration tests for remote http calls * Inject session options to verify script * Change error message in verify tests * Change some test variables management * Update changelog * Add some final fixes - Some function naming enhancement - Removed unused imports in tests
Kudos for building such a wonderful feature. When is it planned to be released? |
Or how can I use the dev/nightly version? @jcarpanelli @spalladino |
Hey @xinbenlv! We are planning on a new 1.4.0 RC early next week. If not, you can checkout the CLI and build it on your end, but I wouldn't advise this for production usage, only for testing. |
Thank you, let me check how to build a dev version. Thank you for answering my question. Also, the actual question we have is that:
|
I see, thanks Santiago. Have etherscan told people if they have plan to support command-line verification process in the future, e.g. with a ssh public key or what other ways that both allow the verification to be fully automated and mitigate the risk of abuse and security attacks? |
We have contacted them privately, but got no response back so far |
I see, thank you, I posted in public on https://www.reddit.com/r/etherscan/comments/970voh/verification_through_api_commendline/ |
Fixes #274
This is the first approach to a possible implementation of a contract verification on etherchain. I still have to code some integration tests for the etherchain communication workflow part.
Some validations have been implemented in order to forbid a user to try to verify a contract without first initializing, adding and pushing a contract to a network so we can retrieve the contract address from the zos.network.json file. Consider that etherchain only allows contract verification and publish on the mainnet, so if other network is specified an error (Unable to retrieve the contract creation bytecode) will be thrown.