zkSync-Community-Hub / zksync-developers

Project for Discussions with the ZKsync Community.
369 stars 233 forks source link

Verification only works if unrelated contracts are included #738

Closed vmaark closed 3 weeks ago

vmaark commented 3 weeks ago

image

The verification still works, but unrelated contract source code is published alongside the actual contract and its dependencies.

vasyl-ivanchuk commented 3 weeks ago

thanks for reporting @vmaark ! I was not able to reproduce the problem using @matterlabs/hardhat-zksync version 1.2.0. When I specify the contract address for the verification, the plugin verifies only the specified contract as expected.

Can you please describe the steps to reproduce the problem? Which plugin versions are you using? If you have a repository with an example, that would be great if you could share it.

irzinfante commented 3 weeks ago

Hello @vmaark @vasyl-ivanchuk. I have created a repo where you can reproduce the issue: https://github.com/irzinfante/treasure-zksync-verification. It is a private repo to which I have invited you.

vmaark commented 3 weeks ago

Thanks @irzinfante, I just tried and got the same results. Also tested it with zksolc 1.5.6, same outcome.

vasyl-ivanchuk commented 3 weeks ago

thanks for the example @irzinfante @vmaark ! Here’s what happens:

By default, all contracts in the project are compiled together. When a contract is compiled alongside other contracts, its bytecode may differ from when it is compiled alone (for instance, due to different compiler optimizations based on the overall compilation context). In this case, the contract is deployed with the bytecode generated after the compilation of all contracts in the project.

When the contract is verified after deployment, the verification plugin first tries to verify it using only its related source code. However, if the generated bytecode differs from the deployed version, the plugin attempts to verify it using the full source code from the compilation context, including unrelated files. In this case, the bytecode matches the deployed version, and the verification passes. That's how you ended up having unrelated files verified with your contract.

Try setting contractsToCompile compiler option to the name of the contract you want to deploy and verify, it will then be compiled and verified using only the related source code. For example:

zksolc: {
  version: "1.5.4",
  settings: {
    contractsToCompile: ['MyContractName'] // no path or extension needed
  },
},

For more detailed information, you can refer to the ZKSync documentation on the compiler settings.

vmaark commented 3 weeks ago

thanks for the example @irzinfante @vmaark ! Here’s what happens:

By default, all contracts in the project are compiled together. When a contract is compiled alongside other contracts, its bytecode may differ from when it is compiled alone (for instance, due to different compiler optimizations based on the overall compilation context). In this case, the contract is deployed with the bytecode generated after the compilation of all contracts in the project.

When the contract is verified after deployment, the verification plugin first tries to verify it using only its related source code. However, if the generated bytecode differs from the deployed version, the plugin attempts to verify it using the full source code from the compilation context, including unrelated files. In this case, the bytecode matches the deployed version, and the verification passes. That's how you ended up having unrelated files verified with your contract.

Try setting contractsToCompile compiler option to the name of the contract you want to deploy and verify, it will then be compiled and verified using only the related source code. For example:

zksolc: {
  version: "1.5.4",
  settings: {
    contractsToCompile: ['MyContractName'] // no path or extension needed
  },
},

For more detailed information, you can refer to the ZKSync documentation on the compiler settings.

Interesting. I was trying to deploy many times today, and one time managed to verify without doing that, I was trying out different npm package versions and also changed the zksolc to 1.5.6, but interestingly I wasn't able to reproduce it again. https://explorer.topaz.treasurescan.io/address/0xABfFae2dce3158892d7fB4b3c0b18fFC19Abe467#contract

irzinfante commented 3 weeks ago

thanks for the example @irzinfante @vmaark ! Here’s what happens:

By default, all contracts in the project are compiled together. When a contract is compiled alongside other contracts, its bytecode may differ from when it is compiled alone (for instance, due to different compiler optimizations based on the overall compilation context). In this case, the contract is deployed with the bytecode generated after the compilation of all contracts in the project.

When the contract is verified after deployment, the verification plugin first tries to verify it using only its related source code. However, if the generated bytecode differs from the deployed version, the plugin attempts to verify it using the full source code from the compilation context, including unrelated files. In this case, the bytecode matches the deployed version, and the verification passes. That's how you ended up having unrelated files verified with your contract.

Try setting contractsToCompile compiler option to the name of the contract you want to deploy and verify, it will then be compiled and verified using only the related source code. For example:

zksolc: {
  version: "1.5.4",
  settings: {
    contractsToCompile: ['MyContractName'] // no path or extension needed
  },
},

For more detailed information, you can refer to the ZKSync documentation on the compiler settings.

Hi @vasyl-ivanchuk, I have tryed this, and clearly it works as expected, thank you! But this is far from desirable, as every time I need to compile a new contract I have to mofify the zksolc settings to point to the contract I want to compile.

It would be awesome and really helpful for better development experience if this contractsToCompile option could be provided as an option in the compile command. That way I would be able to automatize this with a simple script every time I need to compile, deploy and verify a new contract.